Android MediaMuxer录像(支持G711音频)
来源:互联网 发布:淘宝网男土劳动包 编辑:程序博客网 时间:2024/06/06 01:01
Android平台的MediaMuxer是个非常好的录像库,它能将H.264视频+AAC音频存储成.mp4格式的文件,而且稳定性、同步效果都非常好。
MediaMuxer在安卓版的EasyPlayer和EasyPusher都用到了该方法来进行本地录像。作者也写过两篇针对性的博客来做介绍,参考:
http://blog.csdn.net/jyt0551/article/details/60152344
http://blog.csdn.net/jyt0551/article/details/58714595
MediaMuxer的接口定义相对而言比较简单,调用过程如下图所示。
简单来说,就是创建对象、添加音视频轨道、开始、持续写入音视频数据、关闭这样一个过程。
遗憾的是,MediaMuxer并不支持对除AAC以外的音频编码格式的封装,然而在安防行业里G711音频格式的数据是大多数设备的默认编码格式。
如何支持G711格式的数据呢?其实换种思路就会豁然开朗,我们可以先把G711数据解码成PCM,再用MediaCodec编码成AAC,这样曲线存储^_^。不光是G711,所有的音频编码格式都可以这样做哈哈。。
所以前面的流程图里,writeAudioSample的部分就变成这样了:
下面是将解码后的PCM数据塞入Muxer的代码片段。
package org.easydarwin.audio;import android.media.MediaCodec;import android.media.MediaCodecInfo;import android.media.MediaFormat;import android.util.Log;import org.easydarwin.video.EasyMuxer;import java.io.IOException;import java.nio.ByteBuffer;/** * 对EasyMuxer的扩展。支持对PCM格式的音频打包。 */public class EasyAACMuxer extends EasyMuxer { MediaCodec mMediaCodec; String TAG = "EasyAACMuxer"; protected MediaCodec.BufferInfo mBufferInfo = new MediaCodec.BufferInfo(); protected ByteBuffer[] mBuffers = null; private MediaFormat mAudioFormat; public EasyAACMuxer(String path, long durationMillis) { super(path, durationMillis); } @Override public synchronized void addTrack(MediaFormat format, boolean isVideo) { super.addTrack(format, isVideo); if (!isVideo){ mAudioFormat = format; } } public synchronized void pumpPCMStream(byte []pcm, int length, long timeUs) throws IOException { if (mMediaCodec == null) {// 启动AAC编码器。这里用MediaCodec来编码 if (mAudioFormat == null) return; mMediaCodec = MediaCodec.createEncoderByType("audio/mp4a-latm"); Log.i(TAG, String.valueOf(mAudioFormat)); mAudioFormat.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm"); mAudioFormat.setInteger(MediaFormat.KEY_AAC_PROFILE,MediaCodecInfo.CodecProfileLevel.AACObjectLC); mAudioFormat.setInteger(MediaFormat.KEY_BIT_RATE, 16000);// mAudioFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 320); mMediaCodec.configure(mAudioFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); mMediaCodec.start(); mBuffers = mMediaCodec.getOutputBuffers(); } int index = 0; // 将pcm编码成AAC do { index = mMediaCodec.dequeueOutputBuffer(mBufferInfo, 1000); if (index >= 0) { if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) { continue; } if (mBufferInfo.presentationTimeUs == 0){ continue; } if (VERBOSE) Log.d(TAG,String.format("dequeueOutputBuffer data length:%d,tmUS:%d", mBufferInfo.size, mBufferInfo.presentationTimeUs)); ByteBuffer outputBuffer = mBuffers[index]; // ok,编码成功了。将AAC数据写入muxer. pumpStream(outputBuffer, mBufferInfo, false); mMediaCodec.releaseOutputBuffer(index, false); } else if (index == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { mBuffers = mMediaCodec.getOutputBuffers(); } else if (index == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { Log.v(TAG, "output format changed..."); MediaFormat newFormat = mMediaCodec.getOutputFormat(); Log.v(TAG, "output format changed..." + newFormat); } else if (index == MediaCodec.INFO_TRY_AGAIN_LATER) { Log.v(TAG, "No buffer available..."); } else { Log.e(TAG, "Message: " + index); } } while (index >= 0 && !Thread.currentThread().isInterrupted()); final ByteBuffer[] inputBuffers = mMediaCodec.getInputBuffers(); do { index = mMediaCodec.dequeueInputBuffer(1000); if (index >= 0) { inputBuffers[index].clear(); inputBuffers[index].put(pcm, 0, length); if (VERBOSE) Log.d(TAG,String.format("queueInputBuffer pcm data length:%d,tmUS:%d", length, timeUs)); mMediaCodec.queueInputBuffer(index, 0, length, timeUs, 0); } } while (!Thread.currentThread().isInterrupted() && index < 0); } @Override public synchronized void release() { if (mMediaCodec != null) mMediaCodec.release(); mMediaCodec = null; super.release(); }}
一切都在代码中,不再过多解释,至此结束。
阅读全文
0 0
- Android MediaMuxer录像(支持G711音频)
- EasyPlayer实现Android MediaMuxer录像MP4(支持G711/AAC/G726音频)
- 音频:G711
- Android G711(PCMA/PCMU)、G726、PCM音频转码到AAC
- G711 G729音频编码总结
- hi3518e音频G711调试笔记
- G711格式音频编解码
- android Http Post上传数据(图片、录像及音频等)
- Android学习笔记(二)---Mediaplayer、关于视频,音频,录像,录音
- MediaMuxer和MediaExtractor类(音频和视频数据的混合和分离)
- Android音视频处理之MediaMuxer(MP4)
- Android中如何提取和生成mp4文件(MediaMUxer)
- Android G711编解码
- AVI文件中封装G711音频
- android音频支持的格式
- g711
- G711
- android 录像
- cordova 跨平台初探
- 利用ScheduledThreadPoolExecutor定时执行任务
- MVC 和 MVP 的对比
- 工厂模式从无到有
- 【文本超出显示为省略号】
- Android MediaMuxer录像(支持G711音频)
- 常用 Android 开发者选项与卡顿原因
- tensorflow框架基础之损失函数
- 1
- AR移动应用开发(二) Unity工程嵌入Android
- 2
- Cookie
- Linux下使用f.lux软件
- 【Java集合源码剖析】ArrayList源码剖析