iOS 使用lame库进行音频转mp3(一)

来源:互联网 发布:搜狐动态ip软件 编辑:程序博客网 时间:2024/05/18 00:26

iOS 使用lame库进行音频转mp3(一)

iOS 使用lame库进行音频转mp3后时长不对,下面介绍的是录制完成转码,更多代码在最后的链接中下载demo可以查看

#pragma mark - ----------------------------------


// 这是录完再转码的方法, 如果录音时间比较长的话,会要等待几秒...

// Use this FUNC convent to mp3 after record


+ (void)conventToMp3WithCafFilePath:(NSString *)cafFilePath

                        mp3FilePath:(NSString *)mp3FilePath

                         sampleRate:(int)sampleRate

                           callback:(void(^)(BOOL result))callback

{

    

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        

        @try {

            int read, write;

            

            FILE *pcm = fopen([cafFilePath cStringUsingEncoding:1], "rb");  //source 被转换的音频文件位置(FILE文件指针名,"rb": 使用文件的方式)

            fseek(pcm, 4*1024, SEEK_CUR);                                  //skip file header重定位流上的文件指针,(描 述: 函数设置文件指针stream的位置。如果执行成功,stream将指向以fromwhere为基准,偏移offset个字     节的位置。如果执行失败(比如offset超过文件自身大小),则不改变stream指向的位置。返回值: 成功,返回0,否则返回其他值。)

            FILE *mp3 = fopen([mp3FilePath cStringUsingEncoding:1], "wb+");  //output 输出生成的Mp3文件位置

            

            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,2);//设置1为单通道,默认为2双通道(录音时是双通道)

            lame_set_in_samplerate(lame, sampleRate);//设置被输入编码器的原始数据的采样率。

            lame_set_VBR(lame, vbr_default);//设置比特率控制模式,默认是CBR,但是通常我们都会设置VBR。参数是枚举,vbr_off代表CBR,vbr_abr代表ABR(因为ABR不常见,所以本文不对ABR做讲解)vbr_mtrh代表VBR。

            lame_init_params(lame);//根据上面设置好的参数建立编码器

            

            do {

                

                read = (int)fread(pcm_buffer, 2*sizeof(shortint), PCM_SIZE, pcm);//fread是一个函数。从一个文件流中读数据,最多读取count个元素,每个元素size字节,如果调用成功返回实际读取到的元素个数,如果不成功或读到文件末尾返回 0。

                if (read == 0) {

                    write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);//刷新编码器缓冲,获取残留在编码器缓冲里的数据。这部分数据也需要写入mp3文件

                } else {

                    write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);//将PCM数据送入编码器,获取编码出的mp3数据。这些数据写入文件就是mp3文件。

                }

                

                fwrite(mp3_buffer, write, 1, mp3);//写入文件

                

            } while (read != 0);

            

            lame_mp3_tags_fid(lame, mp3);//将VBR/INFO tags封装到一个MP3 Frame中,写到文件开头。如果输出流没有办法回溯,那么必须在第3步设置lame_set_bWriteVbrTag(gfp,0),这一步调用lame_mp3_tags_fid(lame_global_flags *,FILE* fid)将fid参数=NULL。这样的话那个开头的信息帧(MP3 FRAME)的所有字节都是0。

            

            lame_close(lame);//销毁编码器,释放资源。

            fclose(mp3);

            fclose(pcm);

        }

        @catch (NSException *exception) {

            NSLog(@"%@",[exception description]);

            if (callback) {

                callback(NO);

            }

        }

        @finally {

            NSLog(@"-----\n  MP3生成成功: %@   -----  \n", mp3FilePath);

            if (callback) {

                [[PCMtoMP3Manager defaultManager] deleteWithisMp3:NO];

                callback(YES);

            }

        }

    });

}

下面链接及解决方法和相关demo

http://download.csdn.net/download/u011374880/10111418

原创粉丝点击