一、异常错误
WebRTC 是一种用于实时通信的开放式标准,可以让您通过浏览器进行视频和音频通信。使用 WebRTC 技术可以让您实现低延迟的视频通信,从而解决摄像头延迟的问题。
在使用 HTML5 音频或视频时,有时会遇到 DOMException 错误,错误信息为 The play() request was interrupted by a new load request. 这个错误通常发生在当你试图在一个媒体文件正在加载的时候播放另一个媒体文件时。
mse-controller.js:110 Uncaught (in promise) DOMException: The play() request was interrupted by a new load request.
二、原因
解决这个问题的方法很简单,只需要在播放新的媒体文件之前,先停止当前正在播放的媒体文件,等待当前正在加载的媒体文件加载完成,再播放新的媒体文件即可。
另外,在刷新摄像头请求时,如果没有清理旧的定时器,会导致多个定时器同时在运行,最终导致页面卡住。为了解决这个问题,可以将定时器的 ID 存储在一个全局变量中,然后在每次刷新请求时,先清理旧的定时器,再创建新的定时器。
改变之前的代码如下:
function register() { $.ajax({ url: '/dev-api/system/config/configKey/camera.request.ip', beforeSend: function (request) { request.setRequestHeader("Authorization", "Bearer " + getCookie("Admin-Token")); }, success: (res) => { console.log(res); $.ajax({ url: `http://${res.msg}:800/index/api/addStreamProxy`, data: { "secret": `035c73f7-bb6b-4889-a715-d9eb2d1925cc`, "vhost": `${res.msg}`, "app": "live", "stream": getParams("orderNum"), "url": "rtsp://admin:" + `${getParams("password")}@${getParams("ip")}` }, }); start(res.msg) } }); } function start(configIP) { if (flvjs.isSupported()) { var videoElement = document.getElementById('videoElement'); var flvPlayer = flvjs.createPlayer({ type: 'flv', url: `http://${configIP}:800/live/${getParams("orderNum")}.flv` }); flvPlayer.attachMediaElement(videoElement); flvPlayer.load(); flvPlayer.play(); setInterval(() => { // 停止播放 flvPlayer.unload(); flvPlayer.detachMediaElement(); // 重新播放 start(configIP) }, 5000); } }
三、解决方法
优化后的代码如下,在代码中,我们定义了一个全局变量 timerId,用来存储定时器的 ID。在每次刷新请求时,我们先清理旧的定时器,然后再创建新的定时器。这样就可以避免多个定时器同时在运行导致页面卡顿的问题。
var timerId; // 全局变量,存储定时器ID function register() { $.ajax({ url: '/dev-api/system/config/configKey/camera.request.ip', beforeSend: function (request) { request.setRequestHeader("Authorization", "Bearer " + getCookie("Admin-Token")); }, success: (res) => { console.log(res); $.ajax({ url: `http://${res.msg}:800/index/api/addStreamProxy`, data: { "secret": `035c73f7-bb6b-4889-a715-d9eb2d1925cc`, "vhost": `${res.msg}`, "app": "live", "stream": getParams("orderNum"), "url": "rtsp://admin:" + `${getParams("password")}@${getParams("ip")}` }, }); start(res.msg) } }); } function start(configIP) { if (flvjs.isSupported()) { var videoElement = document.getElementById('videoElement'); var flvPlayer = flvjs.createPlayer({ type: 'flv', url: `http://${configIP}:800/live/${getParams("orderNum")}.flv` }); flvPlayer.attachMediaElement(videoElement); flvPlayer.load(); flvPlayer.play(); // 清理旧的定时器 if (timerId) { clearInterval(timerId); } // 创建新的定时器 timerId = setInterval(() => { // 停止播放 flvPlayer.unload(); flvPlayer.detachMediaElement(); // 重新播放 start(configIP) }, 5000); } }
总结一下,解决 DOMException 错误的方法就是在播放新的媒体文件之前,先停止当前正在播放的媒体文件,等待当前正在加载的媒体文件加载完成,再播放新的媒体文件。而解决摄像头延迟的问题,就是在每次刷新请求时,清理旧的定时器,再创建新的定时器。这样就可以避免多个定时器同时在运行导致页面卡顿的问题。