基于FFmpeg的音频编码(PCM数据编码成AAC android)
概述
详细
之前做的一个demo,Android录音获取pcm数据(音频原始数据),然后利用 FFmpeg将PCM数据编码成AAC。
一、准备工作
开发环境
jdk1.8
Eclipse Luna Service Release 1 (4.4.1)
运行环境:
华为荣耀6(Android4.4)、华为p9(Android7.0)
二、程序实现
代码截图如下:

该demo依赖v7包。
FFAacEncoderDemo工程src目录
MainActivity.java是主界面,用来控制录音开始和结束。
FFAacEncoder.java时native方法,用来和jni通信。
jni目录:
include目录下是FFmpeg的一些.h文件
libs目录下是FFmpeg编译的so
AacCoderc 音频编码
cn_vn_aacEncoder_jni_FFAacEncoderJni jni代码与java通信。
1 录音(获取pcm数据)
开始录音
private void startRecord(){
Log.i(TAG, "startRecord mIsRecording="+mIsRecording);
if(!mIsRecording){
mIsRecording = true;
synchronized (mLock) {
mAudioRecordGetExit = false;
}
//初始化ffmpeg 编码器
mFFAacEncoderJni.start();
//创建录音线程、开始录音
mAudioRecordGetThread = new Thread(new AudioRecordGet());
mAudioRecordGetThread.start();
}
}
关闭录音
private void stoptRecord(){
if(mIsRecording){
synchronized (mLock) {
mAudioRecordGetExit = true;
}
mIsRecording = false;
}
}
具体录音通过使用AudioRecord。
private class AudioRecordGet implements Runnable{
private AudioRecord mAudioRecord;
private static final boolean PCM_DUMP_DEBUG = true;
private static final boolean AAC_DUMP_DEBUG = false;
private int mAudioSource = MediaRecorder.AudioSource.MIC;
//采样频率,采样频率越高,音质越好。44100 、22050、 8000、4000等
private int mSampleRateHz = 8000;
//MONO为单声道 ,STEREO为双声道
private int mChannelConfig = AudioFormat.CHANNEL_IN_MONO;
//编码格式和采样大小,pcm编码;支持的采样大小16bit和8bit,采样大小越大,信息越多,音质越好。
private int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
//该size设置为AudioRecord.getMinBufferSize(mSampleRateHz, mChannelConfig, mAudioFormat); 编码aac时会失败。
private int mBufferSizeInBytes = 2048;//AudioRecord.getMinBufferSize(mSampleRateHz, mChannelConfig, mAudioFormat);
private AudioPCMData mAudioPCMData;
public AudioRecordGet() {
Log.i(TAG, "AudioRecordGet ");
mAudioPCMData = new AudioPCMData(mBufferSizeInBytes);
mAudioRecord = new AudioRecord(mAudioSource,
mSampleRateHz, mChannelConfig, mAudioFormat, mBufferSizeInBytes);
Log.i(TAG,"mBufferSizeInBytes="+mBufferSizeInBytes);
}
@Override
public void run() {
mAudioRecord.startRecording();
FileOutputStream outPCM = null;
try {
if (PCM_DUMP_DEBUG) {
String File = "/sdcard/test.pcm";
outPCM = new FileOutputStream(File);
}
} catch (Exception e) {
e.printStackTrace();
}
for(;;){
synchronized (mLock) {
if(mAudioRecordGetExit){
break;
}
}
//读取录音数据
int readSize = mAudioRecord.read(mAudioPCMData.mData, 0, mBufferSizeInBytes);
if (AudioRecord.ERROR_INVALID_OPERATION != readSize) {
if (PCM_DUMP_DEBUG && null != outPCM) {
try {
outPCM.write(mAudioPCMData.mData, 0, readSize);
} catch (Exception e) {
e.printStackTrace();
}
}
mAudioPCMData.mFrameSize = readSize;
Log.i(TAG, "audio pcm size="+readSize);
//设置pcm数据,进行aac编码
mFFAacEncoderJni.setPcmData(mAudioPCMData.mData, readSize);
}
}
if(PCM_DUMP_DEBUG && null != outPCM){
try {
outPCM.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//停止录音、释放
mAudioRecord.stop();
mAudioRecord.release();
//停止音频编码
mFFAacEncoderJni.stop();
Log.i(TAG,"AudioRecordGet thread exit success");
}
}
2 PCM编码成AAC
1 初始化编码器
public class FFAacEncoder {
private String TAG = "FFAacEncoder java";
//load .so
static{
System.loadLibrary("avcodec-57");
System.loadLibrary("avdevice-57");
System.loadLibrary("avfilter-6");
System.loadLibrary("avformat-57");
System.loadLibrary("avutil-55");
System.loadLibrary("postproc-54");
System.loadLibrary("swresample-2");
System.loadLibrary("swscale-4");
System.loadLibrary("aacEncoder");
}
private int mNativeContext = 0;
//初始化编码器
private native final void nativeStart();
//对pcm数据进行编码
private native final void nativeSetPcmData(byte[] pcm, int len);
//必要的清理
private native final void nativeStop();
public void start(){
nativeStart();
}
public void setPcmData(byte[] pcm, int len){
nativeSetPcmData(pcm, len);
}
public void stop(){
nativeStop();
}
}
调用nativeStart方法。
2 音频编码
//设置pcm数据,进行aac编码
mFFAacEncoderJni.setPcmData(mAudioPCMData.mData, readSize);
调用nativeSetPcmData
C++层代码,通过编码获取的AAC原始数据不同播放(存储在/sdcard/test.aac文件中,不能播放),
需要添加adts header(不懂的可以了解一下AAC格式),这样才可以正常播放。/sdcard/adts.aac该文件添加了header,可以正常播放。
三、运行效果
运行效果:

运行结果将生成文件 /sdcard/test.aac

四、其他补充
博客地址:http://blog.csdn.net/vnanyesheshou/article/details/54560684
注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权
基于FFmpeg的音频编码(PCM数据编码成AAC android)的更多相关文章
- 最简单的基于FFMPEG的音频编码器(PCM编码为AAC)
http://blog.csdn.net/leixiaohua1020/article/details/25430449 本文介绍一个最简单的基于FFMPEG的音频编码器.该编码器实现了PCM音频采样 ...
- 最简单的基于FFmpeg的移动端样例附件:Android 自带播放器
===================================================== 最简单的基于FFmpeg的移动端样例系列文章列表: 最简单的基于FFmpeg的移动端样例:A ...
- FFmpeg(11)-基于FFmpeg进行音频重采样(swr_init(), swr_convert())
一.包含头文件和库文件 修改CMakeLists # swresample add_library(swresample SHARED IMPORTED) set_target_properties( ...
- 最简单的基于FFMPEG+SDL的音频播放器 ver2 (采用SDL2.0)
===================================================== 最简单的基于FFmpeg的音频播放器系列文章列表: <最简单的基于FFMPEG+SDL ...
- 最简单的基于FFMPEG+SDL的音频播放器 ver2 (採用SDL2.0)
===================================================== 最简单的基于FFmpeg的音频播放器系列文章列表: <最简单的基于FFMPEG+SDL ...
- [总结]FFMPEG视音频编解码零基础学习方法--转
ffmpeg编解码学习 目录(?)[-] ffmpeg程序的使用ffmpegexeffplayexeffprobeexe 1 ffmpegexe 2 ffplayexe 3 ffprobeexe ...
- FFMPEG视音频编解码零基础学习方法
在CSDN上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的初学者.在和大家探讨的过程中,我忽然发现了一个问题:在“ ...
- FFMPEG视音频编解码零基础学习方法-b
感谢大神分享,虽然现在还看不懂,留着大家一起看啦 PS:有不少人不清楚“FFmpeg”应该怎么读.它读作“ef ef em peg” 0. 背景知识 本章主要介绍一下FFMPEG都用在了哪里(在这里仅 ...
- [总结]FFMPEG视音频编解码零基础学习方法
在CSDN上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的初学者.在和大家探讨的过程中,我忽然发现了一个问题:在“ ...
随机推荐
- ios 重用UI部分代码的好方法(再也不用为局部变量的命名而烦恼啦!)
重用控件类代码的一个非常好的解决方案:所有一样的控件其名字均用同样的一个名字.只是在最后赋值的时候,将创建好的控件赋给我们需要用到的那个控件. - (id)initWithFrame:(CGRect) ...
- 使用Dictionary泛型集合封装业务逻辑判断 z
C#2.0 提供了Dictionary 泛型类,它提供了从一组键到一组值的映射.字典中的每个添加项都由一个值及其相关联的键组成.通过键来检索值的速度是非常快的,接近于 O(1),这是因为 Dictio ...
- myql --- mysqldump使用方法
1.mysqldump的几种常用方法: (1)导出整个数据库(包括数据库中的数据) mysqldump -u username -p dbname > dbname.sql (2)导出数据库结构 ...
- VMware+Windgb+Win7内核驱动调试
com1被占用了,需要用com2
- mysqld_safe脚本执行的基本流程
mysqld_safe脚本执行的基本流程:1.查找basedir和ledir.2.查找datadir和my.cnf.3.对my.cnf做一些检查,具体检查哪些选项请看附件中的注释.4.解析my.cnf ...
- Facebook 工程师是如何高效工作的?
编者按:Facebook 的工程师有哪些高效工作的经验呢?软件工程师访谈了多位 Facebook 的高产工程师,总结了他们的共同经验以及晋级之路,供各位参考. 成为高效开发者这件事你可以通过经验.书本 ...
- HBase目录
1. HBase介绍及简易安装(转) 2. java操作Hbase实例 3. HBase入门基础教程之单机模式与伪分布式模式安装(转) 4. HBase教程 5. 用Java操纵HBase数据库(新建 ...
- 充满未来和科幻的界面设计FUI在国内还没有起步在国外早起相当成熟
所谓FUI可以是幻想界面(Fantasy User Interfaces).科幻界面(Fictional User Interfaces).假界面(Fake User Interfaces).未来主义 ...
- 跨平台app开发(引擎)工具的选择【转】
跨平台app开发(引擎)工具的选择 1.html5执行速度慢,用户体验不好 2.原生应用开发,即ios和安卓分别开发,需要两种技术人员,后期代码维护困难,很难达到统一. 3.xamarin是一款c#的 ...
- 2013年度最新最佳CSS网页设计实例
CSS在网页设计中扮演着举足轻重的角色,尤其是CSS3和HTML5的出现,让我们更加相信CSS能给我们带来无限的遐想和强有力的视觉冲击.今天我要给大家推荐几个最新CSS佳作,虽然本人没有设计头脑,但还 ...