javascriptgoogle-chromemediadevices

Chrome does not prompt user for camera and/or microphone access even in secure context


I have a webpage served via https with the following script:

const userMediaConstraints = {
    video: true,
    audio: true
};

navigator.mediaDevices.getUserMedia(userMediaConstraints)
    .then(stream => { 
        console.log("Media stream captured.")
    });

When I open it in Firefox or Safari, a prompt asking for permission to use camera and microphone appears. But not in Chrome or Opera. There the access is blocked by default and I have to go to site settings and manually allow the access, which is set to Default(ask).

It looks like Chrome and Opera should show prompt, but they do not. I tested it on a different machine with different user that had no prior history with the website with the same result.

What could be wrong?


Solution

  • It turns out, having video with autoplay attribute in HTML or similar lines on page load in Javascript prevent Chrome from showing the prompt.

    HTML that causes this problem:

    <video autoplay="true"></video>
    

    Javascript that causes this problem:

    localVideo = document.createElement('video');
    videoContainer.append(localVideo);
    localVideo.setAttribute('id','localVideo');        
    localVideo.play();
    

    My guess is that the issue has to do with Chrome autoplay policy. Perhaps, Chrome treats my website as providing bad user experience and blocks the prompt?

    I removed <video> from HTML and altered Javascript to create a relevant DOM on getUserMedia:

    let localStream = new MediaStream();
    let localAudioTrack;
    let localVideoTrack;
    let localVideo;
    
    const userMediaConstraints = {
        video: true,
        audio: true
    };
    
    navigator.mediaDevices.getUserMedia(userMediaConstraints)
        .then(stream => { 
            localAudioTrack = stream.getAudioTracks()[0];
            localAudioTrack.enabled = true;
            localStream.addTrack(localAudioTrack);
    
            localVideoTrack = stream.getVideoTracks()[0];
            localVideoTrack.enabled = true;
            localStream.addTrack(localVideoTrack);
    
            localVideo = document.createElement('video');
            videoContainer.append(localVideo);
            localVideo.setAttribute('id','localVideo');
            localVideo.srcObject = localStream;
            localVideo.muted = true;
    
            localVideo.play();
        });
    
    

    And now I get the prompt.