使用 react-native-camera 在 React Native 中的 iOS 中录制视频时无法播放音频

问题描述

我想使用 react-native-sound 播放通过 url 播放的音频,同时我想录制一个视频,以便我可以捕获通过手机扬声器播放的音频视频。我可以在 android 中实现这一点,但 iOS 给我带来了困难。

我已经在官方 react-native-camera github repo 上问过这个问题,但还没有回复

先做

  • [ 是] 您是否尝试过最新版本?
  • [ YES ] 你试过 master 吗?
  • [ YES ] 您是否查找了现有的匹配问题?

平台

Android 中没有问题

它只发生在 iOS 中。

版本

  • Android:使用不同版本的 android,没有遇到任何问题
  • iOS:
  • 反应原生相机:3.44.3
  • 反应原生:0.64.2
  • 反应:17.0.1

描述/当前行为

这仅在 iOS 上发生,在 Android 上运行良好。我想在录制视频时播放音频,以便可以通过相机正在使用的麦克风捕获手机扬声器上播放的音频。我播放音频,一旦我调用 recordAsync() 函数,音频就会停止并开始录制,起初我认为由于与 Android 相比,iOS 中的权限策略不同,因此在 iOS 中无法执行此操作,但是我执行相同操作的客户端提供了该应用的原生 iOS 版本,因此权限不是问题。

预期行为 希望在我录制视频时允许音频继续播放

重现步骤

尝试使用 react-native-sound 播放文件或 URL 中的任何音频,并从 react-native-camera 调用 recordAsync(),

附加

我使用 react-native-sound 播放音频,因为音频是通过 URL 播放的,这是我的带有道具的 RNCamera 组件:

    <RNCamera
          style={styles.preview}
          type={RNCamera.Constants.Type.back}
          flashMode={RNCamera.Constants.FlashMode.on}
          captureAudio={true}
          androidCameraPermissionoptions={{
            title: 'Permission to use camera',message: 'We need your permission to use your camera',buttonPositive: 'Ok',buttonNegative: 'Cancel',}}
          androidRecordAudioPermissionoptions={{
            title: 'Permission to use audio recording',message: 'We need your permission to use your audio',}}>
          {({camera,status,recordAudioPermissionStatus}) => {
            if (showFilenameModal) {
             // show a modal to save the video file with a user entered name
            }
            if (status !== 'READY')
              return (
                <View
                  style={{
                    flex: 1,width: globalStyles.WIDTH,backgroundColor: 'black',justifyContent: 'center',alignItems: 'center',}}>
                  <Text>Waiting</Text>
                </View>
              );
            return recording || processing ? (
              <IconButton
                title={'Stop'}
                icon={'stop'}
                disabled={processing}
                onPress={() => {
                  console.log('Stop Recording');
                  camera.stopRecording();
                }}
              />
            ) : (
              <View
                style={{
                  display: 'flex',flexDirection: 'row',justifyContent: 'space-around',marginBottom: 10,}}>
                  {/* Button to record video without playing the audio */}
                <IconButton
                  title={'Record'}
                  icon="record"
                  onPress={() => this.startRecording(camera,false)}
                />
                  {/* Button to record video while playing the audio */}
                <IconButton
                  title={'Record with Audio'}
                  icon="record"
                  showSound={true}
                  onPress={() => this.startRecording(camera)}
                /> 
              </View>
            );
          }}
        </RNCamera>

这是我开始录制的方式:

startRecording = async function (camera,withAudio = true) {
    const {audioPlayer,setVideoStatus} = this.props;
    audioPlayer.stopAudio();
    setVideoStatus({
      recording: true,processing: false,uri: null,});

    if (withAudio) audioPlayer.playAudio();

    const video = await camera.recordAsync({
      quality: RNCamera.Constants.VideoQuality['720p'],// I've tried this with different flag combination i.e:
      // captureAudio: true / false,// keepAudioSession: true / false,});

    console.log(video.uri.substr(7,video.uri.length),video.codec);

    audioPlayer.stopAudio();
    setVideoStatus({
      recording: false,processing: true,});

    this.setState({
      showFilenameModal: true,uri: video.uri,});
  };

这是我的 info.plist

  <key>NSCameraUsageDescription</key>
  <string>Allow app to open camera to record video</string>
  <key>NSPhotoLibraryAddUsageDescription</key>
  <string>Allow app to save videos to library</string>
  <key>NSAppleMusicUsageDescription</key>
  <string>Allow app to use media library for audio</string>
  <key>NSLocationAlwaysUsageDescription</key>
  <string>Allow app to use location for getting current state</string>
  <key>NSLocationWhenInUseUsageDescription</key>
  <string>Allow app to use location for getting current state</string>
  <key>NSMicrophoneUsageDescription</key>
  <string>Allow app to use microphone to record video with audio</string>

以防万一这些是我的 AndoroidManifest.xml 中的权限:

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.RECORD_AUdio"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

我正在谈论的另一个应用程序不是基于 react native 的,我认为它是原生的 iOS。

解决方法

感谢 react-native-camera 社区,我解决了这个问题:

https://github.com/react-native-camera/react-native-camera/issues/3276