react-native-vision-camera icon indicating copy to clipboard operation
react-native-vision-camera copied to clipboard

๐Ÿ› Audio is not getting recoded while video recording in IOS

Open Zshubham opened this issue 5 months ago โ€ข 24 comments

What's happening?

This code is working fine with Android, but I am getting issues in IOS that after recording the Video, the audio goes missing in the video.

Reproduceable Code

import React, {useState, useRef, useCallback, useEffect} from 'react';
import {View, Text, StyleSheet, Platform, Alert} from 'react-native';
import {
  Camera,
  useCameraDevices,
  CameraDevice,
} from 'react-native-vision-camera';
import {useNavigation, useIsFocused} from '@react-navigation/native';
import {HP} from '../../shared/themes/responsive';
import Header from '../../shared/components/header';
import {useAuth} from '../../../authenticationFlow/AuthContext';
import Loader from '../../shared/components/Loader';
import {UploadShortsNavigationProp} from './types';
import PreviewScreen from './PreviewScreen';
import {useToast} from '../../shared/contexts/useToast';
import {useAlert} from '../../shared/contexts/useAlert';
import CameraControls from './components/CameraControls';

// Import utilities
// import {
//   VideoUtils,
//   getVideoRecordingOptions,
//   getVideoPlaybackOptions,
// } from './utils/videoUtils';
// import {
//   getAudioRecordingOptions,
//   initializeAudioSession,
// } from './utils/audioUtils';

const UploadShorts: React.FC = () => {
  const navigation = useNavigation<UploadShortsNavigationProp>();
  const cameraRef = useRef<Camera>(null);
  const devices = useCameraDevices();
  const [cameraPosition, setCameraPosition] = useState<'front' | 'back'>(
    'back',
  );
  const device = devices?.find(device => device.position === cameraPosition);
  const {userToken, userId} = useAuth();
  const isFocused = useIsFocused();
  const toast = useToast();
  const alert = useAlert();

  const [isRecording, setIsRecording] = useState(false);
  const [recordedVideo, setRecordedVideo] = useState<string | null>(null);
  const [isCompressing, setIsCompressing] = useState(false);
  const [errorMessage, setErrorMessage] = useState<string | null>(null);
  const [recordingTime, setRecordingTime] = useState(0);
  const [showPreview, setShowPreview] = useState(false);
  const [flashEnabled, setFlashEnabled] = useState(false);

  // Check permissions on mount
  useEffect(() => {
    const checkPermissions = async () => {
      try {
        const cameraPermission = await Camera.getCameraPermissionStatus();
        const microphonePermission =
          await Camera.getMicrophonePermissionStatus();

        console.log('Camera permission:', cameraPermission);
        console.log('Microphone permission:', microphonePermission);

        if (
          cameraPermission === 'denied' ||
          microphonePermission === 'denied'
        ) {
          const newCameraPermission = await Camera.requestCameraPermission();
          const newMicrophonePermission =
            await Camera.requestMicrophonePermission();

          console.log('New camera permission:', newCameraPermission);
          console.log('New microphone permission:', newMicrophonePermission);

          if (
            newCameraPermission === 'denied' ||
            newMicrophonePermission === 'denied'
          ) {
            setErrorMessage('Camera and microphone permissions are required');
          }
        }

        // Initialize audio session for proper recording and playback
        // await initializeAudioSession();
      } catch (error) {
        console.error('Permission check error:', error);
        setErrorMessage('Failed to check permissions');
      }
    };

    checkPermissions();
  }, []);

  const startRecording = useCallback(async () => {
    if (!cameraRef.current) {
      setErrorMessage('Camera not initialized');
      return;
    }

    try {
      setIsRecording(true);
      setRecordingTime(0);
      setErrorMessage(null);

      console.log('Starting video recording with audio enabled...');

      const recordingOptions = {
        onRecordingFinished: async (video: any) => {
          if (!video?.path) {
            setErrorMessage('Failed to save video');
            setIsRecording(false);
            return;
          }
          console.log('Video recording finished:', video);
          console.log('Video path:', video.path);
          console.log('Video size:', video.size);
          console.log('Video duration:', video.duration);
          setRecordedVideo(video.path);
          setIsRecording(false);
          setShowPreview(true);
        },
        onRecordingError: (error: any) => {
          console.error('Recording error:', error);
          setIsRecording(false);
          setErrorMessage(
            `Failed to record video: ${error?.message || 'Unknown error'}`,
          );
        },
      };

      await cameraRef.current.startRecording(recordingOptions);
      console.log('Recording started successfully');
    } catch (e) {
      console.error('Recording start error:', e);
      setIsRecording(false);
      setErrorMessage('Failed to start recording. Please check permissions.');
    }
  }, [cameraRef]);

  const pickVideo = async () => {
    try {
      const videoPath = await VideoUtils.pickVideoFromGallery();
      if (videoPath) {
        setRecordedVideo(videoPath);
        setShowPreview(true);
        setErrorMessage(null);
      }
    } catch (error) {
      console.error('Video picking error:', error);
      setErrorMessage('Failed to pick the video');
    }
  };

  const stopRecording = useCallback(async () => {
    try {
      if (cameraRef.current && isRecording) {
        setIsRecording(false);
        await cameraRef.current.stopRecording();
      }
    } catch (error) {
      console.error('Stop recording error:', error);
      setErrorMessage('Failed to stop recording');
      setIsRecording(false);
    }
  }, [cameraRef, isRecording]);

  // Enforce maximum recording duration
  useEffect(() => {
    let intervalId: NodeJS.Timeout | null = null;

    if (isRecording) {
      intervalId = setInterval(() => {
        setRecordingTime(prev => {
          if (prev + 1 >= VideoUtils.MAX_DURATION) {
            setTimeout(() => {
              if (isRecording) {
                stopRecording();
              }
            }, 0);
            return VideoUtils.MAX_DURATION;
          }
          return prev + 1;
        });
      }, 1000);
    }

    return () => {
      if (intervalId) {
        clearInterval(intervalId);
      }
    };
  }, [isRecording, stopRecording]);

  const handlePreviewContinue = useCallback(() => {
    if (!recordedVideo) {
      setErrorMessage('No video selected');
      return;
    }
    navigation.navigate('CaptionScreen', {
      videoUri: recordedVideo,
    });
  }, [navigation, recordedVideo]);

  const toggleCamera = useCallback(() => {
    setCameraPosition(current => (current === 'back' ? 'front' : 'back'));
  }, []);

  const toggleFlash = useCallback(() => {
    setFlashEnabled(current => !current);
  }, []);

  const handleBackPress = useCallback(() => {
    navigation.goBack();
  }, [navigation]);

  if (showPreview && recordedVideo) {
    return (
      <PreviewScreen
        videoUri={recordedVideo}
        onContinue={handlePreviewContinue}
        onDiscard={() => {
          setShowPreview(false);
          setRecordedVideo(null);
        }}
      />
    );
  }

  if (!device) {
    return (
      <View style={styles.loadingContainer}>
        <Text style={styles.loadingText}>Loading camera...</Text>
      </View>
    );
  }

  return (
    <View style={styles.container}>
      <Loader visible={isCompressing} text="Compressing video..." />

      <View style={styles.cameraContainer}>
        <Camera
          ref={cameraRef}
          style={StyleSheet.absoluteFill}
          device={device}
          isActive={isFocused}
          video={true}
          audio={true}
          torch={flashEnabled ? 'on' : 'off'}
        />
      </View>

      <CameraControls
        isRecording={isRecording}
        recordingTime={recordingTime}
        flashEnabled={flashEnabled}
        onBackPress={handleBackPress}
        onGalleryPress={pickVideo}
        onRecordPress={isRecording ? stopRecording : startRecording}
        onFlipPress={toggleCamera}
        onFlashPress={toggleFlash}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#000',
  },
  loadingContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#000',
  },
  loadingText: {
    color: '#fff',
    fontSize: 16,
  },
  cameraContainer: {
    flex: 1,
    marginTop: HP(0),
    borderRadius: 20,
    overflow: 'hidden',
  },
});

export default UploadShorts;

Relevant log output

17:31:41.121: [info] ๐Ÿ“ธ VisionCamera.startRecording(options:onVideoRecorded:onError:): Starting Video recording...
17:31:41.122: [info] ๐Ÿ“ธ VisionCamera.startRecording(options:onVideoRecorded:onError:): Starting recording into file: file:///private/var/mobile/Containers/Data/Application/355B6033-E014-4C5B-A7E8-501A93435DDA/tmp/32098127-6B0E-4226-9361-B5A9BBC56BA3.mov
17:31:41.122: [info] ๐Ÿ“ธ VisionCamera.init(url:fileType:metadataProvider:clock:orientation:completion:): Creating RecordingSession... (orientation: landscapeLeft)
17:31:41.122: [info] ๐Ÿ“ธ VisionCamera.startRecording(options:onVideoRecorded:onError:): Enabling Audio for Recording...
17:31:41.122: [info] ๐Ÿ“ธ VisionCamera.activateAudioSession(): Activating Audio Session...
17:31:41.123: [info] ๐Ÿ“ธ VisionCamera.initializeAudioTrack(withSettings:format:): Initializing Audio AssetWriter with settings: ["AVEncoderBitRatePerChannelKey": 96000, "AVSampleRateKey": 44100, "AVNumberOfChannelsKey": 1, "AVFormatIDKey": 1633772320, "AVEncoderQualityForVBRKey": 91, "AVEncoderBitRateStrategyKey": AVAudioBitRateStrategy_Variable]
17:31:41.123: [info] ๐Ÿ“ธ VisionCamera.updateCategory(_:mode:options:): Changing AVAudioSession category from AVAudioSessionCategoryPlayback -> AVAudioSessionCategoryPlayAndRecord
17:31:41.124: [info] ๐Ÿ“ธ VisionCamera.initializeAudioTrack(withSettings:format:): Initialized Audio AssetWriter.
17:31:41.124: [info] ๐Ÿ“ธ VisionCamera.recommendedVideoSettings(forOptions:): Getting recommended video settings for AVFileType(_rawValue: com.apple.quicktime-movie) file...
17:31:41.130: [info] ๐Ÿ“ธ VisionCamera.initializeVideoTrack(withSettings:): Initializing Video AssetWriter with settings: ["AVVideoCodecKey": hvc1, "AVVideoCompressionPropertiesKey": {
    AllowFrameReordering = 1;
    AllowOpenGOP = 1;
    AverageBitRate = 7651584;
    ExpectedFrameRate = 30;
    MaxAllowedFrameQP = 41;
    MaxKeyFrameIntervalDuration = 1;
    MaximumRealTimeFrameRate = 30;
    MinAllowedFrameQP = 15;
    MinimizeMemoryUsage = 1;
    Priority = 80;
    ProfileLevel = "HEVC_Main_AutoLevel";
    RealTime = 1;
    RelaxAverageBitRateTarget = 1;
}, "AVVideoWidthKey": 1920, "AVVideoHeightKey": 1080]
17:31:41.135: [info] ๐Ÿ“ธ VisionCamera.initializeVideoTrack(withSettings:): Initialized Video AssetWriter.
17:31:41.135: [info] ๐Ÿ“ธ VisionCamera.start(): Starting Asset Writer...
17:31:41.228: [info] ๐Ÿ“ธ VisionCamera.start(): Asset Writer started!
17:31:41.229: [info] ๐Ÿ“ธ VisionCamera.start(): Asset Writer session started at 685128.479016166.
17:31:41.229: [info] ๐Ÿ“ธ VisionCamera.start(): Requesting video timeline start at 685128.479837916...
17:31:41.229: [info] ๐Ÿ“ธ VisionCamera.start(): Requesting audio timeline start at 685128.479880333...
17:31:41.229: [info] ๐Ÿ“ธ VisionCamera.startRecording(options:onVideoRecorded:onError:): RecordingSesssion started in 107.444958ms!
17:31:41.242: [info] ๐Ÿ“ธ VisionCamera.isTimestampWithinTimeline(timestamp:): video Timeline: First timestamp: 685128.4679725
17:31:41.263: [info] ๐Ÿ“ธ VisionCamera.updateCategory(_:mode:options:): AVAudioSession category changed!
17:31:41.294: [info] ๐Ÿ“ธ VisionCamera.activateAudioSession(): Audio Session activated!
17:31:41.296: [error] ๐Ÿ“ธ VisionCamera.sessionRuntimeError(notification:): Unexpected Camera Runtime Error occured!
17:31:41.296: [error] ๐Ÿ“ธ VisionCamera.onError(_:): Invoking onError(): Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSLocalizedFailureReason=An unknown error occurred (-10868), NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x135eaa640 {Error Domain=NSOSStatusErrorDomain Code=-10868 "(null)"}}
{ [unknown/unknown: Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSLocalizedFailureReason=An unknown error occurred (-10868), NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x135eaa640 {Error Domain=NSOSStatusErrorDomain Code=-10868 "(null)"}}]
  name: 'unknown/unknown',
  _code: 'unknown/unknown',
  _message: 'Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSLocalizedFailureReason=An unknown error occurred (-10868), NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x135eaa640 {Error Domain=NSOSStatusErrorDomain Code=-10868 "(null)"}}',
  _cause: 
   { code: -11800,
     details: 
      { NSLocalizedFailureReason: 'An unknown error occurred (-10868)',
        NSUnderlyingError: null,
        NSLocalizedDescription: 'The operation could not be completed' },
     domain: 'AVFoundationErrorDomain',
     message: 'Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSLocalizedFailureReason=An unknown error occurred (-10868), NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x135eaa640 {Error Domain=NSOSStatusErrorDomain Code=-10868 "(null)"}}' } }
17:31:48.867: [info] ๐Ÿ“ธ VisionCamera.stop(): Stopping Asset Writer with status "writing"...
17:31:48.867: [info] ๐Ÿ“ธ VisionCamera.stop(): Requesting video timeline stop at 685136.118041958...
17:31:48.867: [info] ๐Ÿ“ธ VisionCamera.stop(): Requesting audio timeline stop at 685136.118085125...
17:31:48.940: [info] ๐Ÿ“ธ VisionCamera.markAsFinished(lastTimestamp:stopTimestamp:): Last timestamp arrived at 685136.1405085 (0.022466542 seconds after stop()) - video Timeline is now finished!
17:31:48.941: [debug] ๐Ÿ“ธ VisionCamera.markAsFinished(lastTimestamp:stopTimestamp:): 685128.479837916: โบ๏ธ Started
685136.118041958: โน๏ธ Stopped
17:31:48.941: [info] ๐Ÿ“ธ VisionCamera.append(buffer:): Marking video track as finished - target duration: CMTime(value: 7638204042, timescale: 1000000000, flags: __C.CMTimeFlags(rawValue: 1), epoch: 0), actual duration: CMTime(value: 7639174333, timescale: 1000000000, flags: __C.CMTimeFlags(rawValue: 1), epoch: 0) (0.000970291 seconds longer than expected)
17:31:48.972: [error] ๐Ÿ“ธ VisionCamera.stop(): Waited 0.1 seconds but session is still not finished - force-stopping session...
17:31:48.972: [info] ๐Ÿ“ธ VisionCamera.finish(): Stopping AssetWriter with status "writing"...
17:31:48.989: [info] ๐Ÿ“ธ VisionCamera.finish(): Asset Writer session stopped at 685136.107146833.
17:31:49.019: [info] ๐Ÿ“ธ VisionCamera.finish(): Asset Writer finished writing!
17:31:49.019: [info] ๐Ÿ“ธ VisionCamera.startRecording(options:onVideoRecorded:onError:): RecordingSession finished with status completed.
17:31:49.019: [info] ๐Ÿ“ธ VisionCamera.deactivateAudioSession(): Deactivating Audio Session...
17:31:49.020: [info] ๐Ÿ“ธ VisionCamera.deactivateAudioSession(): Audio Session deactivated!
Audio session category set to: Playback
App is being debugged, do not track this hang
Hang detected: 0.85s (debugger attached, not reporting)
'Video loaded successfully:', { canStepForward: true,
  canPlayFastForward: true,
  naturalSize: { height: 1920, width: 1080, orientation: 'portrait' },
  canPlaySlowReverse: true,
  textTracks: [],
  audioTracks: [],
  currentTime: 0,
  target: 1845,
  canPlaySlowForward: true,
  duration: 7.628333568572998,
  canPlayReverse: true,
  canStepBackward: true }
'Video duration:', 7.628333568572998
'Video natural size:', { height: 1920, width: 1080, orientation: 'portrait' }

Camera Device

{
  "hardwareLevel": "full",
  "formats": [],
  "id": "com.apple.avfoundation.avcapturedevice.built-in_video:3",
  "hasTorch": true,
  "hasFlash": true,
  "name": "Back Dual Camera",
  "minExposure": -8,
  "sensorOrientation": "portrait",
  "supportsFocus": true,
  "physicalDevices": [
    "wide-angle-camera",
    "telephoto-camera"
  ],
  "neutralZoom": 1,
  "supportsRawCapture": false,
  "minFocusDistance": 12,
  "maxZoom": 16,
  "minZoom": 1,
  "supportsLowLightBoost": false,
  "maxExposure": 8,
  "position": "back",
  "isMultiCam": true
}

Device

iphone 11 pro max 18.5

VisionCamera Version

4.7.0

Can you reproduce this issue in the VisionCamera Example app?

I didn't try (โš ๏ธ your issue might get ignored & closed if you don't try this)

Additional information

Zshubham avatar Jun 30 '25 12:06 Zshubham

Guten Tag, Hans here! ๐Ÿป

I see that you are facing an issue with audio not being recorded while capturing video on iOS. However, it looks like you did not try reproducing the issue in the VisionCamera Example app. Testing there can help us narrow down if it is a problem with your implementation or something in the library itself.

Also, if you could provide more logs, especially from Xcode while reproducing this issue, it would be very helpful for mrousavy to diagnose it better.

Please give that a try, and let us know what you find!

Note: If you think I made a mistake, please ping @mrousavy to take a look.

maintenance-hans[bot] avatar Jun 30 '25 12:06 maintenance-hans[bot]

The same for me, I have granted all permissions but it is not recording the audio. If the audio tiggers by another program then the Audio will be recorded by [react-native-vision-camera as well. any updates on this issue?

saeidtkh avatar Jun 30 '25 12:06 saeidtkh

@mrousavy it's working for the first time, but on the second time, the audio is missing from the video.

Zshubham avatar Jun 30 '25 12:06 Zshubham

@Zshubham For me there was a conflict with react-native-video. if you have react-native-video somewhere in your project, try to use this version of it: "react-native-video": "^6.8.2", and also add this props:

<Video disableAudioSessionManagement={true}

This worked for me and now I have the audio as well. :)

saeidtkh avatar Jun 30 '25 13:06 saeidtkh

my case when I started record and have following error and only audio is not recordable on iOS 18.5 iPhone 16. 12 mini it's killing me.. permission are granted works fine on android

Camera error: unknown/unknown: Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSLocalizedFailureReason=An unknown error occurred (-10851), NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x14072e6a0 {Error Domain=NSOSStatusErrorDomain Code=-10851 "(null)"}}

LOGANLEEE avatar Jun 30 '25 18:06 LOGANLEEE

I downgrade "react-native-video": "6.10.0" it works fine

nhutlyhcmus avatar Jul 01 '25 07:07 nhutlyhcmus

I downgrade "react-native-video": "6.10.0" it works fine

what is your version of react-native-vision-camera? and react-native also are you using new arch??

LOGANLEEE avatar Jul 01 '25 10:07 LOGANLEEE

okay i tried this method and it works ios 18.5 iphone 16.

once component render initializing camera 3times then that error goes away but still why..?

anyway hope this appoarch can help others as i invested 2days only for this.


useEffect(() => {
    const max = 3; // Number of times to initialize
    if (cameraKey < max) {
      reInitializing(); // Already mounted once, so do 2 more
    }
    // No cleanup needed since this is only on mount
  }, [cameraKey]);


<Camera
        key={cameraKey}
        ref={camera}
        style={StyleSheet.absoluteFill}
        device={device}
        isActive={isActive}
        audio={true}
        video={true}
        onInitialized={() => {
          const timeout = setTimeout(() => {
            setIsCameraInitialized(true);
          }, 1000);

          return () => {
            clearTimeout(timeout);
          };
        }}
        onError={handleCameraError}
      />

LOGANLEEE avatar Jul 02 '25 19:07 LOGANLEEE

what is your version of react-native-vision-camera? and react-native also are you using

"react-native-vision-camera": "^4.7.0", "react-native-video": "6.10.0",

nhutlyhcmus avatar Jul 07 '25 10:07 nhutlyhcmus

@mrousavy it's working for the first time, but on the second time, the audio is missing from the video.

Abdullo-0901 avatar Jul 10 '25 10:07 Abdullo-0901

@Zshubham For me there was a conflict with react-native-video. if you have react-native-video somewhere in your project, try to use this version of it: "react-native-video": "^6.8.2", and also add this props:

<Video disableAudioSessionManagement={true}

This worked for me and now I have the audio as well. :)

This worked for me as well. Thanks.

longnguyenegs avatar Jul 16 '25 11:07 longnguyenegs

my case when I started record and have following error and only audio is not recordable on iOS 18.5 iPhone 16. 12 mini it's killing me.. permission are granted works fine on android

Camera error: unknown/unknown: Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSLocalizedFailureReason=An unknown error occurred (-10851), NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x14072e6a0 {Error Domain=NSOSStatusErrorDomain Code=-10851 "(null)"}}

I have this issue on iPhone 14 Pro too.

longnguyenegs avatar Jul 16 '25 11:07 longnguyenegs

@Zshubham For me there was a conflict with react-native-video. if you have react-native-video somewhere in your project, try to use this version of it: "react-native-video": "^6.8.2", and also add this props:

<Video disableAudioSessionManagement={true}

This worked for me and now I have the audio as well. :)

Which version of react-native-vision-camera are you using ?

cloud-github avatar Jul 25 '25 08:07 cloud-github

i'm facing this error first time when recording the video through vision camera on ios:

[unknown/unknown: Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSLocalizedFailureReason=An unknown error occurred (-10868), NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x13a486250 {Error Domain=NSOSStatusErrorDomain Code=-10868 "(null)"}}]

video is recorded but audio is missing. when i restart the app than every thing is working fine.

i also see some people are saying about the react-native-video package downgrading the version but why we need to downgrade the version of react-native-video its different package form the vision camera.

is there any permanent solution available to fix this error?

chqamarali avatar Jul 25 '25 14:07 chqamarali

Hey guys, I ran through this problem a ton in my app and I had to put a ton of work and research in to fix it reliably. You are dealing with an AVAudioSession collision between RNVC & react-native-video and/or expo-video. Each package tries to start the audio session individually, and sometimes RNVC loses and throws that unknown/unknown error with no audio.

I worked with the creators of react-native-video to add the disableAudioSessionManagement prop to help stop this, but expo-video currently doesn't support it. In my production app, I disabled expo-videos audio session management with the following patch:

diff --git a/node_modules/expo-video/ios/VideoManager.swift b/node_modules/expo-video/ios/VideoManager.swift
index cb07f86..f3cc65b 100644
--- a/node_modules/expo-video/ios/VideoManager.swift
+++ b/node_modules/expo-video/ios/VideoManager.swift
@@ -68,9 +68,9 @@ class VideoManager {
   // This function usually takes less than 5ms to execute, but in some cases (initial setup) it takes up to 70ms
   // Because of this we dispatch it on another queue to minimize the load on main queue.
   internal func setAppropriateAudioSessionOrWarn() {
-    Self.managerQueue.async { [weak self] in
-      self?.setAudioSession()
-    }
+    // Self.managerQueue.async { [weak self] in
+    //   self?.setAudioSession()
+    // }
   }
 
   private func setAudioSession() {

And I disable react-native-vision-camera's audio session management with this diff (which is probably overkill, but whatever):

diff --git a/node_modules/react-native-vision-camera/ios/Core/CameraSession+Audio.swift b/node_modules/react-native-vision-camera/ios/Core/CameraSession+Audio.swift
index 3d67c8c..1efe1cf 100644
--- a/node_modules/react-native-vision-camera/ios/Core/CameraSession+Audio.swift
+++ b/node_modules/react-native-vision-camera/ios/Core/CameraSession+Audio.swift
@@ -17,81 +17,81 @@ extension CameraSession {
    Background audio is allowed to play on speakers or bluetooth speakers.
    */
   final func activateAudioSession() throws {
-    VisionLogger.log(level: .info, message: "Activating Audio Session...")
+    // VisionLogger.log(level: .info, message: "Activating Audio Session...")
 
     do {
-      let audioSession = AVAudioSession.sharedInstance()
+    //   let audioSession = AVAudioSession.sharedInstance()
 
-      try audioSession.updateCategory(AVAudioSession.Category.playAndRecord,
-                                      mode: .videoRecording,
-                                      options: [.mixWithOthers,
-                                                .allowBluetoothA2DP,
-                                                .defaultToSpeaker,
-                                                .allowAirPlay])
+    //   try audioSession.updateCategory(AVAudioSession.Category.playAndRecord,
+    //                                   mode: .videoRecording,
+    //                                   options: [.mixWithOthers,
+    //                                             .allowBluetoothA2DP,
+    //                                             .defaultToSpeaker,
+    //                                             .allowAirPlay])
 
-      if #available(iOS 14.5, *) {
-        // prevents the audio session from being interrupted by a phone call
-        try audioSession.setPrefersNoInterruptionsFromSystemAlerts(true)
-      }
+    //   if #available(iOS 14.5, *) {
+    //     // prevents the audio session from being interrupted by a phone call
+    //     try audioSession.setPrefersNoInterruptionsFromSystemAlerts(true)
+    //   }
 
-      if #available(iOS 13.0, *) {
-        // allow system sounds (notifications, calls, music) to play while recording
-        try audioSession.setAllowHapticsAndSystemSoundsDuringRecording(true)
-      }
+    //   if #available(iOS 13.0, *) {
+    //     // allow system sounds (notifications, calls, music) to play while recording
+    //     try audioSession.setAllowHapticsAndSystemSoundsDuringRecording(true)
+    //   }
 
       audioCaptureSession.startRunning()
-      VisionLogger.log(level: .info, message: "Audio Session activated!")
+    //   VisionLogger.log(level: .info, message: "Audio Session activated!")
     } catch let error as NSError {
-      VisionLogger.log(level: .error, message: "Failed to activate audio session! Error \(error.code): \(error.description)")
-      switch error.code {
-      case 561_017_449:
-        throw CameraError.session(.audioInUseByOtherApp)
-      default:
-        throw CameraError.session(.audioSessionFailedToActivate)
-      }
+    //   VisionLogger.log(level: .error, message: "Failed to activate audio session! Error \(error.code): \(error.description)")
+    //   switch error.code {
+    //   case 561_017_449:
+    //     throw CameraError.session(.audioInUseByOtherApp)
+    //   default:
+    //     throw CameraError.session(.audioSessionFailedToActivate)
+    //   }
     }
   }
 
   final func deactivateAudioSession() {
-    VisionLogger.log(level: .info, message: "Deactivating Audio Session...")
+    // VisionLogger.log(level: .info, message: "Deactivating Audio Session...")
 
-    audioCaptureSession.stopRunning()
-    VisionLogger.log(level: .info, message: "Audio Session deactivated!")
+    // audioCaptureSession.stopRunning()
+    // VisionLogger.log(level: .info, message: "Audio Session deactivated!")
   }
 
   @objc
   func audioSessionInterrupted(notification: Notification) {
-    VisionLogger.log(level: .error, message: "Audio Session Interruption Notification!")
-    guard let userInfo = notification.userInfo,
-          let typeValue = userInfo[AVAudioSessionInterruptionTypeKey] as? UInt,
-          let type = AVAudioSession.InterruptionType(rawValue: typeValue) else {
-      return
-    }
+    // VisionLogger.log(level: .error, message: "Audio Session Interruption Notification!")
+    // guard let userInfo = notification.userInfo,
+    //       let typeValue = userInfo[AVAudioSessionInterruptionTypeKey] as? UInt,
+    //       let type = AVAudioSession.InterruptionType(rawValue: typeValue) else {
+    //   return
+    // }
 
-    // TODO: Add JS-Event for Audio Session interruptions?
-    switch type {
-    case .began:
-      // Something interrupted our Audio Session, stop recording audio.
-      VisionLogger.log(level: .error, message: "The Audio Session was interrupted!")
-    case .ended:
-      VisionLogger.log(level: .info, message: "The Audio Session interruption has ended.")
-      guard let optionsValue = userInfo[AVAudioSessionInterruptionOptionKey] as? UInt else { return }
-      let options = AVAudioSession.InterruptionOptions(rawValue: optionsValue)
-      if options.contains(.shouldResume) {
-        // Try resuming if possible
-        let isRecording = recordingSession != nil
-        if isRecording {
-          CameraQueues.audioQueue.async {
-            VisionLogger.log(level: .info, message: "Resuming interrupted Audio Session...")
-            // restart audio session because interruption is over
-            try? self.activateAudioSession()
-          }
-        }
-      } else {
-        VisionLogger.log(level: .error, message: "Cannot resume interrupted Audio Session!")
-      }
-    @unknown default:
-      ()
-    }
+    // // TODO: Add JS-Event for Audio Session interruptions?
+    // switch type {
+    // case .began:
+    //   // Something interrupted our Audio Session, stop recording audio.
+    //   VisionLogger.log(level: .error, message: "The Audio Session was interrupted!")
+    // case .ended:
+    //   VisionLogger.log(level: .info, message: "The Audio Session interruption has ended.")
+    //   guard let optionsValue = userInfo[AVAudioSessionInterruptionOptionKey] as? UInt else { return }
+    //   let options = AVAudioSession.InterruptionOptions(rawValue: optionsValue)
+    //   if options.contains(.shouldResume) {
+    //     // Try resuming if possible
+    //     let isRecording = recordingSession != nil
+    //     if isRecording {
+    //       CameraQueues.audioQueue.async {
+    //         VisionLogger.log(level: .info, message: "Resuming interrupted Audio Session...")
+    //         // restart audio session because interruption is over
+    //         try? self.activateAudioSession()
+    //       }
+    //     }
+    //   } else {
+    //     VisionLogger.log(level: .error, message: "Cannot resume interrupted Audio Session!")
+    //   }
+    // @unknown default:
+    //   ()
+    // }
   }
 }

And I built a whole package around managing your own audio session that allows you to setup and start your own audio sessions and control the Category and Mode, etc.:

https://github.com/ChristopherGabba/react-native-nitro-audio-manager

Works perfectly in my app now. The alternative is you just disable one package or another's audio session management and choose one to take the lead.

I hope this helps.

I have talked with Marc in the past about opening up the audio session flexibility, but he is clearly bowed up with 19 other open source projects and running a business. I think he is planning on rewriting vision camera completely with Nitro in V5 and so I expect that would be an opportunity to try and rope this in somehow.

ChristopherGabba avatar Aug 11 '25 15:08 ChristopherGabba

Same goes for me too

The video recording works as expected on the first attempt, capturing both audio and video. However, after navigating away from the recording screen and returning, subsequent recordings only capture video while the audio track is missing. Interestingly, restarting the app restores the functionality for the first recording, but the same issue reoccurs on the second attempt.

I have both audio and camera permissions are granted.

it is only happening in IOS ,in android it is working fine.

<Camera key={this.state.cameraInstanceKey} ref={ref => {this.camera = ref}} style={styles.preview} device={cameraType ? backdevice : frontdevice} isActive={isCameraActive} video={true} audio={true} photo={false} onInitialized={this.onVisionCameraInitialized} onError={this.onVisionCameraError} />

Karina5Aryan avatar Aug 25 '25 12:08 Karina5Aryan

same here anyone found a solution for this issue

ferasabufaresKabi avatar Aug 28 '25 10:08 ferasabufaresKabi

https://github.com/TheWidlarzGroup/react-native-video/commit/d2c92a1f3f6579aa6607389de8e51e4b75012f3b

try this might solve the issue worked for me

Karina5Aryan avatar Sep 01 '25 04:09 Karina5Aryan

@mrousavy it's working for the first time, but on the second time, the audio is missing from the video.

i am also facing same issue .. Any update for this issue

vkanagarajan avatar Sep 10 '25 13:09 vkanagarajan

Same goes for me too

The video recording works as expected on the first attempt, capturing both audio and video. However, after navigating away from the recording screen and returning, subsequent recordings only capture video while the audio track is missing. Interestingly, restarting the app restores the functionality for the first recording, but the same issue reoccurs on the second attempt.

I have both audio and camera permissions are granted.

it is only happening in IOS ,in android it is working fine.

<Camera key={this.state.cameraInstanceKey} ref={ref => {this.camera = ref}} style={styles.preview} device={cameraType ? backdevice : frontdevice} isActive={isCameraActive} video={true} audio={true} photo={false} onInitialized={this.onVisionCameraInitialized} onError={this.onVisionCameraError} />

i am also facing exactly same issue. any solution found for this issue

vkanagarajan avatar Sep 10 '25 13:09 vkanagarajan

@vkanagarajan

Try this solution

Worked for me

https://github.com/TheWidlarzGroup/react-native-video/commit/d2c92a1f3f6579aa6607389de8e51e4b75012f3b in library react-native-video

Karina5Aryan avatar Sep 10 '25 14:09 Karina5Aryan

I'm facing with the same issue, any solution for that

Tranthanh98 avatar Sep 27 '25 09:09 Tranthanh98

@LOGANLEEE @cloud-github I have the same problem. On iOS, the sound disappears on the second or third recording. On Android, it happens during the recording โ€” meaning, half of the video has sound, and the other half doesnโ€™t.

Abdullo-0901 avatar Oct 20 '25 07:10 Abdullo-0901

I use:

"react-native-video": "^6.17.0",
 "react-native-vision-camera": "^4.7.2",

But the video is still mute after adding disableAudioSessionManagement={true}

sleekLancelot avatar Nov 07 '25 17:11 sleekLancelot