woshidan's blog

そんなことよりコードにダイブ。

Media Streaming on Androidを見て面白かったので細々調べたメモ(動画のストリーミング配信プロトコル周り)

speakerdeck.com

このメモはセッションで話された内容の書き起こしではなく、上記のスライドの内容が面白かったので自分で勝手に調べたメモです。

調べた結果とセッション中と用語のずれがある場合は、Abema TVのCode IQのプレス記事*1を優先させていただきました。

目次

  • Androidで動画を再生するためのクラス
  • Streamingで動画をダウンロードする、そのためにそれ用のコーデックで圧縮する
  • Apple製のストリーミング動画配信プロトコル HLS(HTTP Live Streaming)とその実装に必要なファイル
  • Abemaで採用しているストリーミング動画配信プロトコル MPEG-DASHの説明

Androidで動画を再生するためのクラス

  • MediaPlayerExoPlayerがある
  • 前者はAPI Level 1からある、詳細はいじれないが単純なユースケースの場合はこれをポンと置いておけば良い
  • 後者はAPI Level 14から利用でパラメータがカスタマイズできる
    • 利用するときはGradleで com:google:android:exoplayer:exoplayer:x.x.x の依存を追加
    • このライブラリは使う機能に合わせて全体やCore, UI, HLS, OKHTTP(通信周りのカスタマイズ)に分かれている

Streamingで動画をダウンロードする、そのためにそれ用のコーデックで圧縮する

  • 動画をダウンロードして再生する、という場面では再生用のファイルをすべてDLしてから再生する場合と再生用のデータを都度都度ダウンロードして再生する場合がある
  • ストリーミング、の場合は後者
    • いわゆるストリーミングにも大きく分けてプログレッシブダウンロード方式(ファイルをHDにダウンロードする)とストリーミング方式(ファイルの内容はその場で取得するだけ)がある
      • プログレッシブダウンロード方式は動画の容量が多いとあれなんですが、シークバーを少し前に戻してもふたたびDLせずにその場で再生可能(DLしたファイルがまだ端末内に残っているので)だったり、さきもってDLするので一気に動画の後半へ飛んだりが可能で、一時期のYoutubeなどで採用されていた*2
      • ストリーミング方式はシークバーを動かしてから動画のDLをするまでしばらくかかることはあるが、都度都度クライアント側の状況に合わせた動画の取得が可能だったり、ネットワークの切り替え(Wifi <=> 4Gなど)が起こりがちな状況(モバイルなど)に対して有利
        • クライアント側にコンテンツが残らないのでセキュア
  • 動画を都度都度ダウンロードするとして
    • 動画は音声 + 画像の集まり
    • 画像分だけでもまじめに考えればとてもじゃないが4Gの通信帯域の幅を越してしまうよね
      • 1pixel = 24bits, 1frame = 49 Mbits, 1second = 1492M bits, 1492M bits(1秒あたりの動画容量) > 60Mbps (4G LTEの通信帯域幅(理想))
    • このままだと配信できるわけがないので圧縮して通信しましょう
    • 動画の圧縮方式をコーデック*3といい、h264という圧縮方式が用いられることが多いです
    • 圧縮すると1/100くらいになるので配信できそう

Apple製のストリーミング動画配信プロトコル HLS(HTTP Live Streaming)とその実装に必要なファイル

  • h264で圧縮したファイルでストリーミング配信をしていますが、そのストリーミング配信のプロトコルはHLS(HTTP Live Streaming)がありますよ
    • HLSを定義したのはApple
  • HLSでストリーミング配信をするには3つのファイルが関係あって
    • Master Playlist (拡張子 .m3u8)
    • Media Playlist (拡張子 .m3u8)
    • ts files (拡張子 .ts)
  • ストリーミング再生のために関連ファイルを取得していく手順
    • 最初に Master Playlist を取得
    • Master Playlistに帯域幅ごとetc. の動画ファイル用Media PlaylistのURLが書いてあるのでMedia Playlistを取得
    • Media Playlistに動画ファイルのURLとそのファイルの再生時間(EXTINF *4 )が書いてあるのでそれを見てtsファイルの取得をする*5
  • ちなみに、tsファイルは「MPEG-2 TS」ファイル
    • もともと地上デジタル放送などで用いられる映像・音声データの形式「MPTG-2 TS」をファイル化する際に数秒単位の「MPEG-2 TS」として細切れにし、暗号化したもの*6

Abemaで採用しているストリーミング動画配信プロトコル MPEG-DASHの説明

  • さっきHLSの話をしたんですが、Abema TVで実際利用しているのはMPEG-DASHというプロトコルですよ*7
    • MPEG-DASHの“DASH”はDynamic Adaptive Streaming over HTTPの略で、国際標準化機関ISO/IECが定義したHTTPストリーミングを行うための規格 *8
      • 動画や音声ファイルを管理するメタデータを記述したMPD(Media Presentation Description)と呼ぶマニフェストファイル仕様を定めた規格と、実際に動画コンテンツを伝送するためのsegment formatと呼ぶファイルフォーマットの運用規格 *9
  • MPEG-DASHで主要なファイルは MPD(.mpd), fragmented mp4 file(.m4s), Initialization file(.m4s) *10
  • 普通のmp4 vs fragmented mp4 file
    • mp4はbox*11という要素が連なった木構造データ形式となっている
      • 代表的な要素(box/atom)として
        • ファイルタイプが記述された ftyp
        • メタデータ*12が書いてある moov
        • メディアデータ*13本体の mdat
      • これらのbox/atomの構成の様子はスライド中の mp4dump コマンドや専用のツールで確認出来る
    • Fragmented mp4 fileはわざわざ名前を変えている通り、少々勝手が異なる
    • .mp4 ファイルを構成する主要な要素について、フラグメントごとに要素を用意している(moof, mdat)
      • ファイルタイプが記述された ftyp (これは同じ)
      • sidx: index of moof + mdat
        • 細分化する前のファイルにおいてこのmp4はどこに位置するか
      • moof: メタデータが書いてあるmoovのフラグメント版。全体に対するメタデータではなく分割されたファイルに対するメタデータ
      • mdat: メディアデータ本体 (これは同じ)
    • フラグメントのファイル群だけでは動画全体の情報が足りないため、全体を統括するためのファイルが必要でこれがinitialization fileやInitialization fragmentと呼ばれている*14
      • Initialization Fragmentの方はftyp(ファイル形式)は dash で動画全体のメタデータに当たる moov を持っている
  • 上記動画ファイルとは別にMPD(Media Presentation Description)がある
    • MPDは動画や音声ファイルを管理するメタデータを記述したマニフェストファイル
    • 要素には
      • MPD: Live配信用につどつど動画データを取りに行く vs 一気にダウンロード, バッファするデータの最小値 etcを書く
      • Representation: ビットレートごとの動画データについて記述 など

長くなってきたので一旦ここまでにします。。

*1:https://codeiq.jp/magazine/2017/11/55460/

*2: http://blog.socialcast.jp/05/post-15/ https://dev.classmethod.jp/tool/http-live-streaming/ など

*3:Wikipediaですが https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%BC%E3%83%87%E3%83%83%E3%82%AF#%E5%8B%95%E7%94%BB%E5%9C%A7%E7%B8%AE%E3%81%AE%E3%82%B3%E3%83%BC%E3%83%87%E3%83%83%E3%82%AF

*4:http://blog.kokoni.jp/2014/02/14/hls%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9/

*5:ファイルごとの再生時間を見て次のファイルをいつ頃取ったらいいとか見るのだろうかと思ったけどこれは想像です

*6:https://k-tai.watch.impress.co.jp/docs/column/keyword/515059.html http://did2memo.net/2017/02/20/http-live-streaming/

*7:Amebaさんのプレス https://codeiq.jp/magazine/2017/11/55460/ 概要としてはこちらもよさそう https://www.ite.or.jp/contents/keywords/1701keyword.pdf

*8:https://codeiq.jp/magazine/2017/11/55460/ より引用

*9:https://www.jstage.jst.go.jp/article/itej/67/2/67_109/_pdf より引用

*10:ファイル拡張子がスライド表記と異なるが https://codeiq.jp/magazine/2017/11/55460/

*11:mp4の前身であるQuickTimeフォーマットに倣いatomとも呼ばれる この辺の参考は http://yebisupress.dac.co.jp/2015/11/04/profile%EF%BC%9Fatom%EF%BC%9Fmp4%E3%81%AE%E3%82%88%E3%81%8F%E3%82%8F%E3%81%8B%E3%82%89%E3%81%AA%E3%81%84%E3%81%82%E3%82%8C%E3%81%93%E3%82%8C%EF%BC%88atom%E7%B7%A8/

*12:ファイルサイズ、再生時間など動画本体以外の付随情報

*13:動画や音声ですね

*14:https://www.jstage.jst.go.jp/article/itej/67/2/67_109/_pdf も参照