当前位置: 首页 > news >正文

android 之 MediaExtractor

MediaExtractor 是Android多媒体处理的基础组件,解封装是其核心价值。

一、功能与定位

MediaExtractor 是Android多媒体框架中的媒体解封装工具,主要作用是从媒体文件(如MP4、MKV、MP3)中分离音视频轨道数据,为后续解码(MediaCodec)或处理提供原始压缩数据流。

  • 核心能力
    • 解析多种封装格式(MP4、WebM、FLV等),提取音频、视频、字幕轨道。
    • 支持本地文件、网络流(需Uri)、加密媒体源。

二、核心API详解

1. 初始化与数据源设置
MediaExtractor extractor = new MediaExtractor();
// 设置数据源(三选一)
extractor.setDataSource("/sdcard/video.mp4");          // 本地路径
extractor.setDataSource(fd);                           // 文件描述符
extractor.setDataSource(context, uri, headers);        // 网络流或ContentProvider
2. 轨道管理
方法作用
int getTrackCount()获取轨道总数(音/视/字幕)
MediaFormat getTrackFormat(int index)获取轨道格式(分辨率、码率、MIME类型等)
void selectTrack(int index)选择需处理的轨道(后续操作仅针对该轨道)
void unselectTrack(int index)取消选择轨道

示例:选择首个视频轨道

for (int i = 0; i < extractor.getTrackCount(); i++) {MediaFormat format = extractor.getTrackFormat(i);String mime = format.getString(MediaFormat.KEY_MIME);if (mime.startsWith("video/")) {extractor.selectTrack(i); // 选中视频轨道break;}
}
3. 数据读取与控制
方法功能
int readSampleData(ByteBuffer buffer, int offset)读取当前样本数据到缓冲区,返回数据大小(-1表示结束)
long getSampleTime()获取当前样本时间戳(微秒)
int getSampleFlags()获取样本标志(如关键帧BUFFER_FLAG_KEY_FRAME
boolean advance()移动到下一样本,返回是否成功
void seekTo(long timeUs, int mode)跳转到指定时间点(SEEK_TO_CLOSEST_SYNC等模式)

关键参数说明

  • offset:指定数据在缓冲区中的写入偏移量,用于分段读取大文件。
  • seekTo模式:
    • SEEK_TO_PREVIOUS_SYNC:跳转到前一个关键帧(高效解码)。
    • SEEK_TO_CLOSEST_SYNC:跳转到最近关键帧(推荐平衡效率与精度)。
4. 资源释放
extractor.release(); // 必须调用,避免内存泄漏

三、底层实现原理

1. 架构分层
层级组件职责
JNI接口层android_media_MediaExtractor.cppJava与C++桥接,转发API调用
C++核心层NuMediaExtractor媒体解析、轨道分离、数据提取
数据源层DataSource从文件/网络/加密源读取原始数据
Extractor插件MP4Extractor按格式实现具体解析逻辑(动态注册)
2. 工作流程
  1. 初始化
    • Java层调用setDataSource() → JNI触发NuMediaExtractor创建。
    • 通过DataSource::RegisterDefaultSniffers()注册格式解析器(如SniffMPEG4)。
  2. 格式识别
    • 轮询所有ExtractorPlugin,根据文件头匹配最佳解析器(置信度最高者)。
  3. 数据提取
    • 按时间戳顺序交错读取音视频样本(非随机排列)。
    • 通过readSampleData()返回压缩数据至应用层缓冲区。

四、典型应用场景

  1. 音视频播放器
    • 配合MediaCodec解码 → Surface渲染视频,AudioTrack播放音频。
  2. 媒体文件转换
    • 提取音视频轨道 → 通过MediaMuxer重新封装为新格式(如MP4转MKV)。
  3. 音视频编辑
    • 剪切:seekTo()定位起始点 → 读取指定区间数据。
    • 合并:多MediaExtractor读取 → MediaMuxer合成。
  4. 自定义处理
    • 提取原始H.264/AAC流 → 滤镜处理 → 重新编码。

深入实现可参考源码:

  • JNI层:frameworks/base/media/jni/android_media_MediaExtractor.cpp
  • C++层:NuMediaExtractorframeworks/av/media/libmediaextractor/
http://www.lqws.cn/news/173179.html

相关文章:

  • JuiceFS v1.3-Beta2:集成 Apache Ranger,实现更精细化的权限控制
  • 使用 Windows 完成 iOS 应用上架:Appuploader对比其他证书与上传方案
  • uniapp map组件的基础与实践
  • Flink checkpoint
  • LlamaIndex 工作流简介以及基础工作流
  • 中国首套1公里高分辨率大气湿度指数数据集(2003~2020)
  • C++11完美转发
  • 练习:对象数组 4
  • Electron Fiddle使用笔记
  • 面向无人机海岸带生态系统监测的语义分割基准数据集
  • stylus - 新生代CSS预处理框架
  • 我用Amazon Q写了一个Docker客户端,并上架了懒猫微服商店
  • SSL证书深度解析与实践指南
  • 宝塔think PHP8 安装使用FFmpeg 视频上传
  • matlab不同版本对编译器的要求(sfunction 死机)
  • Transformer-BiGRU多变量时序预测(Matlab完整源码和数据)
  • 2025年06月06日Github流行趋势
  • 嵌入式学习笔记-freeRTOS taskENTER_CRITICAL(_FROM_ISR)跟taskEXIT_CRITICAL(_FROM_ISR)函数解析
  • uniapp 开发ios, xcode 提交app store connect 和 testflight内测
  • 基于最大相邻夹角的边缘点提取(matlab)
  • 简约商务年终工作总结报告PPT模版分享
  • Tailwind CSS 实战:基于 Kooboo 构建 AI 对话框页面(八):异步处理逻辑详解
  • 使用 Ansible 在 Windows 服务器上安装 SSL 证书
  • 爆炸仿真的学习日志
  • spark 执行 hive sql数据丢失
  • IDEA运行Tomcat出现乱码问题解决汇总
  • C++_哈希表
  • 自托管图书搜索引擎Bookologia
  • 从0开始学习R语言--Day18--分类变量关联性检验
  • 【Spark征服之路-2.3-Spark运行架构】