【发布时间】:2013-10-21 05:22:40
【问题描述】:
我正在尝试使用 img 标签在 HTML5 中呈现 MJpeg 流。 当我运行以下命令时,一切正常,这意味着视频开始播放直到视频结束:
<img src="http://[some ip]:[port]/mjpg">
我的问题是如何逐帧获取流。 对于每一帧,我想获取它,做一些事情(对服务器的 ajax 调用),然后将帧显示为图像。
谢谢。
【问题讨论】:
标签: javascript html mjpeg
我正在尝试使用 img 标签在 HTML5 中呈现 MJpeg 流。 当我运行以下命令时,一切正常,这意味着视频开始播放直到视频结束:
<img src="http://[some ip]:[port]/mjpg">
我的问题是如何逐帧获取流。 对于每一帧,我想获取它,做一些事情(对服务器的 ajax 调用),然后将帧显示为图像。
谢谢。
【问题讨论】:
标签: javascript html mjpeg
您可以在不重复发出 Http 请求的情况下做到这一点。只有一个就足够了。您可以使用fetch api 创建ReadableStream,访问它的Reader 并继续从流中读取。
一旦你让阅读器继续递归地从流中读取块。在字节流中查找 SOI (0xFF 0xD8),它表示标头的结束和 JPEG 帧的开始。标头将包含要读取的 JPEG 的长度(以字节为单位)。从块和任何后续块中读取那么多字节并将其存储到Uint8Array 中。一旦你已经 成功读取帧并将其转换为 blob,从中创建一个 UrlObject 并将其分配给 img 对象的 src 属性。
继续这样做直到连接关闭。
无耻的插件。这是github 上的工作示例的链接。
【讨论】:
如果相机显示原始 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,但不允许播放/暂停/停止功能
【讨论】:
如果您的流源无法返回另一个地址 (http://[some ip]:[port]/frame/XXX) 上的帧,那么您可以在服务器上使用 MJPEG 流解析器。例如,Paparazzo.js 解析流并返回单个 jpeg。实际上它只返回最后一帧而不保存前一帧,但可以更改。
问题只能在没有一些插件和服务器的js浏览器中解决。
【讨论】: