前面介绍过给PCM录音加44个字节头转为wav格式,从而能让普通播放器进行播放。wav格式有一个比较明显的缺点就是数据比较大,因为它是没有压缩过的。一般开发手机上的app,数据流量和优化是要经常考虑的问题,因此如果你需要将录音上传到服务器上,还有能够让普通的播放器播放的话,压缩成mp3是比较好的解决方案,下面就介绍一下如何用lamemp3这个库进行压缩。
1. 到网上去下载lame库,这个就不介绍了,搜索一下就搞定了,或者直接用我附件Demo中的库也可以。
2. 将lamemp3 Add到你的项目中。
3. 在你的源文件中导入lame.h。
4. 设置压缩的参数,这些参数根据自己的需要进行调整:
// 全局指针
lame_t lame;
// mp3压缩参数
lame = lame_init();
lame_set_num_channels(lame, 1); // 单声道
lame_set_in_samplerate(lame, 16000);// 16K采样率
lame_set_brate(lame, 128);// 压缩的比特率为128K
lame_set_mode(lame, 1);
lame_set_quality(lame, 2);
lame_init_params(lame);
5. 调用lame_encode_buffer这个函数进行压缩,这个函数有很多参数,下面一一说明一下:
第一个参数lame_global_flags * gfp,就是我们之前声明的全局指针,即lame
第二个参数const short int pcm_l[],short类型的录音数据,这里表示的是左声道
第三个参数const short int pcm_r[],short类型的录音数据,这里表示的是右声道
说明:把这两个参数都设置为你要压缩的录音数据即可
第四个参数unsigned char *mp3buf,存放压缩完后数据的缓冲区,注意是unsigned char *类型
第五个参数constint mp3buf_size,缓冲区的长度
我们得到的录音数据是byte类型的,首先要将它转换为short类型,由于一个short是两个byte,长度要减半
short *recordingData = (short *)audioData.bytes;
int pcmLen = audioData.length;
int nsamples = pcmLen / 2;
声明一个用来存放压缩后数据的缓冲区,长度就设置为pcmLen即可
unsigned char buffer[pcmLen];
调用lame_encode_buffer进行压缩
int recvLen = lame_encode_buffer(lame, recordingData, recordingData, nsamples, buffer, pcmLen);
注意有可能缓冲区没有填满,所以压缩后数据的实际大小为recvLen,也就是lame_encode_buffer的返回值
把压缩后的数据添加到一个NSMutable中
[mp3Datas appendBytes:buffer length:recvLen];
6. 录音结束后,保存到Document文件中
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
NSString *filePath = [path stringByAppendingPathComponent:@"recording.mp3"];
[mp3Datas writeToFile:filePath atomically:YES];
[mp3Datas release];
7. 释放lame资源
lame_close(lame);
以上就是用lame进行压缩的主要步骤,我设置的录音格式是:16位 16k的pcm,这个要和lame设置的参数对应上,否则压缩是会有问题的。
整个Demo我已经上传到附件中,点击“开始说话”按钮进行录音,然后再点击“说完了”停止录音。
我把压缩后的MP3数据存放在Documents下的recording.mp3文件中,需要的话可以自行用AVAudioPlayer进行播放,或直接把recording.mp3拷出来,用一般的音乐播放器播放。