簡単ネットワークカメラの作り方
はじめに
こちらの記事で、監視カメラアプリLiveCapture3からの映像を複数タイル状に並べて表示するJavaScriptのビューワを作りました。
このビューワは、HTTP GETでJPEG画像を配信するサーバであれば、LiveCapture3ではなくてもライブビューを表示できます。
今回は、このビューワでライブビューを確認できる、簡単ネットワークカメラを作ります。
使用するモジュール
環境は、Ubuntu22.04をベースに記載しますが、WindowsやMacでも同様の構成で作成できます。
使用するモジュールは以下の3つです。
(個々のモジュールの詳細はWeb上にたくさんありますので、ここでは割愛します。)
Video for Linux 2(v4l2)
Linux上でビデオを扱うための統一的なAPI。USB接続されたカメラ(UVC)からの映像を取得します。
v4l2の代わりに、 Windowsの場合はDirectshow、Macの場合はAVFoundationを使用します
ffmpeg
画像や動画を扱うコマンド型式のソフトウェア。USBカメラからの映像をJPEG画像に保存します。
NginX
軽量なWebサーバー。
カメラ映像のJPEG画像をHTTP配信する為に使用します。
処理概要
処理の流れは、
v4l2で、接続したUSBカメラの映像をffmpegに取り込み
ffmpegでカメラ映像をjpegに保存
保存されたjpeg画像をnginxでHTTP配信
という感じです。図に書くとこんな流れになります。
環境構築(Ubuntu)
まずは前述の3つのモジュールをaptでインストールします。
sudo apt upodate
sudo apt install -y nginx ffmpeg v4l-utils
インストール出来たら、systemctl status nginxで、NginXの状態を確認します。
systemctl status nginx
nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service, enabled)
Active: inactive (dead)
ステータスがinactive(dead)の場合は開始させます。
sudo systemctl start nginx
systemctl status nginx
nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service, enabled)
Active: active (running)
ステータスがactive(running)になったら、ウェブブラウザで
http://〇〇.〇〇.〇〇.〇〇
に、実際にアクセスしてみてください。
下記のようなNginXのデフォルトページが表示されればOKです。
次にPCにUSBカメラを接続して、v4l2-ctl --list-devicesでデバイスパスを表示させます
v4l2-ctl --list-devices
HD Webcam eMeet C960: HD Webcam (usb-0000:00:0b.0-1):
/dev/video0
/dev/video1
恐らく、1つのUSBカメラにつき、複数のデバイスパスが表示されると思いますが、その中で若い番号の方を使用します。
上記の例の場合は/dev/video0を使用します。
配信準備
処理としては、ffmpegでNginXの公開ディレクトリにカメラ映像のJPEG画像を保存し続けるだけです。
NginXの公開ディレクトリは/var/www/htmlになりますので、ffmpegを使用して、このディレクトリ直下にcapture.jpgファイルを作成させます。
sudo ffmpeg -f v4l2 -i /dev/video0 \
-r 2 -qscale:v 2 -y \
-f image2 -update 1 /var/www/html/capture.jpg
/var/www/htmlに画像を保存するので、sudoを付けてffmpegを起動します
引数の説明は以下です。
問題なくffmpegが起動すると、秒間2回のペースで、/var/www/html/capture.jpgを更新し続けます。
確認の為、ウェブブラウザでアクセスしてみてください。
http://〇〇.〇〇.〇〇.〇〇/capture.jpg
カメラ映像が表示されればOKです。
(ブラウザでの表示ではJPEG画像は自動更新されません)
ビューワの修正
こちらで紹介したJavaScriptビューワーは、LiveCapture3のJPEG画像配信のパス(/SnapJpeg)にアクセスするようになっているので、ちょっと修正します。
(分かりやすいようにカメラの数は1個に変更しています)
修正ポイントは、ADDRESS_LIST配列に、JPEG画像までのURLを入れている点です。それによって、image.srcに渡すパスもADDRESS_LISTの項目だけになります。
img.src = `${ADDRESS_LIST[pos]}?t=${new Date().getTime()}`;
ちなみに、パスの後ろにつけている ?t=${new Date().getTime()} は、現在時刻のunixtimeをQueryStringとしてURLに追加することでブラウザのキャッシュを効かなくする、昔からある手法です。
このHTMLをliveview.htmlのような名前で保存してダブルクリックでブラウザで表示させれば、USBカメラの映像が表示されます。
さいごに
今回作ったのは、非常に簡易なネットワークカメラですが、JPEG画像だけでもこれだけの動画になります。
サーバ側はJPEG圧縮しかしていないので、非常に低負荷で、ラズパイなどのSingle Board Computerでも問題なく動きますので、色々と試してみてください。
また、興味を持ったら、RTSPなどの動画ストリーム配信にも挑戦してみると面白いと思います!