Android

AndroidのMediaCodecでFLVファイルを再生する

More than 3 years have passed since last update.

Android で ffmpeg 等を使わずに端末標準のデコーダでflvを再生してみました.

flvのフォーマットや MediaCodec API の基本的な使い方は下記のURLを参照してください.

flvの仕様のPDFファイルは,いまadobeからダウンロードできる10.1より,10のもののほうが目次がちゃんとしてたりして読みやすい(?).


コーデック

flv のコーデックのうち,AAC, mp3と H.264, H.263 あたりは,Androidがコーデック持ってるので再生できそうです.

VP6とかもよく見かけるけど, Stagefright に入ってないようなので難しそうです.


音声コーデック(AAC,mp3)

音声データは特に難しいところはありませんが,Audio tagの最初のバイトに SoundRate, SoundSize 等が入っているので,最初のAudio tagを見つけた時点で,AudioTrackやDecoderを初期化します.

また,AACのみパケットのタイプがデータの先頭に1バイト付いてるので処理する必要があります(無視してもデコード出来ると思いますが).


H.264

デコーダに渡すNAL unitのスタートコードはAnnex-B形式の [0x00,0x00,0x00,0x01] でなければいけないようです.

flvは4バイトのサイズが付いているので,そこをすべて[0,0,0,1]に書き換えるだけです.

わかりにくい箇所は,コンフィグレーションレコードの扱いで,flvにはmp4のavcCと同じ形式でH.264のコンフィグレーションが入っていますが,そのままMediaDecoderに渡してもデコード出来ません.

http://stackoverflow.com/questions/25160710/decode-mp4-h-264-using-mediacodec-without-mediaextractor-expected-access-unit-f

mp4をMediaExtractorでパースした場合にどうなっているのかも疑問だったのですが,MediaFormatに"csd-0","csd-1"という名前のキーで書き込まれているようです.

同様に,MediaFormatに入れても良いし,または,NAL形式に変換してBUFFER_FLAG_CODEC_CONFIG フラグを付けて

デコーダに渡せばデコードできます.


H.263

FLVはH.263を格納出来ますが,通常のH.263ではなく,Sorenson Sparkです.よく似たフォーマットですが,互換性は無いのでビットストリームをパースして組み立て直す必要があります.

(目処はついてますが,まだ上手くデコードできてません)

Sorenson Spark は H.263 のサブセットなので,再エンコードせずに変換可能なはずです.Group of Block(GOB) Layerが存在しませんが,Macro Block(MB)は1つしかMBがないGOBと等しいので,Picture Layerだけ上手く作ればデコードできます.

ffmpegを読めば,どうにか出来そうです.

CEREVOの稲垣さんが,今回とは逆の,H.263からSparkへの変換をやっている記事.H.263からSparkへは一般的には変換出来ないのですが,エンコード時のパラメータさえ気をつければ可能なようです.


いろいろメモ

最初,ffmpegのコードを読もうとしていたけど,つらくなって諦めました.

ビデオのデコード時にMediaFormatにColorFormatは指定できません.リファレンスにも指定できるとは書かれてないし,指定しても無視されます.デバッグ時に,RGBで出力して欲しくて試行錯誤して少し嵌りました.H.264の場合はFormatYUV420PackedSemiPlanar等で出てきます.

コーデックに変なデータ渡したりして,久しぶりにOSごと固まったりするのを見ました.

H.264は端末によってサポートしてるプロファイルが違うので,再生できなくて間違ってるのかなーと思ったら別の端末では再生できたりも.


まとめとか

Androidで AAC, mp3と H.264 はデコードできるのを確認しました(当たり前ですが...).

標準のデコーダを使うのでハードウェアデコーダが有効になるのが良いです.


書いた実験用アプリ

https://github.com/binzume/android-flv-player

この記事も含めて,MIT Licenseです.