On iOS: User allows camera but the video element is blank & console error "Unhandled Promise Rejection: NotAllowedError"

62 views Asked by At

Why do I get Unhandled Promise Rejection: NotAllowedError even after the user allows the camera for the page?

I have a webpage that is requesting the camera and streaming it to a video element on the page. It works on my laptop (chrome), but on iOS (safari & chrome), the video element is blank, and there's a console error saying

Unhandled Promise Rejection: NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.

and the line number for the exception is on the line that plays the video this.video.play(). See below.

HTML

            <div class="camera" class.bind="cameraLoading ? 'hidden' : ''">
                <video id="camera-view" ref="video">Video stream not available.</video>
                <div id="button-div">
                    <button id="capture-button" ref="captureButton">
                        <i class="fa fa-camera"></i>
                    </button>
                </div>
                <canvas id="overlay-canvas" ref="overlayCanvas"></canvas>
            </div>

JavaScript

        let constraints = {
            video: {
                width: {ideal: 2160},
                height: {ideal: 2160}
            }
        }

        navigator.mediaDevices
            .getUserMedia(constraints)
            .then((stream) => {
                let videoTrack = stream.getVideoTracks()[0];
                let capabilities = videoTrack.getCapabilities();
                let ideal = Math.min(capabilities.width.max, capabilities.height.max)
                videoTrack.applyConstraints({video: {ideal: ideal}, width: {ideal: ideal}, aspectRatio: 1})
                this.video.srcObject = stream

                this.video.play()

                setInterval(() => {
                    this.cameraLoading = false
                }, 50)
            })
            .catch((err) => {
                console.error(`An error occurred:`, err)
            })

Interestingly, if I click the button to capture the picture. It does capture the picture from the camera. It's just that the video stream isn't getting to the video element. Also, if I navigate to a different view and then come back to the camera view without ever reloading the page (it's a single-page app), the video element loads perfectly. Also, and I'm not sure this is related, it sometimes loads the video element fullscreen.

1

There are 1 answers

0
SGT Grumpy Pants On

I needed to add playsinline to the video element. I stumbled on this when I was trying to figure out why it sometimes loaded fullscreen, and I'm not entirely sure why it works. I also added preload="none", but I've tested them separately, and playsinline is solving the problem.

<video id="camera-view" ref="video" playsinline>Video stream not available.</video>