2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Docker + nginxでマルチ配信を構築

Last updated at Posted at 2022-03-15

仕事でマルチ配信の話が出たため、Dockerを用いて一つのライブ出力から複数のRTMPサーバにデータを転送する中継サーバを構築してみました。その際に色々と調べたため備忘録として本記事にまとめます。

背景

そもそものきっかけは

  1. アプリで配信したライブを自社製のライブPlayer以外にYoutubeやFacebookに対して同時配信したい
  2. 複数配信先はCMSなどで自由に指定できるようにしたい
  3. RTMPの出力はアプリからで一つに制限されているため、RTMPを複数の配信先に中継するサーバが必要
  4. そもそもそれは可能なの??

から始まり、勉強がてらdockerを用いてローカルに中継サーバを構築してみることにしました。

成果物・構成

成果物は以下の通りです。

◆ソースコード

◆構成

stream server にRTMPを渡すために ffmpeg を使用する構成になっています。

Dockerfile

FROM ubuntu:20.04

RUN apt update
RUN apt upgrade -y
RUN apt auto-remove -y

RUN apt install -y language-pack-ja
RUN update-locale LANG=ja_JP.UTF8

RUN apt install -y build-essential libpcre3 libpcre3-dev libssl-dev libz-dev zlib1g-dev unzip git curl wget vim
WORKDIR /usr/local/src/
RUN curl -LO http://nginx.org/download/nginx-1.20.0.tar.gz
RUN curl -LO https://github.com/arut/nginx-rtmp-module/archive/afd350e0d8b7820d7d2cfc3fa748217153265ce6.tar.gz
RUN tar xvzf nginx-1.20.0.tar.gz
RUN tar xvzf afd350e0d8b7820d7d2cfc3fa748217153265ce6.tar.gz
WORKDIR /usr/local/src/nginx-1.20.0
RUN ./configure --with-http_ssl_module --add-module=../nginx-rtmp-module-afd350e0d8b7820d7d2cfc3fa748217153265ce6 --with-debug
RUN make
RUN make install
COPY conf/nginx.conf /usr/local/nginx/conf/nginx.conf
COPY conf/nginx_single.conf /usr/local/nginx/conf/nginx_single.conf
WORKDIR /var/local/www/hls
RUN chmod 777 /var/local/www/hls

# ffmpeg install
WORKDIR /usr/local/src/
RUN wget https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz \
      && tar Jxvf ffmpeg-release-amd64-static.tar.xz \
      && cp ffmpeg-*-amd64-static/ffmpeg /usr/bin/

WORKDIR /var/local/www/hls

マルチ配信の仕組み

RTMPの通信はnginxの nginx-rtmp-module を用いています。Dockerfile のnginxとnginx-rtmp-moduleのインストールしてる箇所は以下の通りです。

RUN apt install -y build-essential libpcre3 libpcre3-dev libssl-dev libz-dev zlib1g-dev unzip git curl wget vim
WORKDIR /usr/local/src/
RUN curl -LO http://nginx.org/download/nginx-1.20.0.tar.gz
RUN curl -LO https://github.com/arut/nginx-rtmp-module/archive/afd350e0d8b7820d7d2cfc3fa748217153265ce6.tar.gz
RUN tar xvzf nginx-1.20.0.tar.gz
RUN tar xvzf afd350e0d8b7820d7d2cfc3fa748217153265ce6.tar.gz
WORKDIR /usr/local/src/nginx-1.20.0
RUN ./configure --with-http_ssl_module --add-module=../nginx-rtmp-module-afd350e0d8b7820d7d2cfc3fa748217153265ce6 --with-debug
RUN make
RUN make install

RTMPを受信し、複数のRTMPサーバへ転送するための設定ファイルは以下の通りです。

# ~~~省略~~~~

rtmp {
    server {
        # ~~~省略~~~~

        application live {
            # ~~~省略~~~~

            allow publish all;          # RTMP push 許可
            allow play 127.0.0.1;       # RTMP pull 有効(ffmpegに対して)

            # 変換コマンド
            exec ffmpeg -re -i rtmp://localhost/${app}/${name} -codec:v libx264 -g 3 -f flv rtmp://localhost/stream1/${name};
            exec ffmpeg -re -i rtmp://localhost/${app}/${name} -codec:v libx264 -g 3 -f flv rtmp://localhost/stream2/${name};
        }

        # ~~~省略~~~~
    }
}

http {
    # ~~~省略~~~
}

処理の順番は以下の通りです。

  • allow play 127.0.0.1; で受信したRTMPを再度localhostに転送
  • localhostに転送したものを2プロセスのffmpegを用いてそれぞれのストリームサーバ rtmp://localhost/streamN/${name}; に転送
    • exec ffmpeg -re -i rtmp://localhost/${app}/${name} -codec:v libx264 -g 3 -f flv rtmp://localhost/stream1/${name};
    • exec ffmpeg -re -i rtmp://localhost/${app}/${name} -codec:v libx264 -g 3 -f flv rtmp://localhost/stream2/${name};

感想

勉強目的で作ってみましたが、大部分は nginxffmpeg の機能を用いて実現しているためコーディングはせずに構築することができました。
今回の成果物では配信先は同じコンテナ内のRTMPサーバに対してですが、ffmpeg コマンドを書き換えることでYoutubeやFacebookに対して配信することは可能です。

勉強後に後から知ったのですがAWS Elemental MediaLiveでRTMP出力が可能であることが判明しました。実サービスでマルチ配信を実現する際は負荷などを考慮すると素直にAWSに頼るのが良さそうです。

参考サイト

2
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?