后续问题“在html5中渲染MJpeg流”

时间:2019-08-02 15:52:41

标签: javascript html video-streaming raspberry-pi3

我使用了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);

0 个答案:

没有答案