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.
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
Although the term "autoplay" is usually thought of as referring to pages that immediately begin playing media upon being loaded, web browsers' autoplay policies also apply to any script-initiated playback of media, including calls to play().