语音格式转换
第一次写博客,记录下新出的问题。
最近做了个新东西,语音格式的转换。从微信获取发送的语音文件,然后转换成MP3上传到服务器。
各种国内国外网站找了好多,大概转换流程就是:slk->pcm->mp3。
网上拿了大佬的silk文件以及lame文件,自己保存一下,发个demo。
// silk转成pcm
NSString *silkFilePath = msg.m_nsFilePath;
char OpenFile[256];
memcpy(OpenFile, [silkFilePath cStringUsingEncoding:NSASCIIStringEncoding], 2 * [silkFilePath length]);
NSString *pcmFilePath = [silkFilePath stringByReplacingOccurrencesOfString:@"slk" withString:@"pcm"];
char filepath[256];
memcpy(filepath, [pcmFilePath cStringUsingEncoding:NSASCIIStringEncoding], 2 * [pcmFilePath length]);
int ret = SILK_Decoder(OpenFile, filepath);
if (ret == 1)
{
pcmFile = fopen(filepath, "r");
if (pcmFile)
{
fseek(pcmFile, 0, SEEK_SET);
DebugLog(@"PlayerViewController PCM文件打开成功...");
// 将pcm格式文件转成MP3格式
[NSThread detachNewThreadWithBlock:^{
// 删除本地的silk文件
// [LLSaveImageManager deleteLocalAudioWithPath:silkFilePath];
// 将pcm格式文件转成MP3格式
[self pcmToMp3:pcmFilePath msg:msg];
[NSThread exit];
}];
}
else
{
DebugLog(@"PlayerViewController PCM文件打开错误...");
return;
}
}
// pcm格式文件转成MP3
NSString *mp3FilePath = [pcmFilePath stringByReplacingOccurrencesOfString:@"pcm" withString:@"mp3"];
@try {
int read, write;
FILE *pcm = fopen([pcmFilePath cStringUsingEncoding:1], "rb");
fseek(pcm, 4*1024, SEEK_CUR);
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_t lame = lame_init();
lame_set_num_channels(lame, 1); // 微信语音单通道
lame_set_in_samplerate(lame, 11025.0); // 输入采样率
lame_set_brate(lame, 88);
lame_set_quality(lame, 2);
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) {
// lame_encode_flush 单声道以及双声道使用
write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
} else {
// lame_encode_buffer_interleaved 双声道数据是交错在一起输入的
write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
}
fwrite(mp3_buffer, write, 1, mp3);
} while (read != 0);
lame_close(lame);
fclose(mp3);
fclose(pcm);
}
@catch (NSException *exception) {
DebugLog(@"exception = %@", [exception description]);
}
@finally {
[HSState sharedInstance].audio_duration = [self getLength:mp3FilePath];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL fileURLWithPath:mp3FilePath] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (!error) {
// 转换成功
...
}
}];
[task resume];
}