Не выводится изображение с камеры на страницу JavaScript

пытаюсь написать простой код, который будет выводить изображение с камеры на пустую страницу. Пробывал с мобильных телефонов и с ПК, запрос на разрешение камеры выводит и все. В логи консоли следующее сообщение: "Uncaught (in promise) DOMException: Could not start video source" Код index.html:

<html>
    <head>
        <title> Cam </title>
        <script src="script.js"></script>
        <link href="style.css" rel="stylesheet"/>
    </head>

    <body onload="main ()">
        <canvas id="myCanvas"></canvas>
    </body>
</html>

Код script.js:

let VIDEO=null;
let CANVAS=null;
let CONTEXT=null;

function main() {
    CANVAS=document.getElementById("myCanvas");
    CONTEXT=CANVAS.getContext("2d");
    CANVAS.width=window.innerWidth;
    CANVAS.height=window.innerHeight;

    let promise=navigator.mediaDevices.getUserMedia({video:true});
    promise.then(function(signal){
        VIDEO=document.createElement("video");
        VIDEO.srcObject=signal;
        VIDEO.play();

        VIDEO.onloadeddata=function() {
            updateCanvas();
        }
    }).catch(function(err){
        alert("Camera error: "+err);
    });
}

function updateCanvas () {
    CONTEXT.drawImage(VIDEO,0,0);
    window.requestAnimationFrame(updateCanvas);
}

Ответы (1 шт):

Автор решения: Leonid

Здесь в сниппетах по соображениям безопасности не работает, но на пробной странице через LiveServer все хорошо. Попробуйте.

Думаю, что проблема в том, что VIDEO.play(); пытаетесь до "привязки" потоковых данных или в рамках политики безопасности (не проигрывать медиа без прямого действия пользователя). Запуск видео надо добавить в коллбэк, то есть, в функцию updateCanvas(). Это должно работать, ведь пользователь только что подтвердил подключение к его камере, но не гарантируется. Лучше добавить кнопку поверх с просьбой "Включить камеру". И уже смело выполнять VIDEO.play();.

В моем примере работает autoplay = true, но опять же насколько это надежно - большой вопрос.

const video = document.querySelector('video');


if (navigator.mediaDevices.getUserMedia) {
    navigator.mediaDevices.getUserMedia({ video: true })
        .then(stream => {
            video.srcObject = stream;
        })
        .catch(err => {
            console.error(err);
        });
}
<video autoplay="true"></video>

Или так через canvas:

let video = null;
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');


if (navigator.mediaDevices.getUserMedia) {
    navigator.mediaDevices.getUserMedia({ video: true })
        .then(stream => {
            video = document.createElement('video');
            video.autoplay = true;
            video.srcObject = stream;

            video.onloadeddata = setCanvas;
        })
        .catch(err => {
            console.error(err);
        });
}

function updateCanvas(){
    ctx.drawImage(video, 0, 0);
    requestAnimationFrame(updateCanvas);
}

function setCanvas(){
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    updateCanvas();
}
<canvas></canvas>

→ Ссылка