阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680
MediaExtractor主要用于提取音视频相关信息,分离音视频。
MediaMuxer主要复用和解复用音视频。

MediaExtractor使用一般步骤

1.//设置数据源
setDataSource
2.//分离轨道
getTrackCount,getTrackFormat
3.//选择轨道
selectTrack,unselectTrack
4.//读取数据
readSampleData
5.//下一帧
advance
6.//释放
release

举例说明:

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.//添加轨道
addTrack
2.写数据
writeSampleData
3.释放
release

注意点

 buffinfo 必须设置相应的有效值,不然会引发错误//写入数据大小bufferInfo.size = readSampleDataSize;//偏移量bufferInfo.offset = 0;//是否为关键帧bufferInfo.flags = mediaExtractor.getSampleFlags();//PTS 单位为微妙,必须为递增不然会报错bufferInfo.presentationTimeUs += videoSampleTime;mediaMuxer.writeSampleData(trackIndex, buffer, bufferInfo);这里重点关注下
bufferInfo.presentationTimeUs
mediaExtractor.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,所以可以不用执行stopmediaMuxer.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();}

原文链接:https://blog.csdn.net/u012098794/article/details/55511623
阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680

多媒体系统之MediaMuxer和MediaExtractor(五)相关推荐

  1. Android音视频开发(三)——MediaExtractor和MediaMuxer的使用

    了解了音视频的编解码过程,我们接下来使用一下经常跟MediaCodec一起搭配的MediaExtractor和MediaMuxer.最后会使用一个简单的demo来了解具体了解这两个工具类的使用过程.这 ...

  2. MediaMuxer的使用

    h264与aac(不包含adts头)合成mp4. package local.asuper.localplayer.mediacodec;import android.media.MediaCodec ...

  3. Android Multimedia框架总结(二十四)MediaMuxer实现手机屏幕录制成gif图

    原址:http://blog.csdn.net/hejjunlin/article/details/53866405 前言:上篇中,介绍是用MediaMuxer与MediaExtractor进入音视频 ...

  4. Android音视频API - MediaCodec/MediaMuxer/MediaStore/MediaController等

    AudioTrack播放音频PCM.[Android] 混音器AudioMixer. MediaPlayer/MediaRecorder, AudioTrack/AudioRecorder, Medi ...

  5. 使用MediaMuxer裁剪视频

    MediaPlayer的使用 使用MediaMuxer裁剪视频 1.解封装,获取不同tracks上的format 2.配置MediaMuxer 3.向MediaMuxer中写入数据 4.释放资源 使用 ...

  6. Android视频编辑器(五)音频编解码、从视频中分离音频、音频混音、音频音量调节等

    前言 这篇博客,主要讲解的是android端的音频处理,在开发Android视频编辑器的时候,有一个非常重要的点就是音频的相关处理.比如如何从视频中分离音频(保存为mp3文件),然后分离出来的音频如何 ...

  7. Android 9 Pie

    Android 9 Pie Android 9 利用人工智能技术,让手机可以为您提供更多帮助.现在,手机变得更智能.更快,并且还可以随着您的使用进行调整. 查看新功能 确保您的应用兼容 测试您的应用与 ...

  8. Android音视频全面介绍与代码实践之音效(四)

    Android在应用层提供丰富的多媒体接口,本文主要介绍音效处理:均衡器风格.预设混响.重低音调节.音量增强.可视化动态频谱,这些音效都使用audioSessionId进行绑定.让用户可选择/设置自己 ...

  9. 探索Android 9.0 Pie新特性变更

    北京时间 8 月 7 日上午,Google 正式发布 Android 9.0 正式版系统,并宣布系统版本 Android P 被正式命名为代号「Pie」. 目前,Google 已向全球 Pixel 设 ...

最新文章

  1. 大数据WEB阶段(十二)会话技术、Cookie、Session及两者的区别
  2. nc65右键生成菜单_DbSchema生成表单和报表,原来如此简单
  3. oracle 打印值,oracle – 在SQL Developer中打印变量的值
  4. 把握本质规律——《数学之美》作者吴军
  5. 爬取 wallhaven图片到本地壁纸库
  6. 数组排序-冒泡排序和选择排序
  7. Windows任务管理器
  8. LINUX下载编译tiff
  9. 文字描边加粗_这些PPT描边字,效果好到没朋友~
  10. 周公解梦|做梦的解释|鬼压床|为什么会做梦
  11. ios客户端学习-手机屏幕尺寸
  12. python爬取网易云评论_Python - 网易云热门评论爬取
  13. app瘦身值图片压缩
  14. 常见蛋白质种类_生活中常见食物的营养学分类,以及不同食物的蛋白质含量
  15. MVC进阶学习--View和Controller之间的数据传递(一)
  16. 苹果app退款_为什么在苹果itunes store更新app不小心购买了付费项目不能退款?
  17. autocad java api_在java中实现 AutoCAD api
  18. 如何查找【期刊】IEEE transaction on XXX 相关论文
  19. 你应该掌握的浏览器相关知识
  20. 论文精读:Faster R-CNN: Towards Real-Time ObjectDetection with Region Proposal Networks

热门文章

  1. 戴尔服务器系列区别,拆解戴尔服务器,看看内部构造与普通计算机的区别
  2. 获取服务器主列表一直显示稍等,正在获取远程列表服务器信息
  3. 振铃信号、拨号音、回铃音、忙音
  4. TH-PEG-DSPE,DSPE-PEG-TH,磷脂-聚乙二醇-靶向肽TH供应
  5. 虚拟机上网设置教程之如何用固定ip虚拟机上网
  6. CMD 命令 查看进程
  7. notepad 快捷键
  8. 【MySQL】“青协”义工管理系统
  9. 顶尖交易高手六招秘笈
  10. java consumer 用法_java 中Consumer的使用