NginxでMP4のモジュールを有効にする

September 19, 2021

TL;DR alpine linuxを使えば解決。

最近はRailsで簡易的な動画ファイルをセルフホスティングできるアプリケーションを作っています。 有名所ではPlexや、最近はJellyfinなどのようなアプリケーションもあります。 これらはiOSやAndroid向けや、ChromecaseやFireTVなどのクライアントにも対応していたりするのですが、動画を観るだけならブラウザで十分です。 しかし自宅で動画をホスティングしようとすると、数百MBや数GBはあるファイルを一度にダウンロードしようとするので動画ファイルをシークすることはできません。

そこで最初は動画をストリーミング再生する方法を調べようとしていて、NginxにはRTMPというモジュールが存在しているようです。 このページにも記されているようにDebianやAlpineでもコマンドでインストールすることができるようです。 あとは/etc/nginx/modules-enabled50-mod-rtmp.confというファイルが作成されるのでこのモジュールを使うことができるようになるわけ。 RTMPはストリーミング配信するときに必要なもので今回の要件とはあまり関係ないようでした。

https://gist.github.com/CSRaghunandan/ce2394cd5a9c8a412f8ff5ee1478560a#file-nginx-conf-L106

たまたま似たようにNginx単体でMP4を配信できそうなnginx.confのGistが見つかりました。 このファイルをそのまま使おうとすると:

nginx: [emerg] unknown directive "mp4" in /etc/nginx/nginx.conf:32

mp4というディレクティブは存在しないとのこと。

https://nginx.org/en/docs/http/ngx_http_mp4_module.html

Nginxのドキュメントを探すとngx_http_mp4_moduleというモジュールが存在しているようで、これを使うと上記の設定ファイルが動くようになるようです。 Nginxが使用できるモジュール一覧を調べるときのコマンドはnginx -Vです。

FROM debian:stable
RUN apt-get update && \
    apt-get install nginx libnginx-mod-rtmp -y

これを最初試そうとしていたときDebianのDockerfileで、コマンドの結果が以下のとおり。

nginx -V | tr ' ' '\n' | grep mp4

出力結果は出ないため当然mp4というディレクティブは使えません。

Nginx : Add/Enable mp4 module

上記のSOでの回答によるとnginx-extrasのパッケージをインストールすれば良いとのことでした。 余談ですが、昔からNginxのチュートリアルを見るとnginx-extrasをインストールするものが多かったのですが、最初から使えるモジュールが多かったんですね。

nginx -V | tr ' ' '\n' | grep mp4
--with-http_mp4_module

今度は使えるようになりました。 先程のGistを若干書き換えて試してみたところ、iPhoneのブラウザでも1GB以上はあるビデオファイルを閲覧できるようになりました。 といってもこれはもともとDebianのベースイメージなので、理想はNginxのDockerfileで使いたいところです。 そう思ってNginxのコンテナイメージを指定してみたところ:

docker run -it nginx:alpine nginx -V | tr ' ' '\n' | grep mp4
--with-http_mp4_module

ということでNginxのコンテナイメージはあらかじめMP4形式を指定できるようでした。 普段Railsを使っているだけだと意外と見過ごしがちなのですが、Nginxも結構奥が深いものだなと思った一日でした。


Profile picture

Personal blog by Seiichi Yonezawa.