【Raspberry Pi】GStreamerでHLS配信ライブストリーミング
この記事では、Raspberry Pi(ラズパイ)に取り付けたカメラで撮影した映像を、リアルタイムで外部のブラウザから確認できるようなストリーミングサーバーの構築を行っていく。
具体的には、GStreamerを使ってRaspberry PiからHTTP Live Streaming(HLS)で配信できるようにする。配信といってもYouTube Liveやニコ生配信ではなく、あくまでもローカルエリア内でのストリーミングとなる。なお、Raspberry Piでカメラを使えるようにするまでの設定は済んでいるものとして、この記事では説明を省略する。
カメラモジュールの設定方法はこちらの記事を参考に。
ニコ生などへ配信したい場合はこちら。
はじめに
ラズパイ用のカメラモジュールをご紹介します。用途によってはケースに入った製品の方が使い勝手が良いです。また、ズーム機能付だったり、赤外線で夜間も撮影できるカメラモジュールもあります。
動画など重い処理をRaspberry Piで行う場合、CPUが発熱して本体が壊れる恐れがあります。ヒートシンクや放熱性のあるケースに入れて必ず熱対策をしましょう。 過去にRaspberry Piを壊してしまったことがある。
Raspberry Piで作るのが大変な方は、ネットワークカメラをご検討なさってもよいでしょう。
Raspberry Piの準備
はじめに重要なお知らせ。実は、GStreamerでライブストリーミングをやってみたところ、AndroidのChromeからのみでしか動画再生できなかった。MacのVLCアプリを使えば動画の再生ができたが、その辺りを踏まえた上で先を読み進めていって欲しい。
今回やった動画再生の結果。
OS | ブラウザ | 再生可否 |
---|---|---|
Mac | Safari | 否 |
Mac | Chrome | 否 |
iOS | Safari | 否 |
iOS | Safari | 否 |
Android | Chrome | 可 |
FFmpegを使った変換だともう少しましな結果になったので、よかたら参考にして欲しい。 FFmpegバージョンはこちら
HLSのブラウザ対応状況
HLSのブラウザ対応状況を調べてみると、MacのChromeではHLS再生にデフォルト対応していないことがわかった。
Can I use... Support tables for HTML5, CSS3, etc
環境
項目 | バージョン |
---|---|
ラズパイ | Raspberry Pi3 Model B+ |
カメラモジュール | OV5647 |
OS | Raspbian 9.13 |
Python | 2.7.13/3.7.0 |
パッケージを更新
次へ進む前に、Raspberry Piを最新状態にしておくことをおすすめする。ただし$ sudo apt updateはOSもアップデートするため、時間がかかるが気長に待とう。
$ sudo apt update
$ sudo apt upgrade
カメラモジュールを/dev/video0として認識させる
まず、カメラモジュール(OV5647)を /dev/video0 として認識させておく必要がある。
$ v4l2-ctl --list-devices
Failed to open /dev/video0: No such file or directory
上のエラーが出ないようにするためには、 $ sudo vi /etc/modules を実行し、次の一行を追記して、Raspberry Piを再起動しておく。
bcm2835-v4l2
再び $ v4l2-ctl --list-devices を実行すると、次のように表示されカメラモジュールが/dev/video0 にマウントされていることがわかる。
bcm2835-codec (platform:bcm2835-codec):
/dev/video10
/dev/video11
/dev/video12
mmal service 16.1 (platform:bcm2835-v4l2):
/dev/video0
GStreamerを使えるようにする
GStreamerのインストール
次の2つのコマンドを順番に実行して、GSrtreamerをRaspberry Piへインストールする。もしもインストールできなかった場合は、前に戻ってRaspberry Piを最新状態にしてからやるとうまくいく。
$ sudo apt install autoconf automake libtool
$ sudo apt install gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-plugins-bad
GStreamerの動作確認
適当なディレクトリを作って移動し、下記コマンドを実行して、.m3u8 と .ts ファイルを作成してみよう。
$ sudo gst-launch-1.0 -v -e v4l2src device=/dev/video0 \
! video/x-h264,width=640,height=480,framerate=15/1 \
! h264parse ! mpegtsmux \
! hlssink max-files=8 target-duration=5 \
location=./segment%05d.ts \
playlist-location=stream.m3u8 \
playlist-root=./
しばらくしてから ctrl + c でシェルを終了する。設定がうまくできていれば、次のように.m3u8 と .ts ファイルが作成されるはず。ただし動画をh264に変換するときは、ソフトウェアエンコードでやっている。
$ ls
stream.m3u8 segment00000.ts segment00001.ts
「.m3u8」と「.ts」ファイルの内容
.m3u8ファイルは、.tsファイルのパスを記述しておくテキストファイルだ。$ cat output.m3u8
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-ALLOW-CACHE:NO
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-TARGETDURATION:9
#EXTINF:8.6319570541381836,
./segment00000.ts
#EXTINF:6.2347087860107422,
./segment00001.ts
そして.tsファイルは、トランスポートストリームファイルと呼び、映像や音声データが含まれているファイルだ。これらのファイルを順番にクライアントマシンへ送ることでHLSを実現している。
HLSでストリーミングサーバー
PythonでWebサーバーを立ち上げる
Pythonなら簡単にWebサーバーが作れる。次のプログラムで、外部からwwwディレクトリへアクセスできるようにした。プログラムをPython3で実行すると、パソコンなどのブラウザから http://<Raspberry PiのIPアドレス>:5555 へアクセスできるようになる。
from http.server import HTTPServer, SimpleHTTPRequestHandler
import os
import ipget # $ sudo pip3 install ipget==0.0.3
os.chdir("./www")
a = ipget.ipget()
ip, bit = a.ipaddr("eth0").split('/')
port = 5555
httpd = HTTPServer(('', port), SimpleHTTPRequestHandler)
print('HTTPServer began -> http://{}:{}'.format(ip, port))
httpd.serve_forever()
「.m3u8」と「.ts」ファイルの作成
ストリーミングサーバーの構築といっても基本は「.m3u8」と「.ts」ファイルを作れば良いだけ。www ディレクトリへ移動し、stream ディレクトリを作成し、次のコマンドを実行して動画ファイルを作成した。
$ sudo gst-launch-1.0 -v -e v4l2src device=/dev/video0 \
! video/x-h264,width=640,height=480 \
! h264parse ! mpegtsmux \
! hlssink max-files=8 target-duration=5 \
location=/home/pi/Streaming/www/stream/segment%05d.ts \
playlist-location=/home/pi/Streaming/www/stream.m3u8 \
playlist-root=http://192.168.100.103:5555/stream/
階層はこんな感じ。
$ pwd
/home/pi/Streaming
$ tree
.
|-- server.py
`-- www
|-- item_apps.html
|-- stream
| |-- segment00009.ts
| |-- segment00010.ts
| |-- segment00011.ts
| |-- segment00012.ts
| |-- segment00013.ts
| |-- segment00014.ts
| |-- segment00015.ts
| `-- segment00016.ts
`-- stream.m3u8
HTML5のVideoタグでHTSを再生
作成した「.m3u8」と「.ts」ファイルを再生するには、HTML5のVideoタグを使えば良い。次のhtmlを作成して、ブラウザからRaspberry Piへアクセスしてみよう。ただし、最初にも述べた通り、残念ながらAndroid以外のブラウザからは動画の再生ができなかった。
<!DOCTYPE html>
<html lang="ja">
<head>
<title>HTTP Live Streaming Test</title>
</head>
<body>
<h1>HTTP Live Streaming Test</h1>
<video width="640"
height="360"
src="stream.m3u8"
preload="none"
onclick="this.play()"
controls />
</body>
</html>
FFmpegバージョンも参考に。