Android 音视频开发(七): 音视频录制流程总结
在前面我们学习和使用了AudioRecord、AudioTrack、Camera、MediaExtractor、MediaMuxer API、MediaCodec。 学习和使用了上述的API之后,相信对Android系统的音视频处理有一定的经验和心得了。本文及后面的几篇文章做的事情就是将这些知识串联起来,做一些稍微复杂的事情。
一、流程分析
1.1 需求说明
我们需要做的事情就是:串联整个音视频录制流程,完成音视频的采集、编码、封包成 mp4 输出。
1.2 实现方式
Android音视频采集的方法:预览用SurfaceView,视频采集用Camera类,音频采集用AudioRecord。
1.3 数据处理思路
使用MediaCodec 类进行编码压缩,视频压缩为H.264,音频压缩为aac,使用MediaMuxer 将音视频合成为MP4。
二、 实现过程
2.1 收集Camera数据,并转码为H264存储到文件
在收集数据之前,对Camera设置一些参数,方便收集后进行数据处理:
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewFormat(ImageFormat.NV21);
parameters.setPreviewSize(1280, 720);
然后设置PreviewCallback:
camera.setPreviewCallback(this);
就可以获取到Camera的原始NV21数据:
onPreviewFrame(byte[] bytes, Camera camera)
在创建一个H264Encoder类,在里面进行编码操作,并将编码后的数据存储到文件:
new Thread(new Runnable() { @Override
public void run() {
isRuning = true;
byte[] input = null;
long pts = 0;
long generateIndex = 0; while (isRuning) {
if (yuv420Queue.size() > 0) {
input = yuv420Queue.poll();
byte[] yuv420sp = new byte[width * height * 3 / 2];
// 必须要转格式,否则录制的内容播放出来为绿屏
NV21ToNV12(input, yuv420sp, width, height);
input = yuv420sp;
}
if (input != null) {
try {
ByteBuffer[] inputBuffers = mediaCodec.getInputBuffers();
ByteBuffer[] outputBuffers = mediaCodec.getOutputBuffers();
int inputBufferIndex = mediaCodec.dequeueInputBuffer(-1);
if (inputBufferIndex >= 0) {
pts = computePresentationTime(generateIndex);
ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
inputBuffer.clear();
inputBuffer.put(input);
mediaCodec.queueInputBuffer(inputBufferIndex, 0, input.length, System.currentTimeMillis(), 0);
generateIndex += 1;
} MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, TIMEOUT_USEC);
while (outputBufferIndex >= 0) {
ByteBuffer outputBuffer = outputBuffers[outputBufferIndex];
byte[] outData = new byte[bufferInfo.size];
outputBuffer.get(outData);
if (bufferInfo.flags == MediaCodec.BUFFER_FLAG_CODEC_CONFIG) {
configbyte = new byte[bufferInfo.size];
configbyte = outData;
} else if (bufferInfo.flags == MediaCodec.BUFFER_FLAG_SYNC_FRAME) {
byte[] keyframe = new byte[bufferInfo.size + configbyte.length];
System.arraycopy(configbyte, 0, keyframe, 0, configbyte.length);
System.arraycopy(outData, 0, keyframe, configbyte.length, outData.length);
outputStream.write(keyframe, 0, keyframe.length);
} else {
outputStream.write(outData, 0, outData.length);
} mediaCodec.releaseOutputBuffer(outputBufferIndex, false);
outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, TIMEOUT_USEC);
} } catch (Throwable t) {
t.printStackTrace();
}
} else {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} // 停止编解码器并释放资源
try {
mediaCodec.stop();
mediaCodec.release();
} catch (Exception e) {
e.printStackTrace();
} // 关闭数据流
try {
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
当结束编码的时候,需要将相关的资源释放掉:
// 停止编解码器并释放资源
try {
mediaCodec.stop();
mediaCodec.release();
} catch (Exception e) {
e.printStackTrace();
} // 关闭数据流
try {
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
此时,我们做到了将视频内容采集-->编码-->存储文件。但这个仅仅是对Android 音视频开发(四):使用 Camera API 采集视频数据的延伸,但是很有必要。因为在前面学习了如何采集音频,如何使用MediaCodec去处理音视频,如何使用MediaMuxer去混合音视频。
示例代码:https://github.com/renhui/AndroidRecorder/releases/tag/only_h264_video
下面我们在当前的的基础上继续完善,即将音视频采集并混合为音视频。
2.2 音视频采集+混合,存储到文件
基本完成思路已经在2.1的结尾处坐了说明,下面贴一下demo的链接:
示例代码:https://github.com/renhui/AndroidRecorder/releases/tag/h264_video_audio
想做更多的事情,只有学习了OpenGL之后才能继续了。录制音视频的学习先到此为止了。
Android 音视频开发(七): 音视频录制流程总结的更多相关文章
- Android Camera系列开发 (二)通过Intent录制视频
Android Camera系列开发 (二)通过Intent录制视频 作者:雨水 2013-8-18 CSDN博客:http://blog.csdn.net/gobitan/ 概述 使用Camera ...
- 【Android 直播软件开发:音视频硬解码篇】
开篇 炙手可热,望而生畏的音视频开发 时至今日,短视频App可谓是如日中天,一片兴兴向荣.随着短视频的兴起,音视频开发也越来越受到重视,但是由于音视频开发涉及知识面比较广,入门门槛相对较高,让许许多多 ...
- Android Studio 集成开发工具教学视频
简介 经过2年时间的研发,Google终于正式发布了面向Android开发者的集成开发环境Android Studio 1.2(稳定版).Android Studio是Google开发的一款面向And ...
- Android 音视频开发学习思路
Android 音视频开发这块目前的确没有比较系统的教程或者书籍,网上的博客文章也都是比较零散的.只能通过一点点的学习和积累把这块的知识串联积累起来. 初级入门篇: Android 音视频开发(一) ...
- 转:Android IOS WebRTC 音视频开发总结 (系列文章集合)
随笔分类 - webrtc Android IOS WebRTC 音视频开发总结(七八)-- 为什么WebRTC端到端监控很关键? 摘要: 本文主要介绍WebRTC端到端监控(我们翻译和整理的,译 ...
- Android音视频开发(1):H264 基本原理
前言 H264 视频压缩算法现在无疑是所有视频压缩技术中使用最广泛,最流行的.随着 x264/openh264 以及 ffmpeg 等开源库的推出,大多数使用者无需再对H264的细节做过多的研究,这大 ...
- Android WebRTC 音视频开发总结
www.cnblogs.com/lingyunhu/p/3621057.html 前面介绍了WebRTCDemo的基本结构,本节主要介绍WebRTC音视频服务端的处理,,转载请说明出处(博客园RTC. ...
- Android 音视频开发(一):PCM 格式音频的播放与采集
什么是 PCM 格式 声音从模拟信号转化为数字信号的技术,经过采样.量化.编码三个过程将模拟信号数字化. 采样 顾名思义,对模拟信号采集样本,该过程是从时间上对信号进行数字化,例如每秒采集 44100 ...
- Android音视频之MediaRecorder音视频录制
前言: 公司产品有很多地方都需要上传音频视频,今天抽空总结一下音频视频的录制.学习的主角是MediaRecorder类. MediaRecorder类介绍: MediaRecorder类是Androi ...
随机推荐
- IntelliJ IDEA安装ideaIU-2019.1
- ConditionalOnBean 与 ConditionalOnMissingBean 的正确玩法
之前看到这篇博客,写ConditionalOnClass的用法,自己实践了一下,感觉有点问题,原文如下: https://blog.csdn.net/lucyTheSlayer/article/det ...
- James Munkres Topology: Sec 22 Exer 3
Exercise 22.3 Let \(\pi_1: \mathbb{R} \times \mathbb{R} \rightarrow \mathbb{R}\) be projection on th ...
- 星环大数据安全组件Guardian与hadoop自带的安全组件区别
在进行讲解之前,先带大家学习下hadoop关于hdfs自己的安全如何实现的--------------------------- 名词: ACL-访问控制列表(Access Control List, ...
- Tomcat映射路径
打开tomcat安装包,在config目录下修改server.xml文件: 在<Host>标签中添加: <Context path="" docBase=&quo ...
- python3_list
name = ['like','new','book',['fa','fdsa'],'new','book','why']#这是个列表 print(name)#把列表打印出来 查 print(name ...
- linux环境下安装tcping工具测试访问超时
wget https://sources.voidlinux.eu/tcping-1.3.5/tcping-1.3.5.tar.gz tar zxvf tcping-1.3.5.tar.gz cd t ...
- tp5 mkdir(): Permission denied 问题
今天使用tp5 线上上传图片的时候遇到了一个问题 mkdir(): Permission denied 如图 百度了一下 发现大家都说 chmod -R 777 runtime 能解决问题 尝试了一下 ...
- [Union]C++中Union学习笔记
C++ union结构式一种特殊的类.它能够包含访问权限.成员变量.成员函数(可以包含构造函数和析构函数).它不能包含虚函数和静态数据变量.它也不能被用作其他类的基类,它本身也不能有从某个基类派生而来 ...
- 微信小程序 + nodeJs(loopback) 实现支付
实现小程序的支付,首先需要去微信官网先了解一下微信小程序支付相关接口文档:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter= ...