🎥
M5CameraやラズパイなどのMJPEGデータを中継するNode.jsサーバ
M5Cameraに最初に書き込まれているのは使いやすいけど…
複数からのアクセスでstreamが見れない!
M5Cameraのコード変えてもいいけど…中継するサーバー作って、複数のM5Cameraの映像を管理するのもありかなぁと思い作りました。
環境
- Node.js v14.15.0
- ライブラリ
- mjpeg-server 0.3.1
- mjpeg2jpegs 1.0.6
M5Cameraに書き込むコード
自分が作ったMDNSに対応させたM5Camera用のプラグラムです
最初にあったコードに追記する形なのでできることは変わりません
Node.js側のソースコード
const express = require('express');
const http = require('http');
const app = express();
const mjpeg2jpegs = require('mjpeg2jpegs');
const mjpegServer = require('mjpeg-server');
const PORT = 8800;
// 複数のクライアントに対応
let buff = Buffer.alloc(0);
// サーバー開始直後にm5cameraから画像取得処理開始
const httpOption = {
hostname: 'm5camera_1.local',
path: '/stream',
port: 81,
responseType: 'arraybuffer',
headers: {
'Content-Type': 'image/jpeg',
},
};
const httpHandler = mjpeg2jpegs((mjpegRes) => {
let processBuff = Buffer.alloc(0);
mjpegRes.on('imageData', (data) => {
// 送られ続けているデータをつなげてためていく
processBuff = Buffer.concat([processBuff, data]);
});
mjpegRes.on('imageEnd', () => {
// 1枚の画像データが完成のタイミング
buff = Buffer.concat([processBuff]);
processBuff = Buffer.alloc(0);
});
});
http.request(httpOption, httpHandler).end();
// motionJpegサーバ
app.get('/', async (req, res) => {
// モーションjpegサーバーの作成 リクエストごとに作成
const mjpegReqHandler = mjpegServer.createReqHandler(req, res);
let c = 0;
const interval = setInterval(() => {
mjpegReqHandler.write(buff);
console.log(c++); // ここの無限ループが抜けられない
if (false) {// クライアントが切断したらここを通らせたい
mjpegReqHandler.close();
clearInterval(interval);
}
}, 100);
});
app.listen(PORT, () => {
console.log('Running at http://localhost:' + PORT);
});
mjpeg2jpegs
を使ってM5Cameraの映像バッファーをまずは取得する
mjpeg-server
でそのバッファーを配信
無限ループが終わらせられなかった…
コード内にも書いてある部分を抜けられなかった
サーバにアクセスし、別のページとかに遷移しちゃってもカウントが止まっていない
ライブラリのexampleにも無限に配信するものがあるわけではなく、配信用途にMJPEGはあってないのかなぁと思いました
おまけ MJPEGをWebサイトで見る
<img src="http://localhost:8800"/>
<!-- or -->
<img src="http://m5camera_1.local:81/stream"/>
簡単ですね
Discussion