从Firefox 49开始,来自IP摄像机的MJPEG流使用内部服务冻结第一帧。这不会发生在Chrome中。我找不到可能导致此错误的FF 49更改日志中的任何更改。请记住,此代码不是我的,并且非常陈旧,但它仍可在Chrome中运行。 我认为可能导致错误的代码片段:
String.Join()
请记住,这个程序很大,我只是采用了我认为可能导致错误的片段。它适用于49之前的所有Firefox版本,目前在Chrome上
答案 0 :(得分:0)
您依赖的是chrome bug。
根据specs:
...当CanvasImageSource对象表示HTMLOrSVGImageElement中的动画图像时,用户代理必须使用动画的默认图像(当不支持动画或禁用动画时,将使用格式定义的图像),或者,如果没有这样的图像,则在为CanvasRenderingContext2D API渲染图像时动画的第一帧。
MJPEG流是这些动画图像的一部分,因此UAs必须仅返回第一帧。 Chrome最近遵循了这部分规格,但仅用于GIF图片。
因此,通过在每次重绘时在请求中添加随机参数,仍然有强制完全重新加载MJPEG流的解决方法,但是你将失去MJPEG格式的所有优点并且会产生大量繁重的请求。
var url = 'http://webcam.st-malo.com/axis-cgi/mjpg/video.cgi?resolution=352x288';
var img = new Image();
img.onload = drawAndReload;
// check if there are already parameters in the passed url
var paramHead = url.indexOf('?') > 0 ? '&' : '?';
img.src = url;
var ctx = c.getContext('2d');
function drawAndReload(){
if(c.width !== this.naturalWidth){
c.width = this.naturalWidth;
c.height = this.naturalHeight;
}
ctx.drawImage(this, 0, 0);
// reset the image
this.src = ''; // should not be necessary
this.src = url + paramHead + Math.random(); // force no-cache
}
<canvas id="c"></canvas>
一个真正的解决方案是将您的MJPEG流转换为视频流服务器端,然后使用MediaSource API获取块并将其显示在HTMLVideoElement中,您将能够在其上绘制画布没有限制。