我为我的公司创建并维护了一个视频流网站。其中一项功能是在全公司范围内播放直播流。 一段时间以来,我收到一些用户的投诉,说如果他们更改标签,流就会停止。 在花了很长时间重现问题后(请参阅这个问题)我发现无论节能/内存节省选项如何,Chrome 都会停止流以节省电池电量。 我在只有以下 HTML 的页面中进行了测试:
<html>
<body>
<video src="<source of the video stream>" controls autoplay></video>
</body>
</html>
如果我在视频开始后更改标签并且不返回视频标签,在 Chrome 上,音频未静音,视频将在大约 1 分钟后停止并显示以下消息:
Uncaught (in promise) DOMException: The play() request was interrupted because
video-only background media was paused to save power.
https://developer.chrome.com/blog/play-request-was-interrupted/
(错误中真实的url被缩短了,但是SO不允许缩短的url)
然而这并没有发生在 Youtube 上。在 youtube 中,无论标签是否隐藏,视频都会继续播放。 所以我检查了一个正在播放的 youtube 视频,发现他们每隔几秒就会调用一个这样的 url:
所以我认为答案是频繁调用后端。由于我的系统也经常调用后端来保存统计信息,我虽然只需要更新调用的频率。
没用。甚至后端调用的频率为 2s。视频在大约 1 分钟后继续停止。
那么……Youtube 的秘密是什么?为什么他们的视频不会停止,而我的视频会在 1 分钟后停止?我该怎么做才能保持视频播放并避免出现该消息?
这是一个 Angular 前端/nodejs 后端系统。
你至少需要像这样处理
promise
:
<html>
<body>
<video id="video" src="<video stream>" preload="auto" controls autoplay></video>
</body>
<script>
var promise = document.querySelector('video').play();
if (promise !== undefined) {
promise.then(_ => {
// Autoplay started!
}).catch(error => {
// Autoplay was prevented.
// Show a "Play" button so that user can start playback.
// OR run your function that resumes the video anyway idk
});
}
</script>
</html>
此外,我认为 Youtube 使用 Api(类似的东西)来确定用户与视频进行了交互,因此它知道如果可见性发生变化,它将继续播放。
在您的独特情况下,您正试图绕过 Chromium 政策 自动播放的视频应该静音,而用户没有互动的视频应该在注意力不集中时停止。我认为您需要使用上面的示例处理错误和/或可能添加一个 event listener 以等待
suspend
事件并播放视频。
const video = document.querySelector("video");
video.onsuspend = (event) => {
console.log("Data loading has been suspended.");
// keep playing video
};
根据我的发现,您可能必须默认将视频静音,并且需要用户交互或手势才能静音。这样就会遵循 Chrome 的自动播放策略,因此切换标签应该可以工作。
我还建议,如果您的公司在此期间需要变通办法,Firefox 可能会工作,因为它不在 Chromium 上运行。
蟒蛇分类!