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だけでは、一時停止などができないため、今回はjsmpegplayerインスタンスを取得し、一時停止などに対応させます。それらの処理をまとめてRtspPlayクラスとしました。
画面表示中に再生を止めない場合は、playerインスタンスの保持などは不要です。

画面側のHTMLファイルです。
id="cameraCanvas"がストリーミングを再生するcanvasエレメントです。

public\player.html
<!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が残っていない場合、次のようなエラーが発生します。

GET https://cdn.jsdelivr.net/gh/phoboslab/jsmpeg@b5799bf/jsmpeg.min.js net::ERR_NAME_NOT_RESOLVED

解決方法

jsmpeg.min.jsをローカルで保持することで、このエラーを解消できます。

  1. jsmpegのサイトから、DOWNLOAD>jsmpeg.min.jsをたどり、ファイルをダウンロードする
  2. ダウンロードしたファイルをクライアントが見える位置に配置する
    本手順ではpublic\js\jsmpeg.min.jsに保存
  3. ダウンロードしたファイルをスクリプトタグでrtsp-relay-index.jsの前に読み込む
    <script src="/js/jsmpeg.min.js"></script>
    <script src="/js/rtsp-relay-index.js"></script>
    
このエントリーをはてなブックマークに追加
にほんブログ村 IT技術ブログへ

コメント

メールアドレスが公開されることはありません。 が付いている欄は必須項目です