代码之家  ›  专栏  ›  技术社区  ›  MM PP

在画布中渲染MJPEG流规格不允许像在“视频”上那样简单地重画“画布”[重复]

  •  1
  • MM PP  · 技术社区  · 7 年前

    我正试图写一个实时的mjpg视频流到一个html画布。

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

    理想的解决方案有任何活的mjpg(理想的链接?)在fiddle中的html画布上进行流式处理。

    如果有任何有用的资源,我希望不包括外部库(允许jquery)

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

    编辑:我也有一个本地的mjpg从类似的例子。解决方案可以使用本地流

    0 回复  |  直到 9 年前
        1
  •  3
  •   Kaiido    7 年前

    根据 to specs 关于CanvasRenderingContext2D drawImage 方法,

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

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

    注意chrome has a bug 只尊重它 .gif文件 但总有一天他们会修复的。

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

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


    编辑2018


    两年后,我想到了第三个解决办法:

    UAs不必保持相同的内存 默认图像 对于文档中的所有2dcontext。
    而对于其他格式,我们仍然有点卡住,对于MJPEG流,它没有一个很好的定义 默认图像 ,我们实际上是 动画的第一帧 .

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

    这是一个仅在火狐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),但它仍然可能比充斥网络要好无论如何,所有这些都应该很容易被垃圾收集。

        2
  •  1
  •   dev7    10 年前

    许多IP mjpeg相机实际上是以预先定义的帧速率发送单独的jpeg文件,当频繁更新时,它看起来像一个视频。

    您需要检查相机的制造商API,以获得用于获取图像流的正确url,例如,使用Foscam相机,我以前做过以下操作,它工作得很好:

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

    显然,你必须得到相机的正确IP和端口号(如果存在)。

    更新- 这并不意味着你不能有其他的直播视频流方法可用,这只是最简单的方式,我知道从一个IP摄像机获取直播视频。

    更新2 -另外,有些相机有用户名和密码,因此您可能需要将它们附加到url videostream.cgi?user=your_user&password=your_password

    希望这有帮助。