MiniDLNA とは
MiniDLNAはその名の通りDLNA/UPnPサーバで、LAN内のクライアントに動画や音声をストリーミングするものです。CIFSやNFSなどのファイル共有でも 動画や音声の再生はできるわけですが、再生のし始めやスキップするときには DLNAのほうが軽い気がします。
MiniDLNAは、先達のDLNAサーバである mediatombよりも設定がシンプルで軽快な動作がウリとのこと。現在はReadyMediaに名前が変わっていますが、Ubuntu 14.04のリポジトリではまだMiniDLNAなので、この記事ではMiniDLNAと呼称します。
Dockerfile を記述する
Ubuntu 14.04において、MiniDLNAはBackportsにいるので今回はppaを使ってインストールします。
- add-apt-repository を使うため software-properties-common をインストール
- add-apt-repository で ppa:djart/minidlna を追加
- MiniDLNA をインストール
という流れです。
FROM ubuntu:14.04
MAINTAINER flny flny@example.com
RUN apt-get install -y \
software-properties-common
RUN add-apt-repository ppa:djart/minidlna -y
RUN apt-get update && apt-get install -y \
minidlna
ADD minidlna.conf /etc/minidlna.conf
ADD start.sh /start.sh
RUN chmod +x /start.sh
EXPOSE 8200
EXPOSE 1900/udp
CMD /start.sh
設定ファイル /etc/minidlna.conf を変更する箇所は多くありません。media_dir にサーバで公開するディレクトリを記述するのと、ポート番号(デフォルト8200)を必要に応じて変更する、friendly_nameでクライアントから見たサーバ名を指定する、くらいでしょうか。
なお、ここで指定したポート番号に加えて、1900/udp も開ける必要があります。
(略)
# If you want to restrict a media_dir to a specific content type, you can
# prepend the directory name with a letter representing the type (A, P or V),
# followed by a comma, as so:
# * "A" for audio (eg. media_dir=A,/var/lib/minidlna/music)
# * "P" for pictures (eg. media_dir=P,/var/lib/minidlna/pictures)
# * "V" for video (eg. media_dir=V,/var/lib/minidlna/videos)
media_dir=V,/mnt/pub/lib/movie
(略)
# Port number for HTTP traffic (descriptions, SOAP, media transfer).
# This option is mandatory (or it must be specified on the command-line using
# "-p").
port=8200
(略)
# Name that the DLNA server presents to clients.
# Defaults to "hostname: username".
friendly_name=minidlna
(略)
起動は普通にserviceコマンドで行います。
#!/bin/bash
service minidlna start
/bin/bash
イメージのビルドとコンテナの作成
buildコマンドでイメージをビルドします。
$ docker build -t minidlna docker/minidlna/
Sending build context to Docker daemon 7.68 kB
Step 1 : FROM ubuntu:14.04
---> e9ae3c220b23
Step 2 : MAINTAINER flny flny@example.com
---> Using cache
---> 768ca4ac1367
Step 3 : RUN apt-get install -y software-properties-common
---> Running in bdc4a354e1de
Reading package lists...
Building dependency tree...
Reading state information...
The following extra packages will be installed:
ca-certificates gir1.2-glib-2.0 iso-codes krb5-locales libasn1-8-heimdal
libcurl3-gnutls libdbus-glib-1-2 libgirepository-1.0-1 libglib2.0-0
libglib2.0-data libgssapi-krb5-2 libgssapi3-heimdal libhcrypto4-heimdal
libheimbase1-heimdal libheimntlm0-heimdal libhx509-5-heimdal libidn11
libk5crypto3 libkeyutils1 libkrb5-26-heimdal libkrb5-3 libkrb5support0
libldap-2.4-2 libroken18-heimdal librtmp0 libsasl2-2 libsasl2-modules
libsasl2-modules-db libwind0-heimdal libxml2 openssl python-apt-common
python3-apt python3-dbus python3-gi python3-pycurl
python3-software-properties sgml-base shared-mime-info unattended-upgrades
xml-core xz-utils
(略)
ご覧の通り、最初のsoftware-properties-commonのインストールで追加パッケージが死ぬほど入るので、一瞬ppa使わないほうがよかったかなと思いましたが このまま進めます。
Step 4 : RUN add-apt-repository ppa:djart/minidlna -y
---> Running in ce05b0ca1683
gpg: keyring `/tmp/tmpa_efmo2i/secring.gpg' created
gpg: keyring `/tmp/tmpa_efmo2i/pubring.gpg' created
gpg: requesting key 8E2B7601 from hkp server keyserver.ubuntu.com
gpg: /tmp/tmpa_efmo2i/trustdb.gpg: trustdb created
gpg: key 8E2B7601: public key "Launchpad PPA for Thanos Kyritsis" imported
gpg: Total number processed: 1
gpg: imported: 1 (RSA: 1)
OK
---> 1a4f7b3aa575
Removing intermediate container ce05b0ca1683
Step 5 : RUN apt-get update && apt-get install -y minidlna
---> Running in affec8556e53
(略)
The following extra packages will be installed:
libavcodec54 libavformat54 libavutil52 libexif12 libflac8 libgsm1 libid3tag0
libjpeg-turbo8 libjpeg8 libmp3lame0 libogg0 libopenjpeg2 libopus0
liborc-0.4-0 libschroedinger-1.0-0 libspeex1 libtheora0 libva1 libvorbis0a
libvorbisenc2 libvpx1 libx264-142 libxvidcore4
Suggested packages:
opus-tools speex
(略)
MiniDLNAも中々の追加っぷりですが、数分待てば終わります。
Removing intermediate container 1cfe8408f5fb
Step 10 : EXPOSE 1900/udp
---> Running in 3aaba6e7e63e
---> 2f59d9cc512e
Removing intermediate container 3aaba6e7e63e
Step 11 : CMD /start.sh
---> Running in cefe9da14814
---> a82bb362f45f
Removing intermediate container cefe9da14814
Successfully built a82bb362f45f
次に runコマンドでコンテナを作成します。-p オプションでポートを開け、-v オプションでホストのディレクトリをコンテナと共有しています。
またこのとき、--netオプションでネットワークモードをhostにする必要があります。デフォルトのbridgeのままだと、DLNAクライアントがサーバを認識できません。
$ docker run -itd --net=host -p 8200:8200 -p 1900:1900/udp -v /mnt/pub:/mnt/pub --name minidlna minidlna
2c8f8edebabcab7e03be9b5f29f7697c2575aaf5ee77c55a9ffbb40328624e70
動作を確認する
netstatで サービスが起動しているか確認します。
$ netstat -na | grep 1900
udp 0 0 0.0.0.0:1900 0.0.0.0:*
$ netstat -na | grep 8200
tcp 0 0 0.0.0.0:8200 0.0.0.0:* LISTEN
起動しているようです。
ブラウザで http://<サーバのIPアドレス>:8200/ を開き、確認することもできます。
Media library の Video files:78は、minidlna.confで指定した/mnt/pub/lib/movie 以下に78個の動画が見つかり、サーバに認識されたことを意味します。
もし--net=hostを付け忘れてコンテナを作成してしまうと、Connected clientsのHW Address(MACアドレス)が全てFF:FF:FF:FF:FF:FFになるので 異常に気付くことができます。このときはコンテナを一旦削除して 作成し直しましょう。
最後にDLNAクライアントで動画を再生してみます。AndroidアプリGinkgoDlnaを使いました。
GinkgoDlnaを起動し、friendly_nameで指定したDLNAサーバ名が表示されれば成功です。
もし表示されない場合、DLNA/UPnPのトラフィックがDLNAクライアントに届いていないということになります。
- コンテナのネットワークモードが host でない
- サーバとクライアントが同一ネットワークにない
- サーバとクライアントの間にある機器(ルータとか)がUPnP、1900/udpを通さない設定になっている
あたりが原因でしょうか。
DLNAサーバ名が表示されたら、サーバ名 -> Video -> All Video とタップすれば、MiniDLNAが認識している動画の一覧が表示されます。さらに動画をタップすると、再生が始まります。
なお、DLNAクライアント自身が再生するか、再生用の別のアプリが呼ばれるかはDLNAクライアントの機能によります。(GinkgoDlnaは後者のタイプ)
以上