Node.jsとExpressを使ったRTSPストリーミング再生方法
本記事では、Node.jsとExpressを使用して、WebアプリケーションでRTSPストリーミングを再生する方法を紹介します。
RTSPストリーミングを再生するライブラリには、rtsp-relayを使います。
バージョン
- express - 4.18.1
- rtsp-relay - 1.6.1
インストール
npm install rtsp-relay
RTSP再生のサンプル
サーバサイド
app.ws()
でクライアント側の接続先を指定し、その中で実際のRTSPのURLを指定します。
今回はクライアントから指定されたカメラ(IPアドレス指定)に接続するサンプルです。固定のカメラであればパラメータは不要です。
"use strict";
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'public')));
const { proxy } = require('rtsp-relay')(app);
app.ws('/api/stream/:cameraIP', (ws, req) => {
proxy({
url: `rtsp://${req.params.cameraIP}:8900/live0`,
})(ws);
});
let webServer = app.listen(8080, () => {
console.log('server start.');
});
クライアント
まず、\node_modules\rtsp-relay\browser\index.jsをクライアントが見える位置にコピーします。 今回はファイル名も変更し、\public\js\rtsp-relay-index.jsとして保存しました。
loadPlayer()
メソッドでサーバ側のアドレスと描画先のcanvasエレメントを指定するとストリーミング再生が始まります。
rtsp-relayだけでは、一時停止などができないため、今回はjsmpegのplayerインスタンスを取得し、一時停止などに対応させます。それらの処理をまとめてRtspPlayクラス
としました。
画面表示中に再生を止めない場合は、playerインスタンスの保持などは不要です。
画面側のHTMLファイルです。
id="cameraCanvas"
がストリーミングを再生するcanvasエレメントです。
<!doctype html>
<html lang="ja">
<head>
<meta charset="charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RTSP Sample</title>
<link rel="stylesheet" href="/css/style.css">
</head>
<body onload="loadPage();">
<div class="container-fluid">
<div class="container-fluid bg-black d-flex align-items-center justify-content-center mb-3" style="height: 54vh;">
<canvas id="cameraCanvas"></canvas>
</div>
<div class="btn-group">
<button type="button" onclick="play();" class="btn btn-primary">再生</button>
<button type="button" onclick="pause();" class="btn btn-primary">一時停止</button>
<button type="button" onclick="stop();" class="btn btn-primary">停止</button>
<button type="button" onclick="destroy();" class="btn btn-primary">destroy</button>
</div>
</div>
<script type="module" src="/js/bootstrap.bundle.min.js"></script>
<script src="/js/rtsp-relay-index.js"></script>
<script src="/js/rtsp-play.js"></script>
<script>
const _camera = new RtspPlay('192.168.0.10', 'cameraCanvas');
function calcVideoSize(maxWidth, maxHeight) {
// 16:9
const sizes = [
{ width: 1920, height: 1080 },
{ width: 1280, height: 720 },
{ width: 960, height: 540 },
{ width: 800, height: 450 },
{ width: 640, height: 360 },
{ width: 480, height: 270 },
{ width: 320, height: 180 },
];
// 最低サイズを設定しておく.
let width = sizes[sizes.length - 1].width;
let height = sizes[sizes.length - 1].height;
for (let size of sizes) {
if (size.width <= maxWidth && size.height <= maxHeight) {
width = size.width;
height = size.height;
break;
}
}
return { width, height };
}
function loadPage() {
// set canvas size.
let { width, height } = calcVideoSize(document.body.clientWidth * 0.9, window.innerHeight * 0.5);
//console.log('video size', width, height);
let canvas = document.getElementById('cameraCanvas');
canvas.style.width = `${width}px`;
canvas.style.height = `${height}px`;
}
async function play() {
await _camera.play().catch((error) => { alert(error); });
}
function pause() {
_camera.pause();
}
function stop() {
_camera.stop();
}
function destroy() {
_camera.destroy();
}
</script>
</body>
実行
次のアドレスにアクセスすると、カメラIPで指定したカメラのRTSPストリームを再生します。
http://<ホスト>:8080/player.html
非インターネット環境でエラー発生時
インターネット接続されておらず、キャッシュにjsmpeg.min.jsが残っていない場合、次のようなエラーが発生します。
解決方法
jsmpeg.min.jsをローカルで保持することで、このエラーを解消できます。
- jsmpegのサイトから、DOWNLOAD>jsmpeg.min.jsをたどり、ファイルをダウンロードする
- ダウンロードしたファイルをクライアントが見える位置に配置する
本手順ではpublic\js\jsmpeg.min.jsに保存 - ダウンロードしたファイルをスクリプトタグでrtsp-relay-index.jsの前に読み込む
<script src="/js/jsmpeg.min.js"></script> <script src="/js/rtsp-relay-index.js"></script>