// // ConvertAudioFile.m // Expert // // Created by xuxiwen on 2017/3/21. // Copyright © 2017年 xuxiwen. All rights reserved. // #import "ConvertAudioFile.h" #import @interface ConvertAudioFile () @property (nonatomic, assign) BOOL stopRecord; @end @implementation ConvertAudioFile /** get instance obj @return ConvertAudioFile instance */ + (instancetype)sharedInstance { static ConvertAudioFile *instance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [[ConvertAudioFile alloc] init]; }); return instance; } /** ConvertMp3 @param cafFilePath caf FilePath @param mp3FilePath mp3 FilePath @param sampleRate sampleRate (same record sampleRate set) @param callback callback result */ //- (void)conventToMp3WithCafFilePath:(NSString *)cafFilePath // mp3FilePath:(NSString *)mp3FilePath // sampleRate:(int)sampleRate // callback:(void(^)(BOOL result))callback //{ // // NSLog(@"convert begin!!"); // __weak typeof(self) weakself = self; // dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // // weakself.stopRecord = NO; // // @try { // // int read, write; // // FILE *pcm = fopen([cafFilePath cStringUsingEncoding:NSASCIIStringEncoding], "rb"); // FILE *mp3 = fopen([mp3FilePath 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, sampleRate); // lame_set_VBR(lame, vbr_default); // lame_init_params(lame); // // long curpos; // BOOL isSkipPCMHeader = NO; // // do { // curpos = ftell(pcm); // long startPos = ftell(pcm); // fseek(pcm, 0, SEEK_END); // long endPos = ftell(pcm); // long length = endPos - startPos; // fseek(pcm, curpos, SEEK_SET); // // if (length > PCM_SIZE * 2 * sizeof(short int)) { // // if (!isSkipPCMHeader) { // //Uump audio file header, If you do not skip file header // //you will heard some noise at the beginning!!! // 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); //// NSLog(@"read %d bytes", write); // } else { // [NSThread sleepForTimeInterval:0.05]; //// NSLog(@"sleep"); // } // // } while (! weakself.stopRecord); // // 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]); // if (callback) { // callback(NO); // } // } // @finally { // if (callback) { // callback(YES); // } // NSLog(@"convert mp3 finish!!! %@", mp3FilePath); // } // }); // //} /** send end record signal */ - (void)sendEndRecord { self.stopRecord = YES; } - (void)conventToMp3WithCafFilePath:(NSString *)cafFilePath mp3FilePath:(NSString *)mp3FilePath sampleRate:(int)sampleRate { __weak typeof(self) weakself = self; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ weakself.stopRecord = NO; @try { int read, write; FILE *pcm = fopen([cafFilePath cStringUsingEncoding:NSASCIIStringEncoding], "rb"); FILE *mp3 = fopen([mp3FilePath 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, sampleRate); lame_set_VBR(lame, vbr_default); lame_init_params(lame); long curpos; BOOL isSkipPCMHeader = NO; do { curpos = ftell(pcm); long startPos = ftell(pcm); fseek(pcm, 0, SEEK_END); long endPos = ftell(pcm); long length = endPos - startPos; fseek(pcm, curpos, SEEK_SET); if (length > PCM_SIZE * 2 * sizeof(short int)) { if (!isSkipPCMHeader) { //Uump audio file header, If you do not skip file header //you will heard some noise at the beginning!!! 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); // NSLog(@"read %d bytes", write); } else { [NSThread sleepForTimeInterval:0.05]; // NSLog(@"sleep"); } } while (! weakself.stopRecord); NSLog(@"停止录音回调-----"); 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(@"出错了"); NSLog(@"%@", [exception description]); } @finally { NSLog(@"转码完成"); NSLog(@"convert mp3 finish!!! %@", mp3FilePath); } }); } #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 被转换的音频文件位置 fseek(pcm, 4*1024, SEEK_CUR); //skip file header 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,1);//设置1为单通道,默认为2双通道 lame_set_in_samplerate(lame, sampleRate); 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); } fwrite(mp3_buffer, write, 1, mp3); } while (read != 0); lame_mp3_tags_fid(lame, mp3); 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) { callback(YES); } } }); } @end