最近项目中需要录制Mp3文件,但是大家都知道Mp3文件Android原生是不支持录制的,所以我用到了Lame库进行将原始音频PCM数据边录边转,不多BB,先上图。

大体实现逻辑如下:

音频相关概念:

       PCM:最为原始的一种格式,PCM 数据是音频的裸数据格式,不经过任何压缩。

       MP3:全称MPEG Audio Layer3,是一种高效的计算机音频编码方案,它以较大的压缩比(1:10至1:12)将音频文件转换成较小的扩展名为.mp3的文件,且能基本保持原文件的音质。

       Lame:是Mike Cheng于1998年发起的一个开源项目,是目前最好的MP3编码引擎。Lame编码出来的MP3音色纯厚、空间宽广、低音清晰、细节表现良好,它独创的心理音响模型技术保证了CD音频还原的真实性,配合VBR和ABR参数,音质几乎可以媲美CD音频,但文件体积却非常小。

       PCM转Mp3:需要借助JNI来调用Lame的C语言代码,实现音频格式的转化。

       采样率:每秒从连续信号中提取并组成离散信号的采样个数,采样率和文件大小成正比。

 

  * 8,000 Hz - 电话所用采样率, 对于人的说话已经足够;;
  * 11,025 Hz;
  * 22,050 Hz - 无线电广播所用采样率;
  * 32,000 Hz - miniDV 数码视频 camcorder、DAT (LP mode)所用采样率;
  * 44,100 Hz - 音频 CD, 也常用于 MPEG-1 音频(VCD, SVCD, MP3)所用采样率;

采样位宽:采样值用多少位0和1来表示,也叫采样精度,用的位数越多就越接近真实声音。如用8位表示,采样值取值范围就是-128 ~ 127,如用16位表示,采样值取值范围就是-32768 ~ 32767。

码率 = 采样频率 * 采样位数 * 声道个数;  码率跟文件大小成正比。

 

Lame库介绍:

    init(int inSampleRate, int outChannel, int outSampleRate, int outBitrate, int quality);   //inSampleRate:输入采样率   outChannel:输入声道数   outSampleRate:输出采样率   outBritrate:位宽   quality:MP3音频质量。0~9。 其中0是最好,非常慢,9是最差,推荐7
    encode(short[] buffer_l, short[] buffer_r, int samples, byte[] mp3buf);  //bufferLeft : 左声道数据   bufferRight:右声道数据  samples :每个声道输入数据大小   mp3buf :用于接收转换后的数据。7200 + (1.25 * buffer_l.length)
    flush(byte[] mp3buf);  //将MP3结尾信息写入buffer中。传入参数:mp3buf至少7200字节。这里还是用以前定义的mp3buf来传入,避免创建过多的数组。
    close();  //关闭释放Lame

 

Mp3编码流程:

  1. 创建AudioRecord对象,设置采样率、采样位宽,获取缓冲区通过AudioRecord.getMinBufferSize方法可以获取到合适的最小缓冲区。
  2. 开启录制audioRecord.startRecording(),循环读取录制数据通过audioRecord.read方法,然后往Mp3编码线程中实时写入读取到的数据。
  3. MP3线程利用生产者消费者模式实时获取到数据,并且调用lame库的encode方法进行编码,并且将编码完成后的数据写入文件。
  4. 录制完成后,调用lame库中的flush方法进入MP3尾信息。

 

 

文件大小与参数对比

采样率(KHz) 

采样位宽(bit)

时长(分)

文件大小

 声音质量

8 8 5 300KB 电话
8 16 5 600KB 电话
16 8 5 300KB 无线电广播
16 16 5 600KB 无线电广播
44.1 8 5 1.2MB CD音质
44.1 16 5 1.2MB CD音质

结论:最优为采样率16KHz,采样位宽8bit,1秒1KB数据。

 

完整项目下载地址:https://github.com/liweidong93/Mp3Encoder

下载即用!!!!

 

 

更多相关文章

  1. 一句话锁定MySQL数据占用元凶
  2. 用srec库实现普通话语音识别
  3. Android自定义适配器---实现简单文件管理器
  4. Android(安卓)对于MVVM模式的理解
  5. 实现 Android(安卓)应用在开机时自启动
  6. android中的解析
  7. 解析Android(安卓)Studio创建的第一个Android(安卓)TV项目
  8. Anroid ListView分组和悬浮Header实现
  9. [置顶] android 多媒体和相机详解三

随机推荐

  1. hzjs颠覆jquery,按照中国人思维开发的最简
  2. 百度搜索功能
  3. 如何检查不包含提交按钮的HTML5表单的有
  4. 为什么不调用我的jQuery.get()回调?
  5. 如何在我的页面上以漂亮的格式显示JSON对
  6. 获取Backbone Model实例的模型/类名
  7. jQuery Ajax未能调用MVC 4控制器方法。
  8. 如何在单元格中添加colspan和文本?
  9. struts2结合swfupload控件实现视频等大文
  10. 我需要提供哪些权限(如果有)我的Chrome扩展