nginx-rtmp-module + FFmpeg + HLSで動画配信ができるdocker-composeをつくった
タイトルのdocker-composeをつくっていきます。ローカルで配信確認したいときにシュッと起動できるようにします。
次のような構成でつくりました。
コンテナ構成
RTMP server
- nginx-rtmp-moduleをつかってRTMP serverをたてる。
- RTMP serverは`rtmp context`でストリームを受け取るapplicationを追加(`application encoder`)。
- `application encoder`はストリームを受け取るとFFmpegで動画を3つのビットレードにエンコードする。
- `application encoder`でエンコードした動画をHLS変換する`application hls`へストリームする。
- `application hls`は変換したm3u8、tsファイルを`/data/hls`に配置する。
- `/data/hls`はホストで同期されていてStreaming serverからもm3u8、tsファイルを参照できるようにしている。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
rtmp {
server {
listen 1935;
application encoder {
live on;
exec ffmpeg -i rtmp://localhost:1935/$app/$name
-c:a aac -strict -2 -b:a 32k -c:v libx264 -x264opts bitrate=128:vbv-maxrate=128:vbv-bufsize=128 -rtbufsize 100M -bufsize 256k -preset veryfast -f flv rtmp://localhost:1935/hls/${name}_low
-c:a aac -strict -2 -b:a 64k -c:v libx264 -x264opts bitrate=256:vbv-maxrate=256:vbv-bufsize=256 -rtbufsize 100M -bufsize 512k -preset veryfast -f flv rtmp://localhost:1935/hls/${name}_mid
-c:a aac -strict -2 -b:a 128k -c:v libx264 -x264opts bitrate=512:vbv-maxrate=512:vbv-bufsize=512 -rtbufsize 100M -bufsize 1024k -preset veryfast -f flv rtmp://localhost:1935/hls/${name}_high;
}
application hls {
live on;
hls on;
hls_path /data/hls;
hls_nested on;
hls_fragment 2s;
hls_variant _low BANDWIDTH=160000;
hls_variant _mid BANDWIDTH=320000;
hls_variant _high BANDWIDTH=640000;
}
}
}
|
Broadcast server
- mp4ファイルをFFmpegを使いループ再生させRTMP serverへストリームしている。
- Broadcast serverはコンテナの1つのためlocalhostではRTMP serverに接続できない。
- 次のように環境変数を参照するようにしている。
1
|
ffmpeg -re -stream_loop -1 -i '/data/broadcast_source.mp4' -f flv "${RTMP_SERVER_URL}/${STREAM_NAME}"
|
- docker-composeで環境変数 'RTMP_SERVER_URL'と'STREAM_NAME'を定義している。
Streaming server
- NginxでHTTP serverをたてる。
- typesに'm3u8'と'ts'を追加している。
- rootを'/data'としてRTMP serverと同期しているm3u8とtsファイルにアクセスしている。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
server {
listen 80;
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /data;
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
}
}
}
|
docker-compose
ホストとコンテナでファイルを同期しているのでdindを使いホストもコンテナ化しています。
ホスト側のdocker-compose
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
version: "3"
services:
dind_streaming_host:
container_name: streaming_host
image: docker:1.13.0-dind
privileged: true
ports:
- 5301:2375
- 1935:1935
- 80:80
- 5000:5000
volumes:
- ./video/clouds_over_the_mountain_hd_stock_video.mp4.mp4:/var/container/data/broadcast_source.mp4
|
コンテナに必要なポートとBroadcast server
から配信する動画をコンテナに同期しています。
コンテナ群のdocker-compose
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
version: "3"
services:
rtmp:
container_name: rtmp_server
build: ./container/nginx_rtmp
ports:
- 1935:1935
volumes:
- /var/container/data:/data
- /var/container/log/rtmp/nginx/:/var/log/nginx
stream:
container_name: stream_server
build: ./container/nginx_stream
ports:
- 80:80
volumes:
- /var/container/data:/data
- /var/container/log/stream/nginx/:/var/log/nginx
broadcast:
container_name: broadcast_server
build: ./container/ffmpeg_broadcast
depends_on:
- rtmp
environment:
RTMP_SERVER_URL: "rtmp://rtmp:1935/encoder"
STREAM_NAME: broadcast
volumes:
- /var/container/data/:/data
|
起動方法と動画配信方法
ホストとコンテナでファイルを同期しているのでdindを使いホストもコンテナ化しているので起動にはdindとdirenvが必要です。
docker-composeの起動方法
まずはホスト側の起動から。
もしdindのイメージがなければプルします。
1
|
docker pull docker:1.13.0-dind
|
ホスト側を起動します。
1
2
|
$ cd (path-to 'streaming-host-sample')
$ docker-compose up -d
|
続いてコンテナ群をまとめているdocker-composeを起動します。
1
2
3
4
|
$ cd (path-to 'streaming_host')
direnv: loading .envrc
direnv: export +DOCKER_HOST
$ docker-compose up -d
|
※ ‘streaming_host’ディレクトではdirenvによってディレクトリでは環境変数DOCKER_HOST
が先に起動したdockerのホストに切り替わっています。これですべてのコンテナが起動できました。
動画の確認方法
コンテナが起動できたらsafariで<a href="http://localhost/hls/broadcast.m3u8">http://localhost/hls/broadcast.m3u8</a>
にアクセスするとBroadcast server
から配信している動画を再生できます。
今回はプレイヤーを用意せずsafariで直接m3u8を参照しています。
サンプルの動画はDISTILLからDLしました。Distill: Free HD Stock Video & HD Video Clips
ライブ配信方法
wirecastなどの配信ツールを使うことでライブ配信ができます。Live Webcasting Software | Telestream Wirecast | Overview出力先のRTMPサーバに’rtmp://localhost:1935/encoder’を指定します。
ストリームを’live’として配信した場合はhttp://localhost/hls/live.m3u8にアクセスするとライブ配信した動画を確認できます。
まとめ
- nginx-rtmp-moduleを使ったRTMPサーバのたて方が理解できた。有償なツールもあるがローカルでシュッと構築して確認するくらいなら今回の構成でもできる。
- ほとんど素の使い方なので低遅延に対する取り組みやm3u8,tsファイルの同期方法など現場では様々な工夫がされている。
- FFmpegのエンコードオプション周りはこれだけで新しいエントリが書けそうなくらいインプットがありそうな領域と感じた。今回は次のブログを参考にエンコード部分を参照させていただいた。
- Nginx rtmp配信 ffmpegを利用したマルチビットレート化成功 | パソコン王者 - 楽天ブログ
ソースを公開しています