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.
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 addedpreload="none"
, but I've tested them separately, andplaysinline
is solving the problem.