Closed MrSolimanKing closed 11 months ago
Whoops, sorry. Fixed this in https://github.com/mrousavy/react-native-vision-camera/pull/2221! :) Let me know if that works for you :)
@mrousavy Fantastic! It's now working flawlessly and perfectly. Thank you so much for your tremendous efforts; I truly appreciate everything you've done.
Released that fix in VisionCamera 3.6.11! :)
If you appreciate my time and dedication in maintaining and improving this project, please consider ๐ sponsoring me on GitHub ๐ so I can keep improving VisionCamera!
I am having a similar issue (almost the same) with the latest v4.0.3
version of the lib. I had the same issue with versions v3.7.0
, v3.7.1
, v3.9.2
.
This issue only occurs for iOS devices. In my case audio
is false
too.
I can see that the onRecordingFinished
callback is triggered always after a delay of 4-5 seconds only for iOS devices. On Android it's triggered without delay.
You can find my component below:
const QualityCheckVideoRecording = ({ lines, setVideoRecorded }) => {
const dispatch = useDispatch();
const cameraDevice = useSelector((state) => state.currentCameraOrientation);
const device = useCameraDevice(cameraDevice);
const appState = useRef(AppState.currentState);
const format = useCameraFormat(device, [{ videoResolution: { width: 640, height: 480 } }]);
const cameraRef = useRef(null);
const [isCameraInitialized, setIsCameraInitialized] = useState(false);
const [isCameraActive, setCameraActive] = useState(true);
const isCameraShown = useMemo(() => {
if (platform.isAndroid) {
return device && isCameraActive;
}
return device;
}, [isCameraActive, device]);
useEffect(() => {
cameraRequestPermissionFlow();
}, []);
useEffect(() => {
KeepAwake.activate();
return () => {
KeepAwake.deactivate();
setCameraActive(false);
setIsCameraInitialized(false);
};
}, []);
const handleAppStateChange = useCallback(
(nextAppState) => {
if (appState.current === 'active' && nextAppState.match(/inactive|background/) && cameraRef.current) {
setCameraActive(false);
setIsCameraInitialized(false);
}
if (appState.current.match(/inactive|background/) && nextAppState === 'active') {
Alert.alert('Recording was interrupted', 'Do you want to start it over again?', [
{
text: 'Yes',
onPress: () => {
setCameraActive(true);
},
},
{
style: 'cancel',
text: 'No',
onPress: () => dispatch(navigatePop()),
},
]);
}
appState.current = nextAppState;
},
[cameraRef],
);
useEffect(() => {
const appStateEventSubscription = AppState.addEventListener('change', handleAppStateChange);
return () => {
appStateEventSubscription.remove();
};
}, [handleAppStateChange]);
useEffect(() => {
if (isCameraInitialized && cameraRef.current && isCameraActive && isCameraShown) {
console.log('WILL RUN START RECORDING');
cameraRef.current.startRecording({
onRecordingFinished: (video) => {
console.log('4 - date: ', new Date());
console.log('==== handleVideoUpload');
setCameraActive(false);
setIsCameraInitialized(false);
setVideoRecorded(video);
console.log('5 date: ', new Date());
dispatch(navigatePop());
},
onRecordingError: (e) => Sentry.captureException(e),
fileType: DEFAULT_VIDEO_FORMAT,
videoBitRate: 'low',
});
}
}, [isCameraInitialized, isCameraActive, isCameraShown]);
const handleCameraInitialized = useCallback(() => {
setIsCameraInitialized(true);
}, []);
const retakeVideo = useCallback(() => {
setCameraActive(false);
if (platform.isAndroid) {
setIsCameraInitialized(false);
}
setTimeout(() => setCameraActive(true), 1000);
}, []);
const stopRecording = useCallback(
async (cb) => {
try {
console.log('1 date: ', new Date());
await cameraRef?.current?.stopRecording();
console.log('2 date: ', new Date());
cb();
console.log('3 date: ', new Date());
} catch (e) {
console.log('e: ', e);
Sentry.captureException(e);
Alert.alert('There was a problem with recording', 'Do you want to start it over again?', [
{
text: 'Yes',
onPress: retakeVideo,
},
{
style: 'cancel',
text: 'No',
},
]);
}
},
[retakeVideo, cameraRef],
);
const showPauseModal = useCallback(() => {
if (cameraRef.current) {
cameraRef.current.pauseRecording();
dispatch(
showModal({
key: '/orders/pause-qc-video-recording',
props: { retakeVideo, stopRecording, lines, setCameraActive },
}),
);
}
}, [cameraRef, dispatch, stopRecording, retakeVideo, lines]);
return (
<View style={styles.contentContainer}>
{isCameraShown ? (
<Camera
collapsable={false}
style={styles.container}
ref={cameraRef}
video
audio={false}
device={device}
onInitialized={handleCameraInitialized}
isActive={isCameraActive}
format={format}
/>
) : null}
<Pressable onPress={showPauseModal} style={styles.cameraActions}>
<Icon style={styles.captureIcon} name="camera" />
</Pressable>
</View>
);
};
My dependencies:
"react": "18.2.0",
"react-native": "0.72.5",
"react-native-vision-camera": "^4.0.3",
Tested on iPhone 12 and Pixel 6a devices
I guess this might be still an issue @mrousavy
What's happening?
My Camera app has 2 options one to record video with audio and one to record without audio, I noticed when I finish recording when the audio is
false
audio={false}
it has a5 - 10
seconds delay in comparison with when the Audio is enabledaudio={true}
which it triggeronRecordingFinished: async (video) => {}
immediately when finish recordingReproduceable Code
Relevant log output
Camera Device
Device
iPhone 12
VisionCamera Version
3.6.10
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