MediaExtractor
MediaExtractor顾名思义就是多媒体提取器,主要负责:
获取媒体文件的格式,包括音视频轨道,编码格式,宽高,采样率,声道数等,
分离音频流,视频流,读取分离后的音视频数据。
相关API概述:
setDataSource(String path)
指定数据来源,支持网络地址和本地地址
getTrackCount()
获取轨道数据数量
getTrackFormat(int index)
获取指定索引位置的轨道格式信息
selectTrack(int index)
根据轨道索引选中指定轨道,选中后将分离器读取选中轨道的数据,读取数据之前必须选中一个轨道,而且同时只能选中一个轨道。
seekTo(long timeUs,int mode)
根据帧时间(timeUs)以及搜寻模式(mode),搜寻最匹配的关键帧。
注意:分离视频轨道时,seekTo不能精确到视频时间,只能根据mode找到最匹配的关键帧。
SEEK_TO_CLOSEST_SYNC 最接近 timeUS 的关键帧
SEEK_TO_NEXT_SYNC timeUS 的下一个关键帧
SEEK_TO_PREVIOUS_SYNC timeUS 的上一个关键帧
advance()
将分离器游标移动到下一帧
readSampleData(ByteBuffer buffer,int offset)
读取当前位置样本数据
getSampleTrackIndex()
获取当前选中的轨道索引
getSampleTime()
当前分离样本时间
getSampleFlags()
获取当前样本类型,为SAMPLE_FLAG_SYNC时表示为关键帧
MediaMuxer
MediaMuxer有助于混合基本流。目前支持mp4或者webm文件作为输出和最多一个音频和、或一个视频基本流。
MediaMuxer不支持复用B帧。
相关API概述:
addTrack(MediaFormat format)
添加具有指定格式的曲目
start()
启动混合器,确保在addTrack之后和writeSampleData之前调用。
writeSampleData(int trackIndex,ByteBuffer byte,MediaCodec.BufferInfo bufferInfo)
将编码的样本写入复用器
stop()
停止混合器
release()
确保在完成任务时释放任何资源
public void extractFile(String path){ File file = new File(path); if (!file.exists()){ return; } try { mMediaExtractor.setDataSource(file.getAbsolutePath()); } catch (IOException e) { e.printStackTrace(); } //获取轨道数量 int trackCount = mMediaExtractor.getTrackCount(); Log.e(TAG, "extractFile: track count"+trackCount); if (trackCount >0){ for (int i = 0; i < trackCount; i++) { MediaFormat trackFormat = mMediaExtractor.getTrackFormat(i); String trackMime = trackFormat.getString(MediaFormat.KEY_MIME); Log.e(TAG, "extractFile: track format"+trackMime); if (trackMime != null && trackMime.startsWith("video/")){ //代表是视频轨道 //以帧/秒为单位描述视频格式帧频的关键 integer = trackFormat.getInteger(MediaFormat.KEY_FRAME_RATE); //根据轨道索引选中指定轨道 mMediaExtractor.selectTrack(i); //初始化合成器 try { mMediaMuxer = new MediaMuxer(SDCARD_PATH +"/output.mp4",MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); //添加具有指定格式的曲目 mVideoTrackIndex = mMediaMuxer.addTrack(trackFormat); //启动混合器 mMediaMuxer.start(); } catch (IOException e) { e.printStackTrace(); } } } if (mMediaMuxer == null){ return; } ByteBuffer allocate = ByteBuffer.allocate(500 * 1024); int sampleSize = 0; MediaCodec.BufferInfo info = new MediaCodec.BufferInfo(); while ((sampleSize = mMediaExtractor.readSampleData(allocate,0))>0){ info.offset = 0; info.size = sampleSize; info.flags = MediaCodec.BUFFER_FLAG_END_OF_STREAM; info.presentationTimeUs += 1000*1000/integer; //将编码的样本写入复用器 mMediaMuxer.writeSampleData(mVideoTrackIndex,allocate,info); mMediaExtractor.advance(); } mMediaExtractor.release(); //停止混合器 mMediaMuxer.stop(); //释放资源 mMediaMuxer.release(); } }
在解析和封装音视频的过程中,还使用到了MediaFormat,MediaCodec等,详细介绍请点击:MediaCodec,MediaFormat详解。
接下来学习----音视频开发六:学习 Android 平台 OpenGL ES
标签:MediaMuxer,MediaExtractor,int,轨道,mMediaExtractor,mMediaMuxer,音视频,MediaCodec From: https://www.cnblogs.com/opensmarty/p/17127510.html