/**
ConvertMp3
@param cafFilePath caf FilePath
@param mp3FilePath mp3 FilePath
@param sampleRate sampleRate (same record sampleRate set)我传的8000.0
*/
- (void)conventToMp3WithCafFilePath:(NSString *)cafFilePath
mp3FilePath:(NSString *)mp3FilePath
sampleRate:(int)sampleRate
{
@try {
int read, write;
//source 被转换的音频文件位置
FILE *pcm = fopen([wavPath cStringUsingEncoding:NSASCIIStringEncoding], "rb");
//output 输出生成的Mp3文件位置
FILE *mp3 = fopen([mp3Path cStringUsingEncoding:NSASCIIStringEncoding], "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_in_samplerate(lame, 8000.0);
lame_set_VBR(lame, vbr_default);
lame_init_params(lame);
long curpos;
BOOL isSkipPCMHeader = NO;
do {
curpos = ftell(pcm);
fseek(pcm, 0, SEEK_END);
fseek(pcm, curpos, SEEK_SET);
if (!isSkipPCMHeader) {
//Uump audio file header, If you do not skip file header
//you will heard some noise at the beginning!!!
//skip file header 跳过 PCM header 能保证录音的开头没有噪音
fseek(pcm, 4 * 1024, SEEK_CUR);
isSkipPCMHeader = YES;
// NSLog(@"skip pcm file header !!!!!!!!!!");
}
read = (int)fread(pcm_buffer, 2 * sizeof(short int), PCM_SIZE, pcm);
write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
fwrite(mp3_buffer, write, 1, mp3);
} while (read != 0);
read = (int)fread(pcm_buffer, 2 * sizeof(short int), PCM_SIZE, pcm);
write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
// NSLog(@"read %d bytes and flush to mp3 file", write);
lame_mp3_tags_fid(lame, mp3);
lame_close(lame);
fclose(mp3);
fclose(pcm);
}
@catch (NSException *exception) {
NSLog(@"%@",[exception description]);
}
@finally {
[[NSFileManager defaultManager] removeItemAtPath:wavPath error:nil];
self.filePath = mp3Path;
// 这个是自己定义的一些方法
if (self.delegate &&[self.delegate respondsToSelector:@selector(voiceRecordHasBeenStoped)]) {
[self.delegate voiceRecordHasBeenStoped];
}
}
}
下面是一些说明:
C 语言的 文件打开模式(fopen)
w+以纯文本方式读写,而wb+是以二进制方式进行读写。
mode说明:
w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
wb 只写方式打开或新建一个二进制文件,只允许写数据。
wb+ 读写方式打开或建立一个二进制文件,允许读和写。
r 打开只读文件,该文件必须存在,否则报错。
r+ 打开可读写的文件,该文件必须存在,否则报错。
rb+ 读写方式打开一个二进制文件,只允许读写数据。
a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)
a+ 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。 (原来的EOF符不保留)
ab+ 读写打开一个二进制文件,允许读或在文件末追加数据。
加入b 字符用来告知函数库打开的文件为二进制文件,而非纯文字文件。
然后是lame_init()来初始化,lame_set_num_channels(lame,1)默认转码为2双通道, 设置单声道会更大程度减少压缩后文件的体积.
接下来 是执行一个 do while 的循环来反复读取FILE* stream, 直到 read != 0 , 结束转码,释放lame_close(lame); fclose(mp3); fclose(pcm);
以上参考地址:https://www.jianshu.com/p/7df304895a6b















暂无评论内容