9

我正在尝试使用 img 标签在 HTML5 中呈现 MJpeg 流。当我运行以下命令时,一切正常,这意味着视频开始播放,直到视频结束:

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

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

谢谢。

4

3 回答 3

7

您可以在不重复发出 Http 请求的情况下执行此操作。只有一个就足够了。您可以使用fetch api创建一个ReadableStream,访问它的Reader并继续从流中读取。

一旦你让阅读器继续递归地从流中读取块。在字节流中查找 SOI (0xFF 0xD8),它表示标头的结束和 JPEG 帧的开始。标头将包含要读取的 JPEG 的长度(以字节为单位)。从块和任何连续的块中读取那么多字节并将其存储到Uint8Array中。成功读取帧后,将其转换为 blob,从中创建一个 UrlObject 并将其分配给 img 对象的 src 属性。

继续这样做,直到连接关闭。

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

于 2018-09-14T09:04:18.887 回答
4

如果相机显示原始 JPEG 图像(不是 .MJPEG 扩展名),您必须手动重新加载它(如果扩展名是 .MJPEG,浏览器将执行所有操作,只需输入正确的 src)。如果您有 .MJPEG 并且想要使用原始 .JPEG,请查看您的相机文档。大多数相机都会公开 .MJPEG 和原始 .JPEG 流(只是在不同的 URL 上)。

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

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

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

相机.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,但不允许播放/暂停/停止功能

于 2015-12-17T12:05:26.253 回答
2

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

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

于 2013-10-14T22:05:21.940 回答