任务目标
使用MediaExtractor和MediaMuxer API解析和封装Mp4文件
MediaExtractor
这两个API相对来说内容很少,具体请参考MediaExtractor官方文档。文档给了一个简单的示例,如下:
MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource(...);
int numTracks = extractor.getTrackCount();
for (int i = 0; i < numTracks; ++i) {
MediaFormat format = extractor.getTrackFormat(i);
String mime = format.getString(MediaFormat.KEY_MIME);
if (weAreInterestedInThisTrack) {
extractor.selectTrack(i);
}
}
ByteBuffer inputBuffer = ByteBuffer.allocate(...)
while (extractor.readSampleData(inputBuffer, ...) >= 0) {
int trackIndex = extractor.getSampleTrackIndex();
long presentationTimeUs = extractor.getSampleTime();
...
extractor.advance();
}
extractor.release();
extractor = null;
简单介绍下方法
- setDataSource(…) 设置输入文件的路径,可以是本地也可以是网络文件,如果是网络文件需要网络权限
- getTrackCount() 获取通道数
- getTrackFormat(…) 获取通道格式
- selectTrack(…) 选中追踪通道
- readSampleData(ByteBuffer byteBuf, int offset) 把指定通道的数据按偏移量读取到ByteBuffer中
- getSampleTime() 获取当前时间戳
- advance() 读取下一帧数据
- release() 释放资源
MediaMuxer
MediaMuxer官方文档内容也比较简单,现在支持Mp4、Webp、3GP输出格式,示例如下:
MediaMuxer muxer = new MediaMuxer("temp.mp4", OutputFormat.MUXER_OUTPUT_MPEG_4);
// More often, the MediaFormat will be retrieved from MediaCodec.getOutputFormat()
// or MediaExtractor.getTrackFormat().
MediaFormat audioFormat = new MediaFormat(...);
MediaFormat videoFormat = new MediaFormat(...);
int audioTrackIndex = muxer.addTrack(audioFormat);
int videoTrackIndex = muxer.addTrack(videoFormat);
ByteBuffer inputBuffer = ByteBuffer.allocate(bufferSize);
boolean finished = false;
BufferInfo bufferInfo = new BufferInfo();
muxer.start();
while(!finished) {
// getInputBuffer() will fill the inputBuffer with one frame of encoded
// sample from either MediaCodec or MediaExtractor, set isAudioSample to
// true when the sample is audio data, set up all the fields of bufferInfo,
// and return true if there are no more samples.
finished = getInputBuffer(inputBuffer, isAudioSample, bufferInfo);
if (!finished) {