expo: expo-av Recording Error: This experience is currently in the background, so the audio session could not be activated.

Summary

I am using expo-av to record audios in my app. This is my code:

const AUDIO_RECORDER_MODE = {
  allowsRecordingIOS: true,
  interruptionModeAndroid: InterruptionModeAndroid.DuckOthers,
  interruptionModeIOS: InterruptionModeIOS.MixWithOthers,
  playsInSilentModeIOS: true,
  playThroughEarpieceAndroid: false,
  shouldDuckAndroid: true,
  staysActiveInBackground: false,
};

async startRecording(
  audioMode = AUDIO_RECORDER_MODE,
  recordingOptions = MULTIPLATFORM_RECORDING_OPTIONS
) {
  const { granted } = await Audio.requestPermissionsAsync();

  if (!granted) {
    throw AudioErrors.permissionsRequired();
  }

  try {
    // Change the audio mode
    await Audio.setAudioModeAsync(audioMode);

    // Start a recording in HQ
    this.recording = new Audio.Recording();

    await this.recording.prepareToRecordAsync(recordingOptions);

    const status = await this.recording.startAsync();

    return status;
  } catch (err) {
    throw AudioErrors.cannotStartRecording();
  }
}

For some reason, the first time the user starts a recording and the permissions are being requested, they get the error (after granting):

Prepare encountered an error: Error Domain=EXModulesErrorDomain Code=0 "This experience is currently in the background, so the audio session could not be activated." UserInfo={NSLocalizedDescription=This experience is currently in the background, so the audio session could not be activated.}

This is my Info.plst:

  "infoPlist": {
    "LSApplicationQueriesSchemes": [
      "geo",
      "http",
      "https",
      "instagram",
      "mailto",
      "maps",
      "sms",
      "spotify",
      "tel"
    ],
    "NSAppTransportSecurity": {
      "NSAllowsArbitraryLoads": true
    },
    "NSCameraUsageDescription": "Allow $(PRODUCT_NAME) to access your camera so you can upload posts and send images to your friends.",
    "NSLocationAlwaysAndWhenInUseUsageDescription": "Allow $(PRODUCT_NAME) to access your location so you can use the map feature.",
    "NSLocationAlwaysUsageDescription": "Allow $(PRODUCT_NAME) to access your location so you can use the map feature.",
    "NSLocationWhenInUseUsageDescription": "Allow $(PRODUCT_NAME) to access your location so you can use the map feature.",
    "NSMicrophoneUsageDescription": "Allow $(PRODUCT_NAME) to access your microphone so you can send audios to your friends.",
    "NSPhotoLibraryAddUsageDescription": "Allow $(PRODUCT_NAME) to access your camera and save the photos you take to your gallery.",
    "NSPhotoLibraryUsageDescription": "Allow $(PRODUCT_NAME) to access your photos so you can select images from your gallery to upload posts or send via chat.",
    "SKAdNetworkItems": [
      { "SKAdNetworkIdentifier": "cstr6suwn9.skadnetwork" },
      ...
    ]
  }
},

What platform(s) does this occur on?

iOS

SDK Version

47.0.0

Environment

expo-env-info 1.0.5 environment info: System: OS: macOS 10.15.7 Shell: 5.7.1 - /bin/zsh Binaries: Node: 16.18.1 - /usr/local/bin/node Yarn: 1.22.19 - ~/.yarn/bin/yarn npm: 8.19.2 - /usr/local/bin/npm Watchman: 2022.10.17.00 - /usr/local/bin/watchman Managers: CocoaPods: 1.11.3 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: iOS 14.4, DriverKit 20.2, macOS 11.1, tvOS 14.3, watchOS 7.2 IDEs: Android Studio: 2021.3 AI-213.7172.25.2113.9123335 Xcode: 12.4/12D4e - /usr/bin/xcodebuild npmPackages: react: 18.1.0 => 18.1.0 react-dom: 18.1.0 => 18.1.0 react-native: 0.70.5 => 0.70.5 react-native-web: ~0.18.7 => 0.18.12 Expo Workflow: managed

Minimal reproducible example

const AUDIO_RECORDER_MODE = {
  allowsRecordingIOS: true,
  interruptionModeAndroid: InterruptionModeAndroid.DuckOthers,
  interruptionModeIOS: InterruptionModeIOS.MixWithOthers,
  playsInSilentModeIOS: true,
  playThroughEarpieceAndroid: false,
  shouldDuckAndroid: true,
  staysActiveInBackground: false,
};

async startRecording(
  audioMode = AUDIO_RECORDER_MODE,
  recordingOptions = MULTIPLATFORM_RECORDING_OPTIONS
) {
  const { granted } = await Audio.requestPermissionsAsync();

  if (!granted) {
    throw AudioErrors.permissionsRequired();
  }

  try {
    // Change the audio mode
    await Audio.setAudioModeAsync(audioMode);

    // Start a recording in HQ
    this.recording = new Audio.Recording();

    await this.recording.prepareToRecordAsync(recordingOptions);

    const status = await this.recording.startAsync();

    return status;
  } catch (err) {
    throw AudioErrors.cannotStartRecording();
  }
}

About this issue

  • Original URL
  • State: open
  • Created a year ago
  • Reactions: 10
  • Comments: 22 (2 by maintainers)

Most upvoted comments

In my solution, works with timeout 500 milliseconds.

image image

I went to Expo office hours to ask the team and they said they are working on a major overhaul of expo-av for beta in SDK 51 and do I doubt much effort will be spent on fixing this type of thing.

Same problem. To reliably get this error try this:

  • Force restart the app with airplane mode on on a real device
  • Turn off the airplane mode and get internet connection
  • Turn on airplane mode again
  • Start the recording

This always produces a “Prepare encountered an error: recorder not prepared.” error for us