はじめに
この記事はAbemaTV Advent Calendar 2017 の12/22分の内容となります。
はじめまして、 @hase-yuu です。
AbemaTVのサーバーチームで、機能開発や映像ファイルのエンコードなど、雑多な業務をしています。
AbemaTVの映像配信については こちら の記事で触れられており、その中でHLS, MPEG-DASHの配信方式がAbemaTVで採用されていることや、生放送における映像ファイルのエンコードについて書かれています。
この記事では、生放送以外の納品されたファイルについて、
配信形式ごとに、ファイルをトランスコードする方法について書きたいと思います。
AbemaTVの映像ファイルフォーマットについて
AbemaTVにおいては、HLS, MPEG-DASHの 2 種類の配信形式を採用しています。
それぞれの配信形式について、 HLSは MPEG2-TS
, fMP4
,(ADTS, MP3)のファイルフォーマットに対応しています。
MPEG-DASH については、仕様自体はファイルフォーマットを限定していませんが、ISO-BMFF
と MPEG-2 TS
用のサブセット・プロファイルがあるため、事実上この 2 つのフォーマットを利用します。
ただし、実際のところ、プレイヤーが全ての仕様に対応しているわけではなく、
配信形式ごとに、再生可能なファイルフォーマットは限られてきます。
プレイヤーごとのファイルフォーマットの対応状況を、以下にまとめました。
HLSファイルフォーマットのプレイヤーのサポート状況(2017/12/22現在)
Android(ExoPlayer) | iOS(AVPlayer) | Web(hls.js) | |
---|---|---|---|
MPEG-2 TS | o | OS X v10.7 or later, iOS 6 or later, and tvOS 9 or later | o |
fMP4 | o | macOS v10.12 or later, iOS 10 or later, and tvOS 10 or later | o |
MPEG-DASHファイルフォーマットのプレイヤーのサポート状況(2017/12/22現在)
Android(ExoPlayer) | Web(dash.js) | |
---|---|---|
MPEG-2 TS | x | x |
fMP4 | o | o |
WebM | o | o |
Matroska | o | o |
※ web(hls.js, dash.js)は、ブラウザによって対応状況が変わります。
WWDC16においてAppleがHLSにおけるfMP4のサポートを発表し、MPEG-2 TSだけでなく、fMP4のプレイヤー対応も進んできており、今後は、HLSとMPEG-DASHの配信においてCMAFに準拠する、fMP4が一般的になるのではないかと予想されます。
AbemaTVにおいては、fMP4へのサポートが進んでいない時期から配信していることもあり、
HLSは MPEG-2 TS
を、MPEG-DASHは fMP4
を利用して配信しています。
映像ファイルのエンコード
AbemaTVでは、納品ファイルを ffmpeg を利用してエンコードしています。
ここでは、実際にファイルをエンコードしてみます。
HLS配信ファイル(MPEG-2 TS)の生成
サンプルとして、AVIのファイルから、5s単位にセグメントしたMPEG-2 TSを生成します。
実際のエンコードは、映像品質を上げるために、パラメータを工夫していますが、
わかりやすくするため、細かいパラメータを省略しています。
% ffmpeg -i big_buck_bunny.avi -hls_time 5 -hls_list_size 0 -hls_flags single_file -c:v libx264 -c:a aac -hls_segment_type "mpegts" master.m3u8
option | 説明 |
---|---|
hls_time | 1セグメントの長さを指定します |
hls_list_size | プレイリスト(m3u8)を構成する最大のセグメント数、0で全てのキーフレームを記載します |
hls_flags single_file | 一つのtsファイルとして出力します、プレイリストにはセグメントのバイト範囲が記載されます |
hls_segment_type | セグメントのファイルフォーマットを記載します(mpegts / fmp4) |
これにより、HLSのプレイリストであるm3u8ファイルと、tsファイルが生成されます。
MPEG-DASH配信ファイル(fMP4)の生成
fMP4のファイルは上記の hls_segment_type
を fmp4
にすることで生成するか、
以下のコマンドで、fMP4を生成できます。
% ffmpeg -i big_buck_bunny.avi -movflags frag_keyframe+empty_moov+separate_moof+default_base_moof big_buck_bunny.mp4
生成されたファイルは、mux(映像ファイルと音声ファイルが混ざっている)となります。
現在MPEG-DASHを再生するプレイヤーは、mux形式のファイルに対応するものはほぼ存在せず、
配信するためには、demux(映像ファイルと音声ファイルが別々)にする必要があります。
MP4Box などのコマンドを利用することによって、fMP4からdemuxのファイルを生成することができますが、セグメントの長さを固定長でしか生成することができません。
$ MP4Box -dash 5000 big_buck_bunny.mp4#video big_buck_bunny.mp4#audio
AbemaTVにおいては、後述するCM挿入のため、セグメントの切れる位置をコントロール必要があり、
fMP4のファイルを自前で分解することにより、demuxファイルを生成しています。
CM挿入のための工夫
AbemaTVでは、 SSAI(Server Side Ad Insertion)方式を採用しており、映像ファイルのセグメントの間にCMのセグメントを挟み込むことにより、広告配信を行なっています。
CMを差し込む際に、セグメントの切れ目が、シーンの切り替わりと一致していない場合、不自然なCMの入りとなってしまうため、違和感なくCMのセグメントを差し込むために、シーンの切り替わり位置にセグメントの切れ目が来るように調整を行なっています。
具体的には、ffmpegのシーン検出オプション(-sc_threshold
)を利用した、機械的なシーンの切り替わり検出と、オペレーターが手動でセグメントの切れ目を指定(-force_key_frames
)することにより、CM差し込みに適した位置で、セグメントを分割しています。
ffmpeg -i big_buck_bunny.avi -hls_time 5 -hls_list_size 0 -hls_flags single_file -c:v libx264 -force_key_frames "00:00:12" -sc_threshold 0 -c:a aac master.m3u8
まとめ
HLS、MPEG-DASHを配信するためのファイルトランスコーディングの方法について書きました。
映像ファイルの最適化については、まだまだやりたいことが全然やれてませんが、 spanky346 や ygoto3_ と共に盛り上げていきたいと思います。
それでは!
参考