nginx-rtmp-module + FFmpeg + HLSで動画配信ができるdocker-composeをつくった


タイトルのdocker-composeをつくっていきます。ローカルで配信確認したいときにシュッと起動できるようにします。
次のような構成でつくりました。

コンテナ構成

RTMP server

 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

1
ffmpeg -re -stream_loop -1 -i '/data/broadcast_source.mp4' -f flv "${RTMP_SERVER_URL}/${STREAM_NAME}"

Streaming server

 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にアクセスするとライブ配信した動画を確認できます。

まとめ

ソースを公開しています