WJUploadVoiceInfoObject
- voiceLocalPcmPath (pcm格式文件路徑)
- oiceLocalMp3Path (mp3文件路徑)
+ (void)convertPCMToMp3:(id<WJUploadVoiceInfoObject>)infoObject
success:(void(^)(NSString *mp3Path))success
failure:(void(^)(NSError *error))failure {
NSString *mp3FilePath = infoObject.voiceLocalMp3Path;
NSString *pcmFilePath = infoObject.voiceLocalPcmPath;
@try {
int read,write;
// 只讀方式打開被轉換音頻文件
FILE *pcm = fopen([pcmFilePath cStringUsingEncoding:1], "rb");
if (!pcm) {
return;
}
// 刪除頭,否則在前一秒鐘會有雜音
fseek(pcm, 4 * 1024, SEEK_CUR);
// 只寫方式打開生成的MP3文件
FILE *mp3 = fopen([mp3FilePath cStringUsingEncoding:1], "wb");
const int PCM_SIZE = 8192;
const int MP3_SIZE = 8192;
short int pcm_buffer[PCM_SIZE * 2];
unsigned char mp3_buffer[MP3_SIZE];
// 這裏要注意,lame的配置要跟AVAudioRecorder的配置一致,否則會造成轉換不成功
lame_t lame = lame_init();
// 採樣率需要和百度語音一致(百度16k,mp3一般是雙聲道的,設置8k)
lame_set_in_samplerate(lame, 8000.0);
lame_set_VBR(lame, vbr_default);
lame_init_params(lame);
do {
//以二進制形式讀取文件中的數據
read = (int)fread(pcm_buffer, 2 * sizeof(short int), PCM_SIZE, pcm);
if (read == 0) {
write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
} else {
write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
}
/*
* 二進制形式寫數據到文件中
*
* mp3_buffer:數據輸出到文件的緩衝區首地址
* write:一個數據塊的字節數
* 1:指定一次輸出數據塊的個數
* mp3:文件指針
*/
fwrite(mp3_buffer, write, 1, mp3);
} while (read != 0);
lame_close(lame);
fclose(mp3);
fclose(pcm);
} @catch (NSException *exception) {
WJLog(@"%@", [exception description]);
if (failure) {
failure(nil);
}
} @finally {
WJLog(@"PCM轉換MP3轉換成功");
if (success) {
success(mp3FilePath);
}
}
}