I try to start the users camera in an html5 app. On my pc this works fine, but testing this on iphone (chrome and safari) the event playing is not triggered.
I created a minimalistic html-page to test this.
<!DOCTYPE html>
<html>
<head>
</head>
<body onload="pageLoaded()"> </body>
<script >
async function startCamera() {
let stream = await navigator.mediaDevices.getUserMedia({ video: {facingMode: 'user'}, audio: false});
if(!stream) return;
let video = document.createElement("video");
video.srcObject = stream;
video.oncanplay = (ev) => {
console.log("video can play");
video.oncanplay = "";
}
video.onplaying = (ev) => {
console.log("video is playing");
}
video.play();
}
function pageLoaded() {
startCamera();
}
</script>
</html>
On mobile I use chrome://inspect to see the logs.
"video can play" is shown, but "video is playing" never shows up.
On my desktop pc, this works just fine.
I didn’t test firefox, edge and opera though…
And I don’t have an android device to test this.
But as I looked up the specification it showed up that the "playing" event is supported by every modern browser.
Does anyone know what I am missing here? Do need to make an additional request for user rights? Do I need to wait for another event to chain the events?
After another test (thx for the comment), this code works.
The trick seems to be clicking the video element to play the camera video stream. Here is the code:
<!DOCTYPE html>
<script >
async function startCamera() {
let stream = await navigator.mediaDevices.getUserMedia({ video: {facingMode: 'user'}, audio: false});
if(!stream) return;
let video = document.createElement("video");
video.style.width = 400;
video.style.height = 400;
video.style.border = "1px solid red";
document.body.appendChild(video);
video.srcObject = stream;
video.oncanplay = (ev) => {
console.log("video can play");
video.oncanplay = "";
}
video.onplaying = (ev) => {
console.log("video is playing");
}
video.onclick = () => { video.play();}
//video.play();
}
function pageLoaded() {
startCamera();
}
</script>
It would be nice if the user didn’t have to do the click, but I guess for now I’ll use it that way until I figure out how to solve this. Help is appreciated.
2
Answers
I made some further tests. It seems, you don't have to add the video element to the document. But on mobile you can't start the video automatically but have to user to "click" something to activly start the video.
Here is a piece of code to show the behaviour on ios.
So "clicking" the video elements works (you will have to add it then) or "clicking" some button will also do the trick. One thing though. If I do not display the video element (not added to document or display = none) the camera screen on my mobile keeps black. Displaying the video element on the website shows me looking into the camera.
To prevent nasty ads from playing automatically, some browsers prevent autoplay, which includes calling
.play()
without user interaction.play ()
returns a promise to indicate the success.https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/play#usage_notes