以前、Darwin Streaming Serverを使って動画ファイルをソーシャルビューイングする話を書きましたが、この方式(RTSP)だとiOS端末から視聴できないので、HTTP Live Streamingに挑戦してみました。
HTTP Live StreamingはAppleが推進しているストリーミング配信方式で、近年デ・ファクトになりつつあるようです。主立った特徴として、
- Apacheなど通常のWebサーバーにファイルを置けば配信できる
- クライアントの通信帯域に合わせて、複数用意したビットレートのファイルを自動的に使い分けてくれる
- HTML5のvideoタグを使ってHTMLページ内でインライン再生できる(iPhoneは全画面強制)
等があります。いつもソーシャルビューイングする面子にiPadしか通信端末がない人がいて動画視聴とチャットが同時にできなくて困ってたんですが、HTMLページに動画に加えインラインフレームでチャットサイトを呼び出すことで、1画面内で再生とチャットが同時に実現しました。更にAppleTV等AirPlayクライアントがある環境なら動画再生をそちらに飛ばし、iPad側はチャットに徹するという、疑似バックグラウンド再生までできてしまいます。画面写真を貼りたいところですが諸般の事情により自重。ベランダの植木鉢の成長動画をみんなで愛でている様でもご想像下さいw。
■動画の下ごしらえにはApple製のCUIツールを使用
iOS端末で視聴する場合、動画のコーデックはH.264を使います。ただしコンテナはmp4ではなく.ts(MPEG2 トランスポートストリーム)になります。更にDarwinで使う時のヒントトラックのようなインデックス情報をテキストファイルで用意する必要があります。これを簡単にしてくれるCUIツールがAppleから配布されています。Developer登録してないとダウンロードできないかもなので、未登録な人はFFMPEG等を使う方法をググったりしてみて下さい。今回は、streamingtools_beta157_signed.dmgを入手しインストールしてある状態で操作しています。
目標として、720p、600p、480pという三段階の画質/ビットレートの同内容の動画を用意し、クライアント側の帯域にあわせて自動選択をすることにします。H.264/AACなmp4ファイルを用意し、下記のフォルダ階層下に配置します。
src/
lo/
hoge.mp4
mid/
hoge.mp4
hi/
hoge.mp4
srcフォルダの下に、lo/mid/hiというビットレート別のサブフォルダを作り、それぞれの中にレート違いの動画hoge.mp4を置いてます。CUIツールでパス指定とオプションを駆使すればこの配置である必要もないですが、とりあえずAppleのドキュメントに倣っています。動画ファイルを取り違えないよう注意しましょう。
次に、各動画のコンテナ変換とセグメンティングを行います。
cd src/lo
mediafilesegmenter -s –I hoge.mp4
loの部分をmid、hiに置き換え計3回実行します。-sオプションは.tsファイルを単一ファイルで出力する指定。以前はセグメンテーション毎に通し番号の付いた無数の.tsファイルを生成されてたんですが、これをつければ出力される.tsファイルは1つだけになります。-I(大文字のi)はIフレーム単位のシークが行えるようにするインデックスも合わせて出力します。どちらもiOS端末がiOS5以降でないと対応できないようです。ここまででファイル構成は以下のようになると思います。hoge.mp4は不要になるので消しても構いません。
src/
lo/
hoge.mp4
hoge.plist
iframe_index.m3u8
main.ts
prog_index.m3u8
mid/
hoge.mp4
hoge.plist
iframe_index.m3u8
main.ts
prog_index.m3u8
hi/
hoge.mp4
hoge.plist
iframe_index.m3u8
main.ts
prog_index.m3u8
main.tsがtsコンテナにパッケージングし直された動画ファイルです。エンコードする訳ではないので数秒で終わります。prog_index.m3u8ファイルがHTML5のvideoタグで動画ファイルの代わりに指定するプレイリスト定義ファイルです。
次に、この3パッケージの動画をクライアントが動的に切り替えて使用できる統括プレイリストを作成します。srcフォルダ直下に移動し、
variantplaylistcreator -o all.m3u8 lo/prog_index.m3u8 lo/hoge.plist -iframe-url lo/iframe_index.m3u8 mid/prog_index.m3u8 mid/hoge.plist -iframe-url mid/iframe_index.m3u8 hi/prog_index.m3u8 hi/hoge.plist -iframe-url hi/iframe_index.m3u8
ちと見辛いのでビットレート毎に色分けしてみます。最初に出力ファイル-o all.m3u8を指定した後、prog_index.m3u8と(動画名).plistを指定し、-iframe-urlオプションでiframe_index.m3u8を指定。これをビットレート種類の数繰り返すわけです。Iフレームシークが不要な場合は3つ目は省略できます。これでsrcフォルダの下にall.m3u8が生成されます。
一式をWebサーバーに置き、QuickTime Player等のHTTP Live Streaming対応ソフトでall.m3u8ファイル(ビットレート固定したい場合は各サブフォルダのprog_index.m3u8)を開けば(QuickTime Playerの場合は「ファイル」->「場所を開く…」から)再生できるはずです。ただ、手持ちの環境では、なぜかWindows版のQuickTime PlayerやVLCでは再生できませんでした。せっかくiOSで再生できるようになったのにWindowsな人が排斥されては困ります。ここはまだ調査中です。
■HTMLページに埋め込む
HTMLファイルにこんな感じで書くだけでOKです。
<video src="all.m3u8" controls preload=”auto” width="100%"></video>
controlsは操作UIを表示する(なくても表示される?)、preloadはページを開くと同時に動画を先読みする指定です。その他、autoplayを指定すると自動で再生が始まるはずですがiOS(Safari)の場合は無視されるようです。JavaScriptからの再生制御もiOSでは効きませんでした。これができるとAjaxや時刻指定で一斉に再生開始して同期視聴できたり面白い
んですが…
実際に再生してみると、まずは480pの動画から再生され(多分variantplaylistcreatorで指定した順?)、帯域に余裕があると見るや600pや720pに途切れることなくスイッチしていきます。(事前のエンコは手間ですが)最低通信速度の面子に合わせて全員が画質を落とさなくても済むのは大きいです。
画質落ちてもいいからパケット量を減らしたい、という場合は、all.m3u8の代わりにlo/prog_index.m3u8を指定したHTMLを用意してやればOKです。我が家ではURIのGETパラメーターで指定できるように工夫したりしてます。
また、これもウチではMac/iOSのSafariからしか再生に成功していません。videoタグは使えるはずのChromeやFireFox、果てはWindows版のSafariでNG。.m3u8形式のファイルを動画として認識してくれないってことなんでしょうかね?WindowsやAndroidでもHTTP Live Streaming自体はできそうな記事がちらほら見付かるので、もう少しリサーチしてみたいと思います。
複数ビットレートを使い分けようとしない限り、事前の準備はDarwinを使ったRTSP配信とそう手間はかわらず、相手がMacかiOSなら別途ソフトのインストールもいらないで視聴できることがわかりました。難点は同期再生できないこととWindowsからの再生が(今のところ)できない点。このあたりはリサーチ次第で改善できる余地がありそうなので、もう少し研究してみたいと思います。
LiveShell Proを買って見た
単体でHDMI入力を720pでUstreamやニコニコ生放送などRTMPサーバーに映像送信ができるLiveShell Proがファームウェアアップデートで…