iOS 音频WAV转mp3

/**
 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

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
Yanwubujin-的头像 - 鹿快
评论 抢沙发

请登录后发表评论

    暂无评论内容