javascript - 将本地 mjpg 视频流式传输到 html canvas

标签 javascript jquery canvas mjpeg

我正在尝试将 mjpg 视频的实时流写入 html Canvas 。

以下:http://camelive.info/有一个包含 mjpeg 视频的公共(public)网络摄像头列表,但它们似乎正在使用框架元素编写 标签,我无法了解它是如何在 fiddle 中工作的。

理想的解决方案是在 fiddle 的 html Canvas 上流式传输任何实时 mjpg(最好是链接?)。

感谢任何有用的资源,我想在不包含外部库(允许 jquery)的情况下执行此操作

编辑:相关:How to make an snapshot from a MJPEG stream in HTML

编辑:我也有一个本地 mjpg 可以从中绘制,就像示例一样。解决方案可以使用本地流

最佳答案

根据to specs关于 CanvasRenderingContext2D drawImage方法,

Specifically, when a CanvasImageSource object represents an animated image in an HTMLImageElement, the user agent must use the default image of the animation (the one that the format defines is to be used when animation is not supported or is disabled), or, if there is no such image, the first frame of the animation, when rendering the image for CanvasRenderingContext2D APIs.

这适用于.gif、SMIL 动画.svg.mjpeg 媒体。因此,一旦获取了数据,就只能在 Canvas 上绘制一帧。

请注意,chrome has a bug并且只尊重 .gif 图像,但他们可能有一天会修复它。

您自己注意到的一个解决方案是使用清除缓存黑客( 'your.url/?' + new Date().getTime(); )获取另一个新帧,但您将失去 mjpeg 格式(部分帧内容)的任何优势,并且无法确定当刷新发生时。

因此,如果适用,更好的解决方案是使用视频格式。视频的每一帧都可以绘制到 Canvas 上。

<小时/>

编辑2018

<小时/>

两年后,第三个解决方案出现在我的脑海中:

UA 并不一定要在内存中为文档中的所有 2DContext 保留相同的默认图像
虽然对于其他格式,我们仍然有点卡住,但对于没有明确定义的默认图像的 MJPEG 流,我们实际上落到了动画的第一帧。

所以通过绘制 <img>在两个不同的 Canvas 上包含我们的 MJPEG 流,在不同的时间,理论上我们可以在 Canvas 上绘制同一 MJPEG 流的两个不同帧。

这是仅在 Firefox 62 上测试的概念验证。

var ctx_stream = stream.getContext('2d');
var ctx_direct = direct.getContext('2d');
img.onload = function() {
   stream.width = direct.width = this.naturalWidth;
   stream.height = direct.height = this.naturalHeight;
   // onload should fire multiple times
   // but it seems it's not at every frames
   // so we'll disable t and use an interval instead
   this.onload = null;
   setInterval(draw, 500);
};
function draw() {
  // create a *new* 2DContext
  var ctx_off = stream.cloneNode().getContext('2d');
  ctx_off.drawImage(img, 0,0);
  // and draw it back to our visible one
  ctx_stream.drawImage(ctx_off.canvas, 0,0);
  
  // draw the img directly on 'direct'
  ctx_direct.drawImage(img, 0,0);
}
  
  
img.src = "http://webcam.st-malo.com/axis-cgi/mjpg/video.cgi?resolution=704x576&dummy=1491717369754";
canvas,img{
  max-height: 75vh;
}
Using a new offcreen canvas every frame: <br><canvas id="stream"></canvas><br>
The original image: <br><img id="img"><br>
Drawing directly the &lt;img> (if this works your browser doesn't follow the specs): <br><canvas id="direct"></canvas><br>

因此,虽然这个解决方案显然会对性能产生影响(我们每帧都创建一个全新的 Canvas 元素及其 2DContext),但它仍然可能比淹没网络要好。无论如何,所有这些都应该很容易被垃圾收集。

关于javascript - 将本地 mjpg 视频流式传输到 html canvas,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38715242/

相关文章:

javascript - javascript 中的加法会产生一个对象

javascript - 如何修改我的垂直可折叠内容面板?

javascript - jQuery 复制内容并在追加之前从中删除类

javascript - jQuery:具有特殊字符的目标属性

javascript - 动画 Canvas 点

javascript - 进行 ajax 调用后日期选择器不工作

javascript - jQuery 脚本不断将我从我正在尝试编辑的页面重定向

Javascript:访问匿名函数中的函数

javascript - Chart.js donut 段内的图片

javascript - html5 Canvas 比例与增加 Canvas 尺寸以进行缩放之间有什么区别?