Android使用LAME Mp3编码

下载地址: LAME MP3 Encoder :: Site Map

当前最新版本是3.100源码下载后以源码方式直接引用。在工程中创建main/cpp文件夹,将源码中的libmp3lame文件夹和include文件夹下的所有.h/.c文件拷贝至cpp目录下。配置CmakeLists.txt文件。

在build.gradle中配置时需要添加CFLAG 编译时参数 STDC_HEADERS,否则会在编译期间报错

/cpp/lame/psymodel.c:2164: undefined reference to `bcopy'
CMakeFiles/lamer.dir/lame/quantize.c.o:/cpp/lame/quantize.c:1287: more undefined references to `bcopy' follow

因此额外添加:

externalNativeBuild {
    cmake {
        cFlags '-DSTDC_HEADERS'
    }
}

 至此,LAME mp3编码库导入完成,可以开始编码开发工作。

整体分为四个阶段: 初始化,编码,刷新缓存,销毁。

1. 初始化

mLameClient = lame_init();
lame_set_in_samplerate(mLameClient, sample_rate);
lame_set_out_samplerate(mLameClient, sample_rate);
lame_set_num_channels(mLameClient, 1);
lame_set_brate(mLameClient, 32);
lame_set_quality(mLameClient, 7);
lame_init_params(mLameClient);
  • in_samplerate: 输入采样率,默认44100HZ, 应该使用AudioRecord时设置的采样率。
  • out_samplerate: 输出采样率,默认是0,LAME支持的输出频率有限包括:
*  MPEG1    32, 44.1,   48khz
*  MPEG2    16, 22.05,  24
*  MPEG2.5   8, 11.025, 12

MP3全称是MPEG-1 audio layer3

MPEG-1音频分为3层,分别是MPEG-1 Layer1/2/3,高层兼容低层,第三层协议被称为MPEG-1 Layer3,简称MP3,2017年MP3专利过期已无专利保护任何人都可使用,已经成为主流的音频压缩技术。压缩近10倍,适合网络传输。

因此这里输出频率定义为44100HZ即可。

  • num_channels: 输入流的声道数,最多支持2个声道,默认为2。根据AudioRecord采样时的设置即可,
  • brate: 在CBR模式下有效。bitrate与compress ratio功能相同,仅设置一个就行,compression默认的压缩率是11.025。
  • quality: 影响压缩算法,值范围为0-9, 0质量最好速度最慢,9质量最差速度最快。源码建议:3 near-best quality, not too slow; 5 good quality, fast; 7 ok quality, really fast。根据场景选择。
  • mode: 模式。立体声或者单声道。默认不设置和输入声道保持一致。
  • VBR:  默认是CBR。VBR是动态码率,适合于本地播放,根据编码内容的复杂程度动态的分配比特,因此输出质量比较高;CBR是静态码率,比特率在流处理过程中保持恒定一致,质量比变化比较明显;vbr_off代表设置为cbr,vbr_mrth代表设置为vbr。其他参数可见代码注释。

2. 编码

int lame_encode_buffer(lame_global_flags * gfp,
   const short int pcm_l[], const short int pcm_r[], const int nsamples,
   unsigned char *mp3buf, const int mp3buf_size)

pcm_l: 左声道数据,short数组

pcm_r: 右声道数据,short数组

nsmples: 数组长度,如果是单声道,即对应的short数组的长度

mp3Buf: 编码结果返回的数组,使用单字节长度容器装载。

mp3buf_size: 编码结果返回的数组长度,源码中有建议给出

mp3buffer_size in bytes = 1.25*num_samples + 7200。

3.刷新缓存

在编码结束之后,需要刷新编码器的缓冲到mp3文件中。

int
lame_encode_flush(lame_global_flags * gfp, unsigned char *mp3buffer, int mp3buffer_size)

 4.关闭

int
lame_close(lame_global_flags * gfp)

以上即LAME编码mp3的步骤。

我在项目中使用方式是边录边编码的方式,通过AudioRecord获取到PCM数据,立刻通知编码器进行编码输出到文件中。有两个重要的点:

1. 如何通知给编码器。 编码和录音运行在不同的线程中,如果编码时机不对会造成遗漏数据的问题,因此采用阻塞队列的方式,在录音线程开始前即启动编码线程,在编码线程中从阻塞队列中读取数据,如果没有数据则阻塞等待,录音线程获取到数据后给队列添加数据编码线程开始处理。即保证了处理的及时性,也没有耗费CPU资源。

2. 传递给LAME的PCM数据大小。有可能在录音阶段获取的是byte数组,需要专为short数组,此时可以使用ByteBuffer转换。在判断是大端序还是小端序时,调用ByteBuffer#nativeOrder即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值