MPEG2-TSのライブ配信をwmpで再生?
HLS x WMP
最近動画配信の話の中でHttp Live Streaming(以下HLS)という言葉を聞く機会が増えてきました。HLSはスマートフォン界隈でかなり対応が進んでいて、iOS4やAndroid4.0などでは標準のプレーヤーでの再生が可能です。
HLSの配信方法というのは、エンコード中のmpeg-tsのファイルを10秒程度に細切れにし、それらをプレイリストにして連続で再生するというものです。細切れになったtsファイルは単純に結合すれば1つのtsファイルになります。
wmpはHLSに対応していないけれど、なんとかして再生する方法はないの?というのが今回の趣旨。
wmpはMPEG-TSのファイル自体は再生できる
前提条件としてWindows7のwmp12はローカルのtsファイルをそのまま再生でき、tsファイルをHTTPサーバに置くと再生やシークができます。ではライブ配信を再生するには?
まず考えるのは、ts形式はもともとストリーミングを目的として作られているので、ファイルを全部読み込まなくても再生が始まるのではないかということです。HLSで生成中のファイルをHttpのプログレッシブダウンロードでサイズ未定のまま受信を続け、受信したところまで再生できれば目的は達成されます。これは一見うまくいきそうでしたが、画面サイズが確定したあとバッファ中のまま再生が始まりませんでした。
そこで一旦前の状態に戻って考えてみます。tsファイルをHttpで再生することはできるので、このあたりを少しいじってみることに。ストリーミング生成中でない(完全な?)ファイルでも、サイズが未定だと再生が始まらないのでContent-Lengthは必須のようです。それならContent-Lengthをものすごく大きくすればサイズ未定と同じような状態になるのでは、と思いやってみると・・・wmpは再生を開始した直後になぜかファイルの最後の部分を読み取りにいきました。
これはどういうことなのか。mpeg-tsはテレビ放送などで使われていて、どこから受信しても再生できるようになっているのでファイルヘッダのようなものが存在しません。wmpはまずファイル終端あたりのパケットのタイムスタンプを読み取り、ファイルの再生終了時間を計算しているのではないかということが推測できます。
ライブ配信の再生には未来のHLSセグメントファイルが必要
つまりContent-Lengthを大きくしてストリーミングを巨大な仮想ファイルに見せかけても、その仮想ファイルの最後の部分がなければwmpは再生を開始できないということです。
そしてここから憶測レベルで作業を進めていきます。時間を確定するためならおそらくパケットの中身(動画)などは見ていないだろう、と。もしかするとタイムスタンプだけ適当に修正したデータを用意できればいいのかもしれない。そこで次の図のような仮想MPEG-TSファイルを仮定します。
ストリーミングを始めて40秒経った状態。HLSで分割されたデータを1~4まで持っています。100の時点で配信を終了するとしたら、その付近のセグメントファイルが欲しいところ。しかしタイムマシンでもない限りまだ存在しない未来のデータを手に入れることはできません。なのですでに持っている1~4のデータのタイムスタンプを16分進めたものを1’~4’としてwmpへ送信してみます。するとwmpは16分40秒のファイルとして再生を始めました!
つまりwmpでHLSというかMPEG-TSのライブ配信を再生する方法はこうです。
- ffmpegなどを使ってmpeg-ts形式でエンコードとセグメント分割をする。
- それらのセグメントファイルを結合した仮想mpeg-tsファイルを送信可能なHttpサーバを作成する
- 仮想mpeg-tsファイルにwmpからアクセスが来たら、最初の部分から順番に送信する
- その直後に仮想mpeg-tsファイルの終端あたりを読みに来たら、持っているセグメントのタイムスタンプを書き換えて送信する
ここまで再生する方法を説明してきましたが、テストではタイムスタンプを修正するのに外部ツールを使っているため実際にライブ配信を再生するところまでは至りませんでした。ここをクリアしたとき果たして上手くいくのかどうか・・・
08/25 追記
タイムスタンプを自前で修正するようにしたところ、ちゃんと動作しました。HLSの仕様上30秒~1分の遅延は仕方ないのかなぁという気持ちはありますが一応成功は成功ということで。
2016/11/06追記
Windows10ではサイズ未定ファイルとして普通に再生できるようです。MPEG-TSのストリーミングではヘッダを気にする必要はありませんが、ファイルとして再生しているのでPATとPMTを最初に送信する必要があります。
参考: 地デジ MPEG-2 TS の PCR/PTS/DTS ラップアラウンド (PCR Wrap-around) 問題を回避して ffmpeg で PS 変換できるようにしてみた