@@ -103,6 +103,7 @@ export function useScreenRecorder(): UseScreenRecorderReturn {
103103 const allowAutoFinalize = useRef ( false ) ;
104104 const discardRecordingId = useRef < number | null > ( null ) ;
105105 const restarting = useRef ( false ) ;
106+ const webcamReady = useRef ( false ) ;
106107
107108 const selectMimeType = ( ) => {
108109 const preferred = [
@@ -182,6 +183,7 @@ export function useScreenRecorder(): UseScreenRecorderReturn {
182183
183184 let cancelled = false ;
184185 let acquiredStream : MediaStream | null = null ;
186+ webcamReady . current = false ;
185187
186188 const acquire = async ( ) => {
187189 try {
@@ -217,11 +219,18 @@ export function useScreenRecorder(): UseScreenRecorderReturn {
217219 } ;
218220 } ) ;
219221 webcamStream . current = stream ;
222+ webcamReady . current = true ;
220223 } catch ( cameraError ) {
221224 if ( ! cancelled ) {
222225 console . warn ( "Failed to get webcam access:" , cameraError ) ;
223226 setWebcamEnabledState ( false ) ;
224- toast . error ( t ( "recording.cameraBlocked" ) ) ;
227+ const isDeviceError =
228+ cameraError instanceof DOMException &&
229+ [ "NotFoundError" , "OverconstrainedError" , "NotReadableError" ] . includes (
230+ cameraError . name ,
231+ ) ;
232+ toast . error ( t ( isDeviceError ? "recording.cameraNotFound" : "recording.cameraBlocked" ) ) ;
233+ webcamReady . current = true ;
225234 }
226235 }
227236 } ;
@@ -230,6 +239,7 @@ export function useScreenRecorder(): UseScreenRecorderReturn {
230239
231240 return ( ) => {
232241 cancelled = true ;
242+ webcamReady . current = false ;
233243 if ( acquiredStream ) {
234244 acquiredStream . getTracks ( ) . forEach ( ( track ) => track . stop ( ) ) ;
235245 webcamStream . current = null ;
@@ -464,9 +474,25 @@ export function useScreenRecorder(): UseScreenRecorderReturn {
464474 }
465475 }
466476
467- if ( webcamEnabled && ! webcamStream . current ) {
468- setWebcamEnabledState ( false ) ;
469- toast . error ( t ( "recording.cameraDenied" ) ) ;
477+ if ( webcamEnabled ) {
478+ if ( ! webcamReady . current ) {
479+ await new Promise < void > ( ( resolve ) => {
480+ const interval = setInterval ( ( ) => {
481+ if ( webcamReady . current ) {
482+ clearInterval ( interval ) ;
483+ resolve ( ) ;
484+ }
485+ } , 50 ) ;
486+ setTimeout ( ( ) => {
487+ clearInterval ( interval ) ;
488+ resolve ( ) ;
489+ } , 5000 ) ;
490+ } ) ;
491+ }
492+ if ( ! webcamStream . current ) {
493+ setWebcamEnabledState ( false ) ;
494+ toast . error ( t ( "recording.cameraDenied" ) ) ;
495+ }
470496 }
471497
472498 stream . current = new MediaStream ( ) ;
0 commit comments