MediaExtractorCompat 类是平台 MediaExtractor 类的直接替代,可提供相同的 API 和功能。它有助于从数据源中提取解复用的媒体数据(通常是编码的)。
它会将容器文件(如 MP4 或 MKV)分离为各个轨道,例如视频、音频和字幕。然后,提取器会从这些轨道中读取原始的编码数据,作为一系列样本(例如,单个压缩视频帧或音频块),然后再将这些数据发送到解码器。
常见用例包括:
- 转码或重混:从轨道读取编码后的样本,以更改编解码器(转码)或将数据流重新打包到新容器中(重混),例如将 MP4 文件转换为 MKV。
- 选择性内容提取:隔离并保存单个轨道,例如从视频文件中提取音频流。
- 低级别调试:检查单个样本以调试文件损坏、时间戳问题或其他问题。
- 构建自定义播放器:对于小众用例,构建可完全控制媒体流水线的自定义播放器。
概览
以下代码示例展示了如何使用 MediaExtractorCompat:
Kotlin
fun extractSamples(context: Context, mediaPath: String) { val extractor = MediaExtractorCompat(context) try { // 1. Setup the extractor extractor.setDataSource(mediaPath) // Find and select available tracks for (i in 0 until extractor.trackCount) { val format = extractor.getTrackFormat(i) extractor.selectTrack(i) } // 2. Process samples val buffer = ByteBuffer.allocate(10 * 1024 * 1024) while (true) { // Read an encoded sample into the buffer. val bytesRead = extractor.readSampleData(buffer, 0) if (bytesRead < 0) break // Access sample metadata val trackIndex = extractor.sampleTrackIndex val presentationTimeUs = extractor.sampleTime val sampleSize = extractor.sampleSize extractor.advance() } } catch (e: IOException) { handleFailure(e) } finally { // 3. Release the extractor extractor.release() } }
Java
public void extractSamples(Context context, String mediaPath) { MediaExtractorCompat extractor = new MediaExtractorCompat(context); try { // 1. Setup the extractor extractor.setDataSource(mediaPath); // Find and select available tracks for (int i = 0; i < extractor.getTrackCount(); i++) { MediaFormat format = extractor.getTrackFormat(i); extractor.selectTrack(i); } // 2. Process samples ByteBuffer buffer = ByteBuffer.allocate(10 * 1024 * 1024); while (true) { // Read an encoded sample into the buffer. int bytesRead = extractor.readSampleData(buffer, 0); if (bytesRead < 0) { break; } // Access sample metadata int trackIndex = extractor.getSampleTrackIndex(); long presentationTimeUs = extractor.getSampleTime(); long sampleSize = extractor.getSampleSize(); extractor.advance(); } } catch (IOException e) { handleFailure(e); } finally { // 3. Release the extractor extractor.release(); } }