mozmorris / react-webcam

Webcam component
https://codepen.io/mozmorris/pen/JLZdoP
MIT License
1.66k stars 282 forks source link

Webcam media stream shows as active before the user gives permissions. #312

Closed 0xabrarhussain closed 3 years ago

0xabrarhussain commented 3 years ago

Please follow the general troubleshooting steps first:

Bug reports:

It seems that there's no way to tell when the user has given permission to use the the webcam? We know that there's onUserMediaError which should get fired when the user rejects the webcam permission. But even before approving the webcam video permission, we get the following from onUserMedia:

MediaStream {id: "nMGPvRn4ZDcdtrRSNXM2NFIQUeHBBSLMaKH0", active: true, onaddtrack: null, onremovetrack: null, onactive: null, …}
active: true
id: "nMGPvRn4ZDcdtrRSNXM2NFIQUeHBBSLMaKH0"
onactive: null
onaddtrack: null
oninactive: null
onremovetrack: null
__proto__: MediaStream

After giving approval, it doesn't seem like any of these change. Active should be false before permissions are granted right? At the current state, looks like onUserMedia is called even before the user gives permission.

mozmorris commented 3 years ago

@0xabrarhussain can you supply your code and the browser you are using?

I have created a quick demo here: https://codepen.io/mozmorris/pen/LYLOwML?editors=0011 Tested latest Chrome, Safari, and iOS Safari. The onUserMedia callback is called after permission is granted and the stream becomes active. Note, if the user has previously given permission there won't be another prompt.

0xabrarhussain commented 3 years ago

Isolating down to the webcam code, I have code which is doing the following:

export function MyComponent(props) {
  const [hasWebcamUserMedia, setHasWebcamUserMedia] = useState(false);

   return (
  <Webcam
    className='db w-100'
    audio={false}
    mirrored={true}
    ref={cameraRef}
    videoConstraints={{
      facingMode: 'user',
    }}
    onUserMedia={(media) => {
      setHasWebcamUserMedia(true);
    }}
    onUserMediaError={(error) => {
        ...
    }}
  />
  {setHasWebcamUserMedia ? {...} : {...}});
}

Nothing else in the entire component calls setHasWebcamUserMedia, but if I console.log what I'm seeing is that hasWebcamUserMedia starts off false, and then it immediately gets set to true before the user has accepted the permission. So there is a prompt, but it seems to be completely ignored for the onUserMedia callback. The webcam does remain empty.

This is all within an Electron app, so it should be Chromium.

mozmorris commented 3 years ago

@0xabrarhussain your ternary setHasWebcamUserMedia ? etc : etc looks suspicious to me.

That should probably be hasWebcamUserMedia ? etc : etc. If you can create a CodePen I can help further but I suspect you have a bug in your code.

mozmorris commented 3 years ago

Please feel free to reopen if you still believe this is a bug.

0xabrarhussain commented 3 years ago

Ended up being a typo. Do think this is still a bug (onUserMedia runs instantly), but we found a work-around which involves continuously trying to screenshot and seeing if we get a video feed.