我正在网页上显示来自IP摄像头的MJPEG流。使用图像元素显示流,该元素由jquery:
设置view = $('<img>');
view.load(function() {
console.log('loaded');
});
view.error(function() {
console.log('error');
});
view.attr('src', 'http://camera_ip/videostream.mjpeg');
当各自的情况发生时,这两件事都会整齐地发生。直到我断开相机。图像冻结(当然)。我想检测此断开连接,以向用户显示错误消息。我想出了一个解决方案,即将图像从画面复制几秒钟到画布,然后比较内容。
有更简单的选择吗?
答案 0 :(得分:0)
我能想到在前端执行此操作的唯一方法是在设置图像的src属性时创建一个AJAX请求。当mjpeg流结束时,AJAX请求应该调用“完整”回调。
如果您对node.js和/或websockets感到满意,您可以选择设置mjpeg代理后端,该后端提供mjpeg流,并在流结束时通过websocket向该客户端发出'close'事件。所以它看起来像这样(请记住,我仍然没有弄清楚bufferToJPEG将如何解析流中的单个jpeg帧):
http.get('http://camera_ip/videostream.mjpeg', function(response) {
var buffer = "";
response.on('data', function(chunk) {
buffer += chunk;
clientSocket.emit('imageFrame', bufferToJPEG(buffer));
});
response.on('end', function() {
clientSocket.emit('imageEnd');
});
});
这个问题(我现在正试图在我自己的项目中处理)是你必须将websocket与每个图像请求相关联,或者在它们进来时从mjpeg流中发出原始jpeg在websockets上(你可以在前端渲染那些带有数据uris的图像)。
希望有所帮助 - 抱歉,你不得不等待很长时间才能得到答复。
编辑:https://github.com/wilhelmbot/Paparazzo.js看起来像是按照我上面描述的方式代理该图片的好方法。
答案 1 :(得分:0)
以下是我在阅读zigzack攻击答案后想出的内容。我使用&#34; datauri&#34;为简单起见,但为了对最终图像进行更精细的控制,我还成功测试了&#34; node-canvas&#34;包而不是。
var mjpeg2jpegs = require('mjpeg2jpegs')
const Datauri = require('datauri')
var camURL = '/videostream.cgi?user=admin&pwd=password'
var camPort = 81
var camTimeout = 10000
var FPS_DIVIDER = 1
var options = {
hostname: '192.168.1.241',
port: camPort,
path: camURL,
timeout: camTimeout
}
function startCamStream (camName, options) {
var http = require('http')
var req = http.request(options, mjpeg2jpegs(function (res) {
var data
var pos = 0
var count = 0
res.on('imageHeader', function (header) {
// console.log('Image header: ', header)
data = new Buffer(parseInt(header['content-length'], 10))
pos = 0
})
res.on('imageData', function (chunk) {
// console.log('Image data: ', data.length)
chunk.copy(data, pos)
pos += chunk.length
})
res.on('imageEnd', function () {
// console.log('Image end')
if (count++ % FPS_DIVIDER === 0) {
const datauri = new Datauri()
datauri.format('.jpeg', data)
socket.emit(camName, datauri.content) // Send the image uri via websockets.
}
})
})).on('timeout', function () {
console.log('timeout')
startCamStream(camName, options)
}).end()
}
startCamStream('ipcam1', options)
使用vue.js(可选)我只是使用img标签嵌入图像uri。
<img :src="ipcam1" alt="ipcam1" />
增加FPS_DIVIDER变量将减少fps输出。如果您想在超时时更改图像,则可以发送&#34;离线&#34;图像到达&#34;超时&#34;回调。