很早以前收藏的一篇文章,本想再访问原作者的blog,好像涉嫌违规被关了,只得遗憾了,不过还好是收藏了,此前在总结多媒体框架时,MediaCodeC作为编解码的重要角色,一起看下今天Android MediaCodec实现多段音视频的截取与拼接。

视音频编辑中,对多段媒体素材进行截取和拼接是非常常见的操作。截取和拼接实际上是对媒体文件数据重新进行组合的过程。

要实现这些功能,就需要对媒体文件进行编解码操作,即先解码要处理的媒体文件数据,然后再按照某种规则对这些数据进行编码,以生成我们所需的目标。

Android提供的MediaCodec及其相关类为我们提供了所需的方法,这些类主要包括:MediaCodec、MediaExtractor、MediaMuxer、MediaFormat。

MediaCodec用于创建视音频编解码器,通过它可以对视音频数据进行编解码操作,它是编解码功能的核心类。

MediaExtractor相当于一个reader,它用于读取媒体文件,并提取出其中的视音频数据。

MediaMuxer相当于一个writer,它用于将内存中的视音频数据写到文件中。

MediaFormat即媒体格式类,它用于描述媒体的格式参数,如视频帧率、音频采样率等。

对视音频文件进行截取与拼接的主要过程是:先创建视音频编解码器,再分别启动视频线程和音频线程,以分别对视音频数据进行解码、编码,最后将编码好的数据写入文件。

主要逻辑如下,关键是三处线程同步的地方,具体原因稍后解释。

再来了解一下这几个类的“脾气”。

一般用MediaCodec创建编解码器时,使用的都是createDecoderByType方法,但在用三星PAD(API LEVEL 18, Android version 4.3)调试时发现,调用该方法创建音频编码器时会出错。故改为使用createByCodecName("OMX.SEC.aac.enc")创建音频编码器。估计这是一个API bug。

configure decoder时,第一个格式参数要与源的格式相同,这里可以先通过extractor将源的格式读出来,再直接传给configure方法。configure encoder时,需设定几个必要的参数,具体请参考官方说明。

当把全部要处理的数据灌给编解码器后,使用queueInputBuffer(inputBufIndex,0, 0, 0L, MediaCodec.BUFFER_FLAG_END_OF_STREAM)方法来通知编解码器结束工作。之后,在OutputBuffer的bufferInfo中,将携带这个标志,通过判断是否有这个标志,我们就可以断定数据是否都已处理完成,以进行后续操作。再之后,dequeueOutputBuffer的返回都将是INFO_TRY_AGAIN_LATER。当然,如果你自己有办法在OutputBuffer中判断数据是否灌完,也可以不使用此标志。

当数据灌完后,要使用releaseOutputBuffer,把缓冲区释放掉。否则,你会发现queueInputBuffer总是返回-1,因为没有空闲的缓冲区了。

MediaExtractor用来读取源文件,给定文件路径后,便可将其中的视音频数据拿出来。关键是它的seekTo方法,它用于对读取数据的游标进行定位,可以定位到指定点前的最后一个sync点、指定点后的第一个sync点,或者与指定点最近的sync点。对于H.264数据,sync点可以认为是视频关键帧的时码位置。

MediaMuxer的使用非常简单,先创建,再添加视音频轨,然后start,再writeSampleData,最后stop。需要注意的是,必需先添加完所有的视音频轨后,再去start,而不能先start,再试图去addTrack,否则会出错。这也是为什么在本文的逻辑中,视频线程需要去wait音频线程添加完音频轨后再继续的原因。

需要注意的是,不能在启动完编解码器后,立即调用getOutputFormat企图addTrack,而应该在dequeueOutputBuffer后的INFO_OUTPUT_FORMAT_CHANGED中调用,否则会出错。

当要向文件中同时写入视频和音频数据时,必需先writeSampleData所有视频数据,再写音频数据,或者反之,即二者必需连续调用writeSampleData,不能交叉调用,否则写出的文件会有问题。这也是本文中为何muxer启动后,音频线程需等待视频线程先写完数据,自己才能继续干活的原因。

当所有的writeSampleData完成后,不要忘记调用stop和release,否则写出的文件也会有问题。

最后还要注意,这几个类中,时间单位都是微秒。

下面我来补充mediaCodec的支持的格式,MediaCodec更多详情,会在Camera相关框架分析中,会隆重介绍的:

MediaCodec支持的格式:

  • "video/x-vnd.on2.vp8" - VP8 video (i.e. video in .webm)

  • "video/x-vnd.on2.vp9" - VP9 video (i.e. video in .webm)

  • "video/avc" - H.264/AVC video

  • "video/mp4v-es" - MPEG4 video

  • "video/3gpp" - H.263 video

  • "audio/3gpp" - AMR narrowband audio

  • "audio/amr-wb" - AMR wideband audio

  • "audio/mpeg" - MPEG1/2 audio layer III

  • "audio/mp4a-latm" - AAC audio (note, this is raw AAC packets, not packaged in LATM!)

  • "audio/vorbis" - vorbis audio

  • "audio/g711-alaw" - G.711 alaw audio

  • "audio/g711-mlaw" - G.711 ulaw audio

第一时间获得博客更新提醒,以及更多android干货,源码分析,欢迎关注我的微信公众号,扫一扫下方二维码或者长按识别二维码,即可关注。

Android MediaCodec实现多段音视频的截取与拼接相关推荐

  1. FFmpeg Android 学习(一):Android 如何调用 FFMPEG 编辑音视频

    一.概述 在Android开发中,我们对一些音视频的处理比较无力,特别是编辑音视频这部分.而且在Android上对视频编辑方面,几乎没有任何API做支持,MediaCodec(硬编码)也没有做支持.那 ...

  2. 视频教程-Android WebRTC 实现1V1实时音视频通信-Android

    Android WebRTC 实现1V1实时音视频通信 从2012年开始从事移动互联网方面的开发工作,曾担任去哪儿网开发工程师,搜狗高级开发工程师,拥有多年一线实战开发经验. 擅长语言:Object- ...

  3. html让视频跟图片之间无缝,图片、样式、音视频之间的无缝拼接,教你一个万能方法!...

    原标题:图片.样式.音视频之间的无缝拼接,教你一个万能方法! 大家好,我是老沙. 发现没有,几乎每个品牌的公众号都开始长图排版了,长图排版最常遇到的一个问题便是缝隙.去缝的教程老沙写过不少: 关于静态 ...

  4. 作为一个Android程序员,关于音视频开发,这些你确定这些你都懂了吗

    14. 深入学习一些音视频领域的开源项目,如 webrtc,ffmpeg,ijkplayer,librtmp 等等 15. 将 ffmpeg 库移植到 Android 平台,结合上面积累的经验,编写一 ...

  5. 都2021了作为一名Android开发者,还不学音视频开发?我劝你早点认清现实!

    缘起 最近经常遇到一些同学问我如何学习音视频,怎样才能快速上手?还有一些对音视频不了解的同学问我该不该学习音视频?作为一名音视频行业的10年Android老兵,我有一些思考分享给大家,希望能对你有所帮 ...

  6. android音频杂音问题_Android 音视频去回声、降噪(Android音频采集及回音消除)(转)...

    好久没写文章了,其实是想记录一下自己在Android开发的成长历程.谈到音视频这块,对于新手来说刚接触到这一块,那是非常非常的恶心~我自己弄这一块也是从头开始,在 网上也翻阅了无数的资料.浏览了无数的 ...

  7. 某些老司机直播APP这么受欢迎?作为Android程序员如何进军音视频?

    前言 随着4g转入5g时代,音视频发展非常迅速.纵然市面上的直播软件杂乱无章,到了深夜成了老司机的福利.那么开发这些直播APP需要学习那些技术呢? 我们都知道现在Android开发的形势,或许此时可以 ...

  8. [Android多媒体技术] 播放Raw/Assets音视频方法总结

    转自:https://juejin.im/post/5bec0958e51d454c7d0f9a32 关于ijkplayer这块已验证可以播放音视频,Seek正常. 标红: 文章里RawDataSou ...

  9. android端采用FFmpeg进行音视频合成与分离

    上一篇文章谈到音频剪切.混音.拼接与转码,也详细介绍cMake配置与涉及FFmpeg文件的导入: android端采用FFmpeg进行音频混合与拼接剪切 .现在接着探讨音视频的合成与分离. 1.音频提 ...

  10. Android WebView加载H5音视频自动播放、关闭Activity停止播放

    在Android加载H5,实现H5中的音视频自动播放  在Activity中添加代码: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELL ...

最新文章

  1. matlab 数据保存为txt excel mat
  2. windows进程间通信方式总结
  3. linux 命令行模式自动登录,实现linux的自动登录--命令行模式启动
  4. myeclipse打包java文件_MyEclipse将Java项目打包成jar文件的三种方法
  5. php system startup,opencart Warning: require_once(/system/startup.php) failed to open stream
  6. JavaScript tab页
  7. idea导入java项目类上面显示红色的J符号解决办法
  8. CSS基础——盒子模型【学习笔记】
  9. 2014——我们都任性过
  10. 效果实现JS实现飞雪飘飘的效果
  11. MySQL技术内幕:InnoDB存储引擎
  12. 专注于操作系统25之软盘镜像
  13. 数据绑定之DataFormatString
  14. 基于python对B站缓存视频的批量复制,重命名
  15. SkipList A Probabilistic Alternative to Balanced Trees
  16. 推荐 10 个实用但偏执的 Java 编程技巧
  17. LSTM实现股票预测
  18. ZZNU 正约数之和
  19. 【校内test】桶哥的问题
  20. 「产品读书」增长黑客:创业公司的用户与收入增长秘籍

热门文章

  1. 一步一步打造基于TICK的工业级系统监控平台
  2. 算法面试题_求给定字符串的排列、组合、八皇后问题
  3. 论文笔记_S2D.06-2018-BMVC-用于实时语义分割的轻量级精细网络RefineNet
  4. 开源真实场景图像检测数据集汇总
  5. 一文详解3D相机面临的困难问题和解决方案
  6. 牛牛以前在老师那里得到了一个正整数数对(x, y), 牛牛忘记他们具体是多少了。 但是牛牛记得老师告诉过他x和y均不大于n, 并且x除以y的余数大于等于k。 牛牛希望你能帮他计算一共有,,,
  7. jekins构建通知邮件配置及邮件附件设置,jenkins构建通知邮件没有RF的log和report文件...
  8. MongoDB 学习笔记(一)—— 安装入门
  9. CentOS 5 全功能WWW服务器搭建全教程
  10. 【转】恢复默认vs2005