将本地mjpg视频流式传输到html画布

时间:2016-03-21 17:19:56

标签: javascript jquery canvas mjpeg

我正在尝试将mjpg视频的直播流写入html画布。

以下内容:http://camelive.info/有一个包含mjpeg视频的公共网络摄像头列表,但它们似乎正在编写< frameset>带有框架元素的标签,我无法理解它是如何在小提琴中工作的。

理想的解决方案是在小提琴的html画布上播放任何直播mjpg(理想情况下是链接?)。

感谢任何有用的资源,我想这样做而不包括外部库(允许jquery)

修改:相关:How to make an snapshot from a MJPEG stream in HTML

编辑:我也有一个像示例一样的本地mjpg。解决方案可以使用本地流

2 个答案:

答案 0 :(得分:3)

根据to specs关于CanvasRenderingContext2D drawImage方法,

  

具体来说,当 CanvasImageSource 对象表示动画时   在 HTMLImageElement 中的图像,用户代理必须使用默认值   动画的图像(格式定义的图像将被使用   当动画不受支持或被禁用时),或者,如果没有   这样的图像,即动画的第一帧,在渲染图像时   for CanvasRenderingContext2D API。

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

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

你注意到的一个解决方案是使用clear-cache hack('your.url/?' + new Date().getTime();)获取另一个新帧,但你将失去mjpeg格式(部分帧内容)的任何优点而不能确保什么时候会发生更新。

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

编辑2018

两年后第三个解决方案出现在我的小脑袋里:

UA并不依赖于为文档中的所有2DContexts保留相同的默认图像
而对于其他格式,我们仍然有点卡住,对于MJPEG流,没有明确定义的默认图像,我们实际上落到动画的第一帧

因此,通过在两个不同的画布上绘制包含我们的MJPEG流的<img>,在不同的时间,我们理论上可以在画布上绘制两个不同的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),但它仍然可能比充斥网络更好。所有这些都应该很容易收集垃圾。

答案 1 :(得分:1)

其中许多IP mjpeg摄像机实际上以预定义的帧速率发送单独的jpeg文件,经常更新时,它看起来像一个视频。

您需要检查相机的制造商API,以获取用于获取图像流的正确网址,例如使用Foscam相机我之前已完成以下操作并且它完美运行:

<img id='videostream' src="http://123.456.789.233:8080/videostream.cgi">

您显然必须获取相机的正确IP和端口号(如果存在)。

UPDATE - 这并不意味着您无法使用其他实时视频流方法,这只是我知道从IP摄像机获取实时视频的最简单方法。

更新2 - 某些相机也有用户名&amp;密码,因此您可能需要将其附加到网址videostream.cgi?user=your_user&password=your_password

希望这有帮助。