序章
MediaExtractor は、指定されたメディア ファイルのメディア情報を抽出するために使用されるツール クラスです。率直に言うと、ビデオまたはオーディオ内のトラック、デュレーション、フォーマットなどの情報とデータ ストリームを抽出するために使用できます。
MediaExtractor は通常、ビデオのデコードと再生に MediaCodec と一緒に使用されます。
説明する
ビデオには複数のデータ ストリームを含めることができます (通常はビデオ用に 1 つ、オーディオ用に 1 つですが、複数のオーディオ ストリームが存在する場合もあります)。後続のさまざまな操作を実行する前に、必要なデータ トラック番号を取得する必要があります。
通常、ビデオを再生するには次のクラスを使用します。
- MediaCodec: メディア ファイルのエンコードとデコードを担当し、内部メソッドはすべてネイティブです
- MediaExtractor: 指定された種類のメディア ファイルのトラックをファイルから検索し、それを MediaCodec のバッファに埋める役割を果たします。
- AudioTrack: デコードされたオーディオの再生を担当します。
- SurfaceView: デコードされたビデオを表示します。
動画の再生は主に以下の手順に分かれます。
- MediaExtractor にリソースをロードする
- ビデオが置かれているトラックを取得する
- MediaExtractor はビデオが配置されているトラックを選択します
- ビデオ、デコーダをデコードする MediaCodec を作成します。
- ビデオリソースが終了するまでループを開始します
- エクストラクター内のリソースを 1 つのユニットでデコーダーの入力バッファーに充填します。
- デコーダは、デコードされたビデオを出力バッファに書き込みます。
- デコーダが出力バッファを解放すると、バッファ内のデータがサーフェスにレンダリングされます。
もちろん、これはビデオを再生するだけで、オーディオは再生しません。オーディオの再生については、以前に書いた AudioTrack を参照してください。
皆さん、ビデオとオーディオを混同しないように注意してください。口頭ではビデオについて説明してきましたが、実際の再生ではこれらは分離されています。オーディオは音に対応し、ビデオは画像と写真に対応します。
上記から、この中での MediaExtractor の役割がわかります。
メインメソッド
- setDataSource(String path): データ ソースを設定します。これはローカル ファイルまたはネットワーク ファイルです。
- getTrackCount(): ソースファイルのトラック数を取得
- getTrackFormat(intindex): 指定された(インデックス)のトラックフォーマットを取得します。
- getSampleTime(): 現在のタイムスタンプを返します。
- readSampleData(ByteBuffer byteBuf, int offset): オフセットに従って、指定されたトラックのデータを ByteBuffer に読み取ります。
- Advance(): データの次のフレームを読み取ります
- release(): 読み込み後にリソースを解放します。
使用例
private fun init() {
try {
//构造
mExtractor = MediaExtractor()
//设置视频数据源,可以是本地文件也可以是网络文件,这里我使用了手机本机拍摄的示例文件
mExtractor?.setDataSource("${
externalCacheDir!!.absolutePath}/test.mp4")
for (i in 0 until mExtractor!!.getTrackCount()) {
//获取轨道信息
val mediaFormat: MediaFormat = mExtractor!!.getTrackFormat(i)
val mime = mediaFormat.getString(MediaFormat.KEY_MIME)
Log.i("Test", "第${
i}个轨道格式:$mime\n")
}
} catch (e: Exception) {
Log.e("Test", "出错了", e)
}
}
印刷データは以下の通りです。
I/Test: 第0个轨道格式:video/avc
I/Test: 第1个轨道格式:audio/mp4a-latm
video/avc
上記からわかるように、MediaExtractor は、ビデオのトラック情報とaudio/mp4a-latm
オーディオのトラック情報を表すビデオ ファイルの情報を抽出するのに役立ちます。
主に、対応する MediaFormat を取得するためです。MediaFormat にはビデオのすべての情報が含まれており、一般的に使用されるいくつかのビデオ情報を以下に示します。
val videoIndex = getTrackIndex("video/")//找到视频所在轨道
val mediaFormat: MediaFormat = mExtractor!!.getTrackFormat(videoIndex)
//获取视频高度
val width = mediaFormat.getInteger(MediaFormat.KEY_WIDTH)
//获取视频高度
val height = mediaFormat.getInteger(MediaFormat.KEY_HEIGHT)
//总时长
val duration = mediaFormat.getLong(MediaFormat.KEY_DURATION)
//获取视频缓存输出的最大大小
val maxInputSize = mediaFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE)
//以下是不一定能获取到的数据
//获取采样率
val sampleRate = mediaFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE)
//获取码率
val bitRate = mediaFormat.getInteger(MediaFormat.KEY_BIT_RATE)
//获取声道数量
val channelCount = mediaFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT)
//获取帧率
val frameRate = mediaFormat.getInteger(MediaFormat.KEY_FRAME_RATE)
//PCM编码 模拟信号编码
val pcmEncoding = mediaFormat.getInteger(MediaFormat.KEY_PCM_ENCODING)
詳細については、自分で調べることができます。公式ドキュメント: MediaExtractor
プロジェクトのサンプル ソース コード: Github/VideoDemo
MediaCodec での使用に関する内容については、続報のブログで更新する予定です。