📝

MJPG-streamerのストリーミング映像をvideoタグに描画する

2020/11/23に公開

はじめに

MJPG-streamerのストリーミング映像をvideoタグに描画する仕組みとスクリプトを紹介します。実行環境やスクリプトは、個人開発のコンテンツウソ穴に必要だったので調査しました。

実行画面

MJPG-streamerのストリーミング映像をcanvasタグ,videoタグで描画しています。
向かって左がcanvasタグで、右がvideoタグです。

仕組み

カメラ付きのラズパイに、NginxとMJPG-streamerをインストールしました。

処理は大きく分けて2つあります
(1)MJPG-streamerからスナップショットを取得しcanvasタグに描画
(2)canvasタグの映像をvideoタグに描画

本筋ではありませんが、自己証明書を使いSSL通信にしています。

動作結果

全ての環境で動かないのが残念、特にiPhoneで動いてほしい(対策案ある方、是非コメント欄で教えてください!)

デバイス OS ブラウザ 動作結果
Surface Window10 Chrome(バージョン 87.0.4280.66) OK
Surface Window10 FireFox(バージョン 83.0) NG
Surface Window10 Edge(バージョン 87.0.664.41) OK
iPhone iOS14.2 Safari NG
Android Android9 Chrome OK

※検証日:2020/11/23

ソース

ソースはこちら、https://{{ラズパイIP}}/webcam1/?action=snapshotMJPG-streamerでスナップショットを取得するURLを指定します。

/var/www/canvastovideo.html
<!DOCTYPE html>
<html>
<head>
    <title>MJPG-streamer -> CANVAS-TAG -> VIDEO-TAG</title>
</head>
<body>
<table width="100%">
  <tr>
    <td>
      <B>MJPG-streamer -> CANVAS-TAG</B><br/><canvas id="canvas" width="400px" height="400px"></canvas>
    </td>
    <td>
      <B>CANVAS-TAG -> VIDEO-TAG</B><br /><video id="player-canvas" autoplay loop muted poster="" playsinline width="400px" height="400px"></video>
    </td>
  </tr>
</table>

<script>
let canvasStream = null;

//(1)MJPG-streamerからスナップショットを取得しcanvasタグに描画
function drawCanvasFromMjpegStrmer(){ //MJPG-streamer -> CANVAS-TAG
  const canvas = document.querySelector("canvas");
  const ctx = canvas.getContext("2d");
  setInterval(() => {
      if (canvas && ctx){
            const chara = new Image();
            chara.src = "https://{{ラズパイIP}}/webcam1/?action=snapshot";
            chara.onload = () => {
              ctx.drawImage(chara, 0, 0);
            };
      }
  }, 10000/60);
}

//(2)canvasタグの映像をvideoタグに描画
function drawVideoFromCanvas() { // CANVAS-TAG -> VIDEO-TAG
  const canvas = document.getElementById("canvas");
  const video  = document.getElementById("player-canvas");
  const ctx    = canvas.getContext('2d');

  ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
  canvasStream = canvas.captureStream(30);
  video.srcObject = canvasStream;
}

drawCanvasFromMjpegStrmer(); // MJPG-streamer -> CANVAS-TAG
drawVideoFromCanvas();       // CANVAS-TAG -> VIDEO-TAG
</script>
</body>

Nginxの設定

/etc/nginx/sites-available/serversの設定はこちら。

  • 概要
    • 自己証明書(server.crt,server.key)を設定しSSL通信
    • http://localhost:8090/はMJPG-streamerのURL
      • URLhttps://localhost:8090/webcam1/?action=snapshotでスナップショットとれる
    • /var/wwwをルートに設定
      • /var/www/canvastovideo.htmlは、https://xxxxxxx/canvastovideo.htmlでアクセスできる
$ cat /etc/nginx/sites-available/servers
server {
    listen       443  default ssl;
    ssl on;
    ssl_certificate     /etc/nginx/conf.d/server.crt;
    ssl_certificate_key /etc/nginx/conf.d/server.key;
    root /var/www;
    index index.html index.html index.php;
    server_name localhost;
    location / {
          try_files $uri $uri/ /index.html;
    }
    location /webcam1/ {
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header Host $http_host;
          proxy_redirect off;
          proxy_pass http://localhost:8090/;
    }
}

※上記設定と連動したMJPG-streamerの実行コマンド

$ /usr/local/bin/mjpg_streamer -i "input_raspicam.so -x 400 -y 400 -fps 15 -q 80" -o "output_http.so -p 8090 -w /usr/local/share/mjpg-streamer/www"

※自己証明書の作成コマンド

$ openssl genrsa 2048 > server.key
$ openssl req -new -key server.key > server.csr
$ openssl x509 -days 3650 -req -signkey server.key < server.csr > server.crt

設定を反映するためNginxを再起動

$ sudo /etc/init.d/nginx restart

参考にしたサイト

Discussion