在html5中渲染MJpeg流

时间:2013-10-13 15:16:45

标签: javascript html5 mjpeg

我正在尝试使用img标记在HTML5中呈现MJpeg流。 当我运行以下内容时,一切都运行良好,意味着视频开始播放,直到视频结束:

<img src="http://[some ip]:[port]/mjpg">

我的问题是如何逐帧获取流。 对于每一帧,我想得到它,做一些事情(ajax调用服务器),然后将帧显示为图像。

感谢。

3 个答案:

答案 0 :(得分:3)

如果相机曝光原始JPEG图像(不是.MJPEG扩展名),则必须手动对其进行自动加载(如果扩展名为.MJPEG,则浏览器将执行所有操作,只需输入正确的src)。如果您有.MJPEG并想使用原始.JPEG检查您的相机文档。大多数相机都会暴露.MJPEG和原始.JPEG流(仅在不同的URL上)。

不幸的是,您无法通过ajax轻松获取图像,但您可以定期更改图像的src。

您可以使用Date.getTime()并将其添加到查询字符串中以强制浏览器重新加载图像,并在每次加载图像时重复。

如果使用jQuery,代码将如下所示:

camera.html

<!DOCTYPE html>
<html>

<head>
    <title>ipCam</title>
</head>

<body>
    <h1>ipCam</h1>
    <img id="motionjpeg" src="http://user:pass@127.0.0.1:8080/" />
    <script src="motionjpeg.js"></script>
    <script>
        //Using jQuery for simplicity

        $(document).ready(function() {
            motionjpeg("#motionjpeg"); // Use the function on the image
        });
    </script>
</body>

</html>

motionjpeg.js

function motionjpeg(id) {
    var image = $(id), src;

    if (!image.length) return;

    src = image.attr("src");
    if (src.indexOf("?") < 0) {
        image.attr("src", src + "?"); // must have querystring
    }

    image.on("load", function() {
        // this cause the load event to be called "recursively"
        this.src = this.src.replace(/\?[^\n]*$/, "?") +
            (new Date()).getTime(); // 'this' refers to the image
    });
}

注意我的示例将在页面加载时播放MotionJPEG,但不允许播放/暂停/停止功能

答案 1 :(得分:3)

您可以执行此操作而无需重复发出Http请求。仅一个就足够了。您可以使用fetch api创建一个ReadableStream,访问它的Reader并继续从流中读取。

一旦您有了读取器,便会递归地从流中读取块。在字节流中寻找SOI(0xFF 0xD8),该信号指示标头的结尾和JPEG帧的开头。标头将包含要读取的JPEG长度(以字节为单位)。从块和任何后续块中读取那么多字节,并将其存储到Uint8Array中。一旦你 成功读取框架,将其转换为Blob,从中创建一个UrlObject,并将其分配给img对象的src属性。

继续执行直到连接关闭。

无耻的插头。这是指向github上的工作示例的链接。

答案 2 :(得分:2)

如果您的流源无法在另一个地址(http:// [some ip]:[port] / frame / XXX)上返回帧,那么您可以在服务器上使用MJPEG流解析器。例如,Paparazzo.js解析流并返回单个jpeg。实际上它只返回最后一帧而不保存前一帧,但可以更改它。

只有在没有插件和服务器的js浏览器中才能解决问题。