音视频分离器,将一些格式的视频分离出 视频轨道和音频轨道。
主要流程和API:
int videoTrackIndex = -1;
int audioTrackIndex = -1;
for(int i = 0; i < mMediaExtractor.getTrackCount(); i++) {
//获取码流的详细格式/配置信息
MediaFormat format = mMediaExtractor.getTrackFormat(i);
String mime = format.getString(MediaFormat.KEY_MIME);
if(mime.startsWith("video/")) {
videoTrackIndex = i;
}
else if(mime.startsWith("audio/")) {
audioTrackIndex = i;
}
}
获取到媒体文件的详细信息之后,就可以选择指定的通道,分离和读取数据
mMediaExtractor.selectTrack(videoTrackIndex); //选择读取视频数据
while(true) {
int sampleSize = mMediaExtractor.readSampleData(buffer, 0); //读取一帧数据,获取指定通道数据
if(sampleSize < 0) {
break;
}
mMediaExtractor.advance(); //移动到下一帧
}
mMediaExtractor.release(); //读取结束后,要记得释放资源
音视频合成器,将 视频和音频合成 相应的格式。
1.创建对象后,一个比较重要的操作就是addTrack
,添加数据通道,需要传入MediaFormat对象,MediaFormat即媒体格式类,用于描述媒体的格式参数(视频帧率,音频采样率等
两种方式:
使用MediaExtractor.getTrackFormat()解析得到的MediaFormat对象(实际很少使用
手动创建MediaFormat对象
MediaFormat.createVideoFormat(MIMETYPE_VIDEO_AVC,width,height);
MediaFormat.createAudioFormat(MIMETYPE_AUDIO_AAC, sampleRate, channelCount);
2.通过addTrack()后,记录下对应的trackIndex,就可以使用MediaMuxer.writeSampleData(),向mp4文件中写入数据了。
BufferInfo info = new BufferInfo();
info.offset = 0;
info.size = sampleSize;//数据大小
info.flags = MediaCodec.BUFFER_FLAG_SYNC_FRAME;//是否为关键帧
info.presentationTimeUs = timestamp;//必须给出正确的时间戳!单位是微妙us
mMediaMuxer.stop();
mMediaMuxer.release();
根据实际需求,初始化参数(path,fileName,createTime,fps等,需要帧率是为了计算视频时间戳,且有一个预录需求,需要帧率设置一个圆环buffer)
//根据参数初始化MediaMuxer
mediaMuxer = new MediaMuxer(filePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
//手动创建对应MediaFormat
videoFormat = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, param.width, param.height);
audioFormat = MediaFormat.createAudioFormat(MediaFormat.MIMETYPE_AUDIO_AAC, 8000, 1);
关于编码器的介绍放后面,在此只说过程。
mediaMuxer.writeSampleData(index, buffer, info);