HTML 视频元素有时无法在 iOS 上以 PWA 模式播放来自 getUserMedia 的流

Chr*_*son 5 javascript ios getusermedia progressive-web-apps svelte

我正在尝试捕获相机输入并在视频元素中播放它。此代码始终适用于桌面 Chrome 和 Safari。在 iOS 上,它始终在使用 Safari 的浏览器模式下工作。

我面临的问题是,它仅有时无法在 iOS 的独立 PWA 模式(保存到主屏幕)下工作。我没有收到任何错误,而且它似乎是随机发生的。我想我修好了它只是为了几个小时后它再次发生。有时关闭应用程序并重新打开可以正常工作,有时需要尝试 10 次以上。我尝试过很多不同版本的代码,异步的、基于承诺的、等待加载的、可以播放的等等。

流加载并处于活动状态(授予权限时),srcObject 显示为正确设置,但 video.play() 不起作用。我尝试等待戏剧承诺,但有时它永远不会解决。视频 ReadyState 保持在 0。有时代码会正常工作,视频会像平常一样播放相机流。

任何帮助将不胜感激。

navigator.mediaDevices
    .getUserMedia({
        video: {
            width: { min: 640, ideal: 1280, max: 1920 },
            height: { min: 480, ideal: 720, max: 1080 },
            facingMode: 'environment'
        },
        audio: true
    })
    .then((stream) => {
        let video = document.createElement('video');
        video.controls = true;
        video.muted = true;
        video.playsInline = true;
        video.onerror = function (e) {
            console.log(e);
        };
        video.onabort = function (e) {
            console.log(e);
        };
        console.log(stream);
        try {
            video.srcObject = stream;
        } catch (e) {
            console.log(e);
            window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
            video.src = window.URL && window.URL.createObjectURL(stream);
        }
        console.log('source: ', video.src);
        console.log('sourceObj: ', video.srcObject);
        console.log(video);
        //Dirty hack to try and debug, same result, tried waiting for play promise, play() onloaded, play() oncanplay, all same result
        //video state sometimes gets to 4, sometimes stays at 0
        let interval = setInterval(() => {
            console.log(video.isConnected);
            console.log(video.readyState);
            console.log(video);
            console.log(stream);
            //will sometimes just stay at readyState 0
            if (video.readyState === 4) {
                video.play();
                window.clearInterval(interval);
            }
        }, 500);
    });

Run Code Online (Sandbox Code Playgroud)