问题描述
我有一个正在收听 mjpeg 视频流的 html/javascript 客户端:
myImg = document.getElementById('my-image');
myImg.src = 'http://myserver.com/camera.mjpeg';
工作正常,但如果视频流因任何原因死机,视频源会在最后收到的图像上“冻结”,我没有机会向用户显示错误。我看到 this post 提供了一个解决方案(在流旁边创建一个长时间运行的 ajax 请求),它只在某些时候有效。我希望有一种更受支持的方法,例如通过 disconnect
事件或其他方式。
即使是接收数据的事件也比没有好。至少通过这种方式我可以判断是否已经有一段时间没有帧通过了。使用 addEventListener('load')
仅适用于第一帧。
有什么想法吗?
更新:
myImg.addEventListener('error',event => { ... });
myImg.addEventListener('stalled',event => { ... });
myImg.addEventListener('suspend',event => { ... });
解决方法
这在 mjpeg
的正常实现中很常见,例如
<video src="http://myserver.com/camera.mjpeg" controls>
Your browser does not support the <code>video</code> element.
</video>
mjpeg 是一系列图像,最终无论出于何种原因,它都不会获得下一个图像,从而破坏了连接。 (这有时是因为源被缓存,导致浏览器每次都使用最后一张图像)。我不认为这是一个错误,更多的是用 mjpeg 流编程。
您可以执行一个简单的解决方案,设置刷新率并设置 src 每约 500 毫秒持续刷新连接(或更少,具体取决于您的网络连接/资源)。
setInterval(function() {
var myImg = document.getElementById('myImg');
myImg.src = 'http://myserver.com/camera.mjpeg?rand=' + Math.random();
},5000);
添加随机数是为了防止在服务器发送这些标头时浏览器端缓存。
或者您可以创建一个 ReadableStream,并继续将字节块直接读入图像源。 this repo 中有一个强大的例子,来自 this other question。
,这样的东西会起作用吗?
function hasLoaded(myImg) {
return myImg.complete && myImg.naturalHeight !== 0;
}