ラズパイについて色々調べていたら、カメラを使ったライブストリーミング環境を構築している記事を見つけたのでそれをやってみた備忘録です。
ほぼこちらの記事そのままなので、詳しい方法などはそちらを参照してください。
では始めます。
1:Raspberry Piとカメラ
今回自分が使ったRaspberry Piとカメラは以下の通りです。
・Raspberry Pi 4 2GBモデル
Raspberry Pi 4で一番安いモデルです。
・Raspberry Pi カメラモジュール Rev 1.3
リボンケーブルで接続するタイプのRaspberry Pi用のカメラモジュールです。今買うとしたらV2という新しいバージョンのカメラになっていると思いますが、古いこのタイプでもちゃんとカメラとして映るので大丈夫でした。
ちなみにRaspberry Pi用のカメラモジュールを使っていますが、市販されているUSBで接続するタイプのカメラでも大丈夫だと思います。
あとはディスプレイやマウス、キーボードなどを用意します。
2:カメラの確認
まずはカメラがちゃんと認識されているかを確認します。以下のコマンドを実行して接続されているデバイスを確認します。
$ v4l2-ctl --list-device
このコマンドが使えない場合は、以下のコマンドを実行してインストールします。
$ sudo apt-get install v4l-utils
「v4l2-ctl --list-device」を実行すると、以下のように接続されているデバイス一覧が表示されます。
$ v4l2-ctl --list-device bcm2835-codec-decode (platform:bcm2835-codec): /dev/video10 /dev/video11 /dev/video12 mmal service 16.1 (platform:bcm2835-v4l2): /dev/video0
カメラを1台接続している場合は上記の「/dev/video0」がそのカメラのデバイスになっています。この表示がなければラズパイ側でカメラが認識されていないので、もう一度接続を確認してみてください。
3:FFmpeg、Nginxなどのインストール
今回のカメラ映像ライブストリーミングの流れを簡単に言うと「カメラ映像→FFmpegでH.264に変換→RTMPプロトコルでNginxサーバに送る→WebページでHLS形式で配信」という感じになっています。
なのでRaspberry PiにFFmpeg、Nginxをラズパイにインストールする必要があります。
これらをインストールするために、以下のコマンドを実行します。
・パッケージリストの更新
$ sudo apt-get update
・FFmpegのインストール
$ sudo apt-get install ffmpeg
・Nginxのインストール
$ sudo apt-get install nginx
・NginxにRTMPを対応させるモジュールをインストール
$ sudo apt-get install libnginx-mod-rtmp
先にapt-get updateをやっておかないとインストールできない場合があるので、実行しておくのを忘れないようにしてください。
4:HLS配信の設定
必要なもののインストールができたので、次は配信用の設定ファイルを記述していきます。
以下のコマンドを実行してconfファイルをエディタで開きます。
$ sudo nano /etc/nginx/modules-available/rtmp-live.conf
rtmp-live.confファイルの中身は以下のように記述します。各設定項目の詳しい説明はこの公式wikiを参照してください。
・rtmp-live.conf
rtmp { # RTMPでの設定 server { listen 1935; # ポート番号 chunk_size 4096; # チャンクサイズ allow play all; # 許可。play allなので全て再生を許可している。 access_log /var/log/nginx/rtmp_access.log; # アクセスログの保存パス application live { # applicationの後の文字が名称がURLの一部になる。つまりrtmp://<ip address>/liveのようになる。 live on; # ライブ配信を受け取る hls on; # ストリーミング形式をHLSにする record off; # 録画しない hls_path /tmp/live; # 配信用ファイル(.tsファイル)保存先 hls_fragment 1s; # .tsファイルに区切る秒数 } } }
ファイルの記述が終了したら、今度はシンボリックリンクを作成します。こうすることでNginxを起動させる毎に「rtmp-live.conf」ファイルが読み込まれるようになります。
$ cd /etc/nginx/modules-enabled $ sudo ln -s ../modules-available/rtmp-live.conf ./99-rtmp-live.conf
これでHLS配信の設定は完了です。
5:配信ファイルの保存場所をRAMにする
4までの設定でも問題なく配信はできますが、今のままでは配信用の動画ファイルの一時保存先は「/tmp」になっています。つまりはSDカードに保存されるようになっているので、配信をすると配信用動画の一時保存と削除が大量に行われます。これではSDカードの寿命を縮めることにもなってしまうので、ラズパイ本体のメモリー領域であるRAMに保存するように設定します。
まず以下のコマンドでfstabファイルをエディタで開きます。
$ sudo nano /etc/fstab
エディタを開いたら以下の一文を追記します。
tmpfs /tmp tmpfs defaults,noatime,mode=1777 0 0
追記したらファイルを上書き保存します。
ちなみに各項目は以下のようになっています。
1.device:マウントされるパーティション/デバイス。tmpfsはRAMディスク。
2.dir:マウントポイント。/tmpを指定。
3.type:ファイルシステムタイプ。RAMディスクなのでtmpfsを指定。
4.options:マウントオプション。mode=1777はファイル操作を行う設定。
5.dump:dumpでバックアップを取るかどうか。0はバックアップなし。
6.fsck:fsckによるチェックの順番。0はチェックなし。
これで/tmpファイルがRAM上に保存されるようになります。ちなみにラズパイを再起動させると自動的に削除されます。
6:Webページの準備
続いて配信ファイルを表示させるWebページの準備をします。
Webページは「/var/www/html」配置します。「cd /var/www/html」で移動して、そのディレクトリからライブ配信しているHLS動画を参照できるようシンボリックリンクを設定します。
$ cd /var/www/html
$ sudo ln -s /tmp/live live
そして「/var/www/html」ディレクトリ内にindex.htmlファイルを作成します。
$ sudo nano /var/www/html/index.html
HLSを表示させるライブラリはhls.jsなど色々ありますが、今回はVideo.jsというライブラリを使用します。index.htmlファイルの中身は以下のように記述します。
・index.html
<!DOCTYPE html> <html lang="ja"> <head> <title>Streaming Test</title> <!-- このスタイルシートを読み込まないと再生ボタンなどが表示されない --> <link href="https://vjs.zencdn.net/7.6.6/video-js.css" rel="stylesheet" /> </head> <body> <h1>Movie Title</h1> <p>description</p> <video-js id="my-video" controls liveui="true" preload="auto" width="1280" height="720" data-setup="{responsive: true}" > <source src="/live/stream.m3u8" type="application/x-mpegURL" /> <p class="vjs-no-js"> To view this video please enable JavaScript, and consider upgrading to a web browser that <a href="https://videojs.com/html5-video-support/" target="_blank">supports HTML5 video</a> </p> </video-js> <script src="https://vjs.zencdn.net/7.6.6/video.js"></script> </body> </html>
index.htmlを保存すればWebページの準備は完了です。
Webページがちゃんと表示されるかはNginxを起動させてから確認します。
以下のコマンドでNginxを再起動させます。
$ sudo systemctl restart nginx.service
Nginxのプロセスがちゃんと動いているかは「ps aux | grep nginx」コマンドで確認します。
$ ps aux | grep nginx root 3778 0.0 0.0 57776 1324 ? Ss 14:56 0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on; www-data 3779 0.5 0.3 58036 4716 ? S 14:56 0:01 nginx: worker process www-data 3780 0.0 0.1 57916 2844 ? S 14:56 0:00 nginx: worker process www-data 3781 0.0 0.1 57916 2844 ? S 14:56 0:00 nginx: worker process www-data 3782 0.0 0.1 57916 2844 ? S 14:56 0:00 nginx: worker process www-data 3783 0.0 0.1 57908 2908 ? S 14:56 0:00 nginx: cache manager process pi 3870 0.0 0.0 3916 560 pts/1 S+ 15:00 0:00 grep --color=auto nginx
Nginxの起動時にエラーが出たりプロセスが確認できない場合は「/var/log/nginx/error.log」を開いてエラーを確認してみてください。
$ cat /var/log/nginx/error.log
Nginxの起動を確認できたらRaspberry Piのブラウザを開いてURLに「127.0.0.1」と打ち込みます。以下のような画面が表示されればOKです。
ライブ配信をするにはffmpegを使いますが、コマンドが長くなるのでシェルファイルを記述し、そのファイルを実行するようにします。
どこでも良いですが、homeディレクトリ直下に「mystreaming.sh」ファイルを作成します。
$ cd $ nano mystreaming.sh
シェルファイルの内容は以下のように記述して保存します。
・mystreaming.sh
#!/bin/bash if pidof -x ffmpeg > /dev/null; then echo "FFmpeg is already running." exit 1 fi ffmpeg \ -f v4l2 -thread_queue_size 8192 -input_format yuyv422 \ -video_size 1280x720 -framerate 30 \ -i /dev/video0 \ -c:v h264_omx -b:v 768k \ -bufsize 768k -vsync 1 -g 10 \ -f flv rtmp://localhost/live/stream
簡単に説明すると、最初のif文ですでにffmpegが実行されているかを確認します。すでに他で実行されていた場合は何もせずに終了します。ffmpegのライブ配信部分については、1280×720のサイズでフレームレートを30に設定しています。
ここまで準備ができたら以下のコマンドでシェルファイルを実行します。ライブ配信を止めたい場合は「Ctrl+C」で終了させます。
$ sh mystreaming.sh
エラーがなければffmpegのコマンドが実行されるので、その状態でもう一度Raspberry Piのブラウザを開いてURLに「127.0.0.1」と打ち込みます。
再生ボタンが表示されるので、そのボタンをクリックするとカメラ映像のライブ配信が表示されます。ただ10秒ぐらい遅延があるかと思います。
また「ip a」コマンドでRaspberry PiのIPアドレスを確認してそのアドレスにアクセスすることで別のPCなどからでもライブ配信を確認できます。
$ ip a
ちなみにライブ配信中に「/tmp/live/」ディレクトリの中を見てみると、以下のように.tsファイルがどんどん作成されています。この.tsファイルが「rtmp-live.conf」の「hls_fragment 」で設定した秒数で細切れになった動画ファイルとなっています。
$ sudo ls /tmp/live/ stream-339.ts stream-347.ts stream-355.ts stream-363.ts stream-371.ts stream-379.ts stream-387.ts stream-395.ts stream-340.ts stream-348.ts stream-356.ts stream-364.ts stream-372.ts stream-380.ts stream-388.ts stream-396.ts stream-341.ts stream-349.ts stream-357.ts stream-365.ts stream-373.ts stream-381.ts stream-389.ts stream-397.ts stream-342.ts stream-350.ts stream-358.ts stream-366.ts stream-374.ts stream-382.ts stream-390.ts stream-398.ts stream-343.ts stream-351.ts stream-359.ts stream-367.ts stream-375.ts stream-383.ts stream-391.ts stream-399.ts stream-344.ts stream-352.ts stream-360.ts stream-368.ts stream-376.ts stream-384.ts stream-392.ts stream-400.ts stream-345.ts stream-353.ts stream-361.ts stream-369.ts stream-377.ts stream-385.ts stream-393.ts stream-401.ts stream-346.ts stream-354.ts stream-362.ts stream-370.ts stream-378.ts stream-386.ts stream-394.ts stream.m3u8
以上がRaspberry Piでカメラのライブストリーミングをやる方法です。
ほぼ参考資料のページ様の内容と同じですが、割と簡単にできて驚きました。
HLSやVideo.js、ffmpegについては何もわかっていないのでそのあたりも掘り下げて色々カスタマイズできるようになるともっと色々面白いことができそうです。
・参考資料
- Raspberry Pi + USBカメラ のH.264映像をブラウザで見られるようにする - みかんのゆるふわ技術ブログ
- Raspberry Piに接続されているwebカメラの情報をv4l2-ctlで簡単に取得したい | Developers.IO
- nginxについてまとめ(設定編) - Qiita
- ローカル環境で 生放送 をとりあえず試したい - 虎の穴開発室ブログ
- Directives · arut/nginx-rtmp-module Wiki · GitHub
- nginx-rtmp-moduleでお試しLive配信環境を作る - Qiita
- Raspberry Pi 4 Webサーバーを構築する - PCまなぶ
- Raspberry PI(ラズベリーパイ)を楽しもう
- fstab - ArchWiki
- Ubuntu日本語フォーラム / fstabのオプションの意味