Android オーディオおよびビデオ開発 (8) MediaExtractor

序章

MediaExtractor は、指定されたメディア ファイルのメディア情報を抽出するために使用されるツール クラスです。率直に言うと、ビデオまたはオーディオ内のトラック、デュレーション、フォーマットなどの情報とデータ ストリームを抽出するために使用できます。
MediaExtractor は通常、ビデオのデコードと再生に MediaCodec と一緒に使用されます。

説明する

ビデオには複数のデータ ストリームを含めることができます (通常はビデオ用に 1 つ、オーディオ用に 1 つですが、複数のオーディオ ストリームが存在する場合もあります)。後続のさまざまな操作を実行する前に、必要なデータ トラック番号を取得する必要があります。

通常、ビデオを再生するには次のクラスを使用します。

  1. MediaCodec: メディア ファイルのエンコードとデコードを担当し、内部メソッドはすべてネイティブです
  2. MediaExtractor: 指定された種類のメディア ファイルのトラックをファイルから検索し、それを MediaCodec のバッファに埋める役割を果たします。
  3. AudioTrack: デコードされたオーディオの再生を担当します。
  4. SurfaceView: デコードされたビデオを表示します。

動画の再生は主に以下の手順に分かれます。

  1. MediaExtractor にリソースをロードする
  2. ビデオが置かれているトラックを取得する
  3. MediaExtractor はビデオが配置されているトラックを選択します
  4. ビデオ、デコーダをデコードする MediaCodec を作成します。
  5. ビデオリソースが終了するまでループを開始します
  6. エクストラクター内のリソースを 1 つのユニットでデコーダーの入力バッファーに充填します。
  7. デコーダは、デコードされたビデオを出力バッファに書き込みます。
  8. デコーダが出力バッファを解放すると、バッファ内のデータがサーフェスにレンダリングされます。

もちろん、これはビデオを再生するだけで、オーディオは再生しません。オーディオの再生については、以前に書いた 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 での使用に関する内容については、続報のブログで更新する予定です。

おすすめ

転載: blog.csdn.net/gs12software/article/details/105951635