ファイルサーバにある動画ファイルを再生する

本年度もよろしくおねがいします。

さて、新年早々冬コミの戦利品を眺めていたところ閃いたというか、単に忘れていただけの「ファイルサーバにある動画ファイルを XBOX360 から再生する」というのをやってみました。

XBOX 360 では同一ネットワーク内に存在する Windows PC にあるメディアファイルを再生することができますが、ウチの環境では各種動画データをクライアント端末ではなく FreeBSD 7.1 にて稼働しているファイルサーバに集約させています。

このため、今回は FreeBSD に格納された動画ファイルを XBOX360 から扱うことができるようにするを目的とします。恐らく Linux でも同じ手法で達成することは可能であると存じますが、手元に Linux BOX が無いので試していません。

まず、前提となる Digital Living Network Alliance(DLNA)というか Universal Plug and Play (UPnP) によるストリーミングを達成するために必要なサーバソフトウェアを選定します。といっても良く分かっていないので適当にググってみました。

色々あって迷いますが、ここは定番の「ports にあるから」との理由で uShare を使ってみました。特に難しい設定は不要ですので簡単に導入できます。

下記に手順を提示します。

まずは ports からインストールします。

PlayStation 3 などの DLNA クライアントを利用する場合では WITH_LIBDLNA を有効にしてください。

# cd /usr/ports/net/ushare/
# make WITH_LIBDLNA=yes install

設定ファイルを編集します。

ここでは下記のみを設定します。

  • USHARE_IFACE バインドするネットワークデバイス名を指定してください。
  • USHARE_DIR 公開したいディレクトリのパスを指定してください。
# cd /usr/local/etc
# cp ushare.conf.sample ushare.conf

# diff  ushare.conf.sample ushare.conf
9c9
< USHARE_IFACE=
---
> USHARE_IFACE=fxp0
21c21
< USHARE_DIR=
---
> USHARE_DIR=/export/media

次に /etc/rc.conf に下記を追記します。

ushare_enable="YES"
ushare_flags="-x -v"

バグがあるため XBOX を認識させるためには ushare.conf ではなく ushare_flags にてコマンドラインオプション "-x" を指定して認識させる必要があります。また "-v" はお馴染みの vervose でログメッセージを出力してくれますので、導入初期はこの出力を確認して挙動を確認します。

そして uShare デーモンを起動してみます。

# /usr/local/etc/rc.d/ushare start
Starting ushare.

ここで XBOX360ダッシュボートから [Xbox360] → [ビデオライブラリー]を選択すると、機器の選択画面にて ushare という項目が表示されます。(ushare の名称はデフォルト名。ushare.conf の USHARE_NAME にて設定可能です)

しかしながら、日本語を含むディレクトリ・ファイルを正しく処理できないようで本来は存在しているファイルが表示されない現象が確認できました。

いつものことなので、ソースを漁ってみます。

# pwd
/usr/ports/net/ushare/work/ushare-1.1a/src
# grep setlocale *
Binary file ushare matches
ushare.c:  setlocale (LC_ALL, "");
Binary file ushare.o matches

ushare.c にて locale を殺しています。iconv を使ってどうにかしてみようとしているらしいですが、ushare のログを見るとどうも上手くいっていないようです。

Jan  1 14:11:36 azusa uShare[96941]: Freeing entry invalid name id=1923 [初音ミク]

よく分からないので、ファイルサーバとして稼働している samba の内部エンコーディングに設定してある EUC-JP をハードコートしてやっつけます。また、最近の Linux ならすべて UTF-8 を前提としているので UTF-8 になるんじゃないかと。

ushare.c の差分はこんな感じです。

# diff ushare.c.org ushare.c
735c735
<   setlocale (LC_ALL, "");
---
>   setlocale (LC_ALL, "ja_JP.eucJP");

ports 用に patch を作ります。これは既存の patch に追記させます。

# cd ../
# diff -c src/ushare.c.org src/ushare.c >> ../../files/patch-ushare

綺麗にしてからビルドして再インストール、デーモンの再起動を行います。

# cd ../
# make distclean
# make deinstall && make reinstall
# /usr/local/etc/rc.d/ushare restart

これで日本語を含む場合でも正しく処理がされます。しかしながら、前述のようにやっつけな方法ですので、誰か iconv を使ったエレガントな方法を教えてください。(今の FreeBSD の iconv は CP932 とかも使えるようになってますし)

また、某動画投稿サイトから動画ファイルを引き抜いて flv 形式から mp4 形式に変換している人への注意点ですが、mp4 形式の動画ファイルについては拡張子を m4v にする必要があります。

これは拡張子が mp4 であるファイルは音声ファイルとして扱われることが原因となっているようです。個人的には拡張子だけでファイル形式を判断するのはどうかと思いますが、オーバーヘッドの関係じゃないかなぁ、と邪推してみる次第です。

また、XBOX360 でサポートされるフォーマットなどについては下記を参照してください。
http://support.microsoft.com/kb/945416/ja