サーバー上の大量の JPG ファイルのセットを読み取り (同じディレクトリに JPG ファイルを書き込み続ける別のプロセスがあるため無限)、それらを一定の時間間隔で MJPEG ストリームとしてユーザーのブラウザーに送信するスクリプトを作成しています (以下のコードの変数「frameDelay」)。これは、IP カメラが行うことと似ています。
このスクリプトのメモリ使用量が増え続け、常にシステムによって強制終了されることがわかりました (Ubuntu)。
この一見単純なスクリプトを何度も調べました。したがって、私は以下のコードを投稿しています。コメント/提案は大歓迎です!
app.get('/stream', function (req, res) {
res.writeHead(200, {
'Content-Type':'multipart/x-mixed-replace;boundary="' + boundary + '"',
'Transfer-Encoding':'none',
'Connection':'keep-alive',
'Expires':'Fri, 01 Jan 1990 00:00:00 GMT',
'Cache-Control':'no-cache, no-store, max-age=0, must-revalidate',
'Pragma':'no-cache'
});
res.write(CRLF + "--" + boundary + CRLF);
setInterval(function () {
if(fileList.length<=1){
fileList = fs.readdirSync(location).sort();
}else{
var fname = fileList.shift();
if(fs.existsSync(location+fname)){
var data = fs.readFileSync(location+fname);
res.write('Content-Type:image/jpeg' + CRLF + 'Content-Length: ' + data.length + CRLF + CRLF);
res.write(data);
res.write(CRLF + '--' + boundary + CRLF);
fs.unlinkSync(location+fname);
}else{
console.log("File doesn't find")
}
}
console.log("new response:" + fname);
}, frameDelay);
});
app.listen(port);
console.log("Server running at port " + port);
トラブルシューティング プロセスを容易にするために、以下はスタンドアロン (サードパーティ ライブラリなし) のテスト ケースです。
まったく同じメモリの問題があります(メモリ使用量が増え続け、最終的にOSによって強制終了されました)。
問題は setInterval () ループにあると考えられます。おそらく、これらの画像は送信後にメモリから削除されていないか、何か (変数 "res" にまだ保存されている可能性があります)。
フィードバックや提案は大歓迎です!
var http = require('http');
var fs = require('fs');
var framedelay = 40;
var port = 3200;
var boundary = 'myboundary';
var CR = '\r';
var LF = '\n';
var CRLF = CR + LF;
function writeHttpHeader(res)
{
res.writeHead(200,
{
'Content-Type': 'multipart/x-mixed-replace;boundary="' + boundary + '"',
'Transfer-Encoding': 'none',
'Connection': 'keep-alive',
'Expires': 'Fri, 01 Jan 1990 00:00:00 GMT',
'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate',
'Pragma': 'no-cache',
});
res.write(CRLF + '--' + boundary + CRLF);
}
function writeJpegFrame(res, filename)
{
fs.readFile('./videos-8081/frames/' + filename, function(err, data)
{
if (err)
{
console.log(err);
}
else
{
res.write('Content-Type:image/jpeg' + CRLF);
res.write('Content-Length:' + data.length + CRLF + CRLF);
res.write(data);
res.write(CRLF + '--' + boundary + CRLF);
console.log('Sent ' + filename);
}
});
}
http.createServer(function(req, res)
{
writeHttpHeader(res)
fs.readdir('./videos-8081/frames', function(err, files)
{
var i = -1;
var sorted_files = files.sort();
setInterval(function()
{
if (++i >= sorted_files.length)
{
i = 0;
}
writeJpegFrame(res, sorted_files[i]);
}, framedelay);
});
}).listen(port);
console.log('Server running at port ' + port);