MediaMuxer和MediaExtractor
来源:互联网 发布:json数组格式怎样写 编辑:程序博客网 时间:2024/04/30 14:04
MediaExtractor主要用于提取音视频相关信息,分离音视频。
MediaMuxer主要复用和解复用音视频。
MediaExtractor使用一般步骤
1.//设置数据源setDataSource2.//分离轨道getTrackCount,getTrackFormat3.//选择轨道selectTrack,unselectTrack4.//读取数据readSampleData5.//下一帧advance6.//释放release
eg:
int trackCount = mediaExtractor.getTrackCount();for (int i = 0; i < trackCount; i++) { MediaFormat trackFormat = mediaExtractor.getTrackFormat(i); String mime = trackFormat.getString(MediaFormat.KEY_MIME); if (mime.startsWith("video/")) { mediaExtractor.selectTrack(i); break; } else if (mime.startsWith("audio/")) { mediaExtractor.selectTrack(i); break; } }
MediaMuxer使用一般步骤
1.//添加轨道addTrack2.写数据writeSampleData3.释放release
注意点
buffinfo 必须设置相应的有效值,不然会引发错误 //写入数据大小 bufferInfo.size = readSampleDataSize; //偏移量 bufferInfo.offset = 0; //是否为关键帧 bufferInfo.flags = mediaExtractor.getSampleFlags(); //PTS 单位为微妙,必须为递增不然会报错 bufferInfo.presentationTimeUs += videoSampleTime; mediaMuxer.writeSampleData(trackIndex, buffer, bufferInfo);这里重点关注下bufferInfo.presentationTimeUsmediaExtractor.getSampleTime()因为mediaExtractor的提取顺序应该是dts的顺序不是pts的顺序,如果视频中存在b帧则getSampleTime不可能递增的,所以bufferInfo.presentationTimeUs=mediaExtractor.getSampleTime()可能会报错,前面说了这个值必须递增。如果不存在b帧,pts==dts,使用没问题。
设置PTS的办法
1.算出帧时间距,github上看见的,排除i帧来计算不知道是为什么,不排除感觉也一样的
long videoSampleTime;// mediaExtractor.readSampleData(buffer, 0);// //skip first I frame// if (mediaExtractor.getSampleFlags() == MediaExtractor.SAMPLE_FLAG_SYNC)// mediaExtractor.advance(); mediaExtractor.readSampleData(buffer, 0); long firstVideoPTS = mediaExtractor.getSampleTime(); mediaExtractor.advance(); mediaExtractor.readSampleData(buffer, 0); long SecondVideoPTS = mediaExtractor.getSampleTime(); videoSampleTime = Math.abs(SecondVideoPTS - firstVideoPTS);
2.通过帧率来计算
//每秒多少帧int frameRate=mediaFormat=getInteger(MediaFormat.KEY_FRAME_RATE)//得出平均每一帧间隔多少微妙videoSampleTime=1000*1000/frameRate
最后提供2个简单的运用示例
有耗时,不要ui线程使用,只是演示
/** * 提取音/视频 * * @param inPath * @param outPath * @param isVideo */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) public static void trackExtractor(String inPath, String outPath, boolean isVideo) { //提取器 MediaExtractor mediaExtractor = new MediaExtractor(); try { mediaExtractor.setDataSource(inPath); } catch (IOException e) { e.printStackTrace(); } MediaMuxer mediaMuxer = null; //复用器 try { mediaMuxer = new MediaMuxer(outPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); } catch (IOException e) { e.printStackTrace(); } int trackIndex = 0; int trackCount = mediaExtractor.getTrackCount(); for (int i = 0; i < trackCount; i++) { MediaFormat trackFormat = mediaExtractor.getTrackFormat(i); String mime = trackFormat.getString(MediaFormat.KEY_MIME); if (mime.startsWith("video/") && isVideo) { trackIndex = mediaMuxer.addTrack(trackFormat); mediaExtractor.selectTrack(i); break; } else if (mime.startsWith("audio/") && !isVideo) { trackIndex = mediaMuxer.addTrack(trackFormat); mediaExtractor.selectTrack(i); break; } } mediaMuxer.start(); ByteBuffer buffer = ByteBuffer.allocate(1024 * 1000); MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo(); long videoSampleTime=getSampleTime(mediaExtractor,buffer); while (true) { int readSampleDataSize = mediaExtractor.readSampleData(buffer, 0); if (readSampleDataSize < 0) { break; } bufferInfo.size = readSampleDataSize; bufferInfo.offset = 0; bufferInfo.flags = mediaExtractor.getSampleFlags(); bufferInfo.presentationTimeUs += videoSampleTime; mediaMuxer.writeSampleData(trackIndex, buffer, bufferInfo); mediaExtractor.advance(); } mediaExtractor.release(); mediaMuxer.stop(); //内部也会执行stop,所以可以不用执行stop mediaMuxer.release(); } private static long getSampleTime(MediaExtractor mediaExtractor, ByteBuffer buffer) { long videoSampleTime;// mediaExtractor.readSampleData(buffer, 0);// //skip first I frame// if (mediaExtractor.getSampleFlags() == MediaExtractor.SAMPLE_FLAG_SYNC)// mediaExtractor.advance(); mediaExtractor.readSampleData(buffer, 0); long firstVideoPTS = mediaExtractor.getSampleTime(); mediaExtractor.advance(); mediaExtractor.readSampleData(buffer, 0); long SecondVideoPTS = mediaExtractor.getSampleTime(); videoSampleTime = Math.abs(SecondVideoPTS - firstVideoPTS); Log.d("MediaMuxerUtil", "videoSampleTime is " + videoSampleTime); return videoSampleTime; } /** * 合成音视频 * * @param videoPath * @param audioPath * @param outPath */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) public static void trackMuxer(String videoPath, String audioPath, String outPath) { MediaExtractor videoExtractor = new MediaExtractor(); try { videoExtractor.setDataSource(videoPath); } catch (IOException e) { e.printStackTrace(); } MediaFormat videoFormat = null; int videoTrackIndex = -1; int videoTrackCount = videoExtractor.getTrackCount(); for (int i = 0; i < videoTrackCount; i++) { videoFormat = videoExtractor.getTrackFormat(i); String mime = videoFormat.getString(MediaFormat.KEY_MIME); if (mime.startsWith("video/")) { videoTrackIndex = i; break; } } MediaExtractor audioExtractor = new MediaExtractor(); try { audioExtractor.setDataSource(audioPath); } catch (IOException e) { e.printStackTrace(); } MediaFormat audioFormat = null; int audioTrackIndex = -1; int audioTrackCount = audioExtractor.getTrackCount(); for (int i = 0; i < audioTrackCount; i++) { audioFormat = audioExtractor.getTrackFormat(i); String mime = audioFormat.getString(MediaFormat.KEY_MIME); if (mime.startsWith("audio/")) { audioTrackIndex = i; break; } } videoExtractor.selectTrack(videoTrackIndex); audioExtractor.selectTrack(audioTrackIndex); MediaCodec.BufferInfo videoBufferInfo = new MediaCodec.BufferInfo(); MediaCodec.BufferInfo audioBufferInfo = new MediaCodec.BufferInfo(); MediaMuxer mediaMuxer = null; try { mediaMuxer = new MediaMuxer(outPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); } catch (IOException e) { e.printStackTrace(); } int writeVideoTrackIndex = mediaMuxer.addTrack(videoFormat); int writeAudioTrackIndex = mediaMuxer.addTrack(audioFormat); mediaMuxer.start(); ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 1000); long videoSampleTime=getSampleTime(videoExtractor,byteBuffer); while (true) { int readVideoSampleSize = videoExtractor.readSampleData(byteBuffer, 0); if (readVideoSampleSize < 0) { break; } videoBufferInfo.size = readVideoSampleSize; videoBufferInfo.presentationTimeUs +=videoSampleTime; videoBufferInfo.offset = 0; videoBufferInfo.flags = videoExtractor.getSampleFlags(); mediaMuxer.writeSampleData(writeVideoTrackIndex, byteBuffer, videoBufferInfo); videoExtractor.advance(); } long audioSampleTime=getSampleTime(audioExtractor,byteBuffer); while (true) { int readAudioSampleSize = audioExtractor.readSampleData(byteBuffer, 0); if (readAudioSampleSize < 0) { break; } audioBufferInfo.size = readAudioSampleSize; audioBufferInfo.presentationTimeUs += audioSampleTime; audioBufferInfo.offset = 0; audioBufferInfo.flags = audioExtractor.getSampleFlags(); mediaMuxer.writeSampleData(writeAudioTrackIndex, byteBuffer, audioBufferInfo); audioExtractor.advance(); } mediaMuxer.stop(); mediaMuxer.release(); videoExtractor.release(); audioExtractor.release(); }
0 0
- MediaMuxer和MediaExtractor
- 利用MediaExtractor和MediaMuxer实现视频剪切
- 利用MediaExtractor和MediaMuxer实现视频剪切
- Android 视频分离和合成(MediaMuxer和MediaExtractor)
- 使用MediaExtractor和MediaMuxer分类和合成视频
- MediaMuxer和MediaExtractor类(音频和视频数据的混合和分离)
- Anroid中MediaMuxer,MediaCodec,MediaExtractor用例
- MediaExtractor
- Android中MediaCodec和MediaMuxer的使用
- Android中MediaMuxer和MediaCodec用例
- MediaExtractor介绍
- Android中MediaMuxer和MediaCodec用例 - audio+video
- Android中MediaMuxer和MediaCodec用例 - audio+video
- Android中MediaMuxer和MediaCodec用例 - audio+video
- Android中MediaMuxer和MediaCodec用例 - audio+video
- Android中MediaMuxer和MediaCodec用例 - audio+video
- Android在MediaMuxer和MediaCodec录制视频示例 - audio+video
- Android中MediaMuxer和MediaCodec用例 - audio+video
- ReentrantLock实现原理
- No validator could be found for type: java.lang.Double
- lintcode 跳跃游戏(116)
- Java List的ArrayList实现
- MAC瘦身,XCODE手动清理
- MediaMuxer和MediaExtractor
- 日志-syslog系统日志
- wait,notify,notifyAll详细介绍
- Ural 2070 Interesting Numbers
- 常用的邮箱服务器(SMTP、POP3)地址、端口
- 自己编写的数据仓库梳理工具,不知道还需要什么功能,求指教
- JVM内存区域划分Eden Space、Survivor Space、Tenured Gen,Perm Gen解释
- 大数据学习线路
- JVM类加载器