我使用了arun tom在Rendering MJpeg stream in html5的“ Shameless Plug”上提出的代码。
https://github.com/aruntj/mjpeg-readable-stream。
开始工作。但是,当我尝试使用多于1台摄像机时,几秒钟后一个或另一个失败。即使两个传入的流确实起作用,它们也会闪烁很多。用一台相机,效果很好。
Chrome开发者控制台中显示的错误:
index.js:61 RangeError: Invalid array buffer length
at new ArrayBuffer (<anonymous>)
at index.js:40
我做了一些原始代码。产生了嵌入式功能,并且尝试提取“ Content-Length”时还存在一个问题,因为原始代码的长度为小写“ l”。
我在'setInterval()'中以超时时间播放。我还在服务器端以较低的fps播放。
在服务器端,它是Raspberry Pi 3,我在两个不同的终端上分别运行以下命令:
mjpg_streamer -i "input_uvc.so -r 320x240 -d /dev/video0 -f 30 -q 80" -o "output_http.so -p 8080 -w /home/devchu/public_html"
mjpg_streamer -i "input_uvc.so -r 320x240 -d /dev/video1 -f 30 -q 80" -o "output_http.so -p 8081 -w /home/devchu/public_html"
HTML本质上是:
<img id="image0" alt="no image 1"/>
<img id="image1" alt="no image 2"/>
index.js:
'use strict';
const SOI = new Uint8Array(2);
SOI[0] = 0xFF;
SOI[1] = 0xD8;
const CONTENT_LENGTH = 'content-length';
const TYPE_JPEG = 'image/jpeg';
let contentLength = -1;
let headers = '';
let imageBuffer = null;
let bytesRead = 0;
let frames = 0;
const getLength = (headers) => {
let contentLength = -1;
headers.toLowerCase().split('\n').some((header, _) => {
const pair = header.split(':');
if (pair[0] === CONTENT_LENGTH) {
contentLength = pair[1];
return;
}
});
return contentLength;
}
const read = (reader, imageTag) => {
reader.read().then(({done, value}) => {
if (done) {
controller.close();
return;
}
for (let index =0; index < value.length; index++) {
// we've found start of the frame. Everything we've read till now is the header.
if (value[index] === SOI[0] && value[index+1] === SOI[1]) {
// console.log('header found : ' + newHeader);
contentLength = getLength(headers);
// console.log("Content Length : " + newContentLength);
imageBuffer = new Uint8Array(new ArrayBuffer(contentLength));
}
// we're still reading the header.
if (contentLength <= 0) {
headers += String.fromCharCode(value[index]);
}
// we're now reading the jpeg.
else if (bytesRead < contentLength){
imageBuffer[bytesRead++] = value[index];
}
// we're done reading the jpeg. Time to render it.
else {
imageTag.src = URL.createObjectURL(new Blob([imageBuffer], {type: TYPE_JPEG}));
frames++;
contentLength = 0;
bytesRead = 0;
headers = '';
}
}
read(reader, imageTag);
}).catch(error => {
console.error(error);
})
}
const streamToImage = (url, imageTag) => {
fetch(url)
.then(response => {
if (!response.ok) {
throw Error(response.status+' '+response.statusText)
}
if (!response.body) {
throw Error('ReadableStream not yet supported in this browser.')
}
const reader = response.body.getReader();
setInterval(() => {
console.log("fps : " + frames);
frames = 0;
}, 200);
read(reader, imageTag);
}).catch(error => {
console.error(error);
})
}
const url1 = 'http://10.0.0.58:8080/?action=stream';
const url2 = 'http://10.0.0.58:8081/?action=stream';
streamToImage(url1, image0);
streamToImage(url2, image1);