1. 程式人生 > >錄音(PCM格式)、播放、lame轉碼成MP3

錄音(PCM格式)、播放、lame轉碼成MP3

/**
 * 
音訊轉碼,由PCM轉碼為MP3
 */

- (
void)convertToMP3
{
   
NSString * mp3FileName = @"sendRecord.mp3";
   
NSString * documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
   
NSString *mp3FilePath = [documentPath stringByAppendingPathComponent:mp3FileName];
   
NSString * audioFilePath = [NSString stringWithFormat:@"%@/audio.caf", documentPath];
   
   
NSLog(@"audioPath:%@", audioFilePath);
   
   
@try {
       
int read, write;
       
       
FILE *pcm = fopen([audioFilePath 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_in_samplerate(lame, 11025.0);
       
lame_set_VBR(lame, vbr_default);
       
lame_init_params(lame);
       
       
do {
            read =
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_close(lame);
       
fclose(mp3);
       
fclose(pcm);
    }
   
@catch (NSException *exception) {
       
NSLog(@"%@",[exception description]);
    }
   
@finally
    {
       
NSLog(@"MP3生成成功:%@", mp3FilePath);
    }
}

#pragma mark - 取得錄音檔案儲存路徑/**
 * 
取得錄音原始檔案儲存路徑
 *
 * 
@return 錄音原始檔案路徑
 */

- (
NSURL *)getSavePath{
   
NSString *urlStr=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    urlStr=[urlStr
stringByAppendingPathComponent:@"audio.caf"];
   
NSURL *url=[NSURL fileURLWithPath:urlStr];
   
return url;
}

- (
NSString *)getSavePathToString{
   
NSString *urlStr=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    urlStr=[urlStr
stringByAppendingPathComponent:@"audio.caf"];
   
return urlStr;
}

/**
 * 
取得MP3檔案儲存路徑
 *
 * 
@return MP3檔案路徑
 */

- (
NSURL *)getMP3Path
{
   
//播放MP3 NSString * mp3FileName = @"sendRecord.mp3";
   
NSString * documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
   
NSString *mp3FilePath = [documentPath stringByAppendingPathComponent:mp3FileName];
   
return [NSURL fileURLWithPath:mp3FilePath];
}

- (
NSString *)getMP3PathToString
{
   
//播放MP3 NSString * mp3FileName = @"sendRecord.mp3";
   
NSString * documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
   
NSString *mp3FilePath = [documentPath stringByAppendingPathComponent:mp3FileName];
   
return mp3FilePath;
}

#pragma mark - 取得錄音檔案設定/**
 * 
取得錄音檔案設定
 *
 * 
@return 錄音設定
 */

-(
NSDictionary *)getAudioSetting{
   
NSMutableDictionary *dicM=[NSMutableDictionary dictionary];
   
//設定錄音格式
    [dicM
setObject:@(kAudioFormatLinearPCM) forKey:AVFormatIDKey];
   
//設定錄音取樣率,8000是電話取樣率,對於一般錄音已經夠了
    [dicM
setObject:@(11025.0) forKey:AVSampleRateKey];
   
//設定通道,這裡採用單聲道
    [dicM
setObject:@(2) forKey:AVNumberOfChannelsKey];
   
//每個取樣點位數,分為8162432
    [dicM
setObject:@(16) forKey:AVLinearPCMBitDepthKey];
   
//是否使用浮點數取樣 //    [dicM setObject:@(YES) forKey:AVLinearPCMIsFloatKey]; //音訊編碼質量
    [dicM
setObject:@(AVAudioQualityLow) forKey:AVEncoderAudioQualityKey];
   
//....其他設定等 return dicM;
}

#pragma mark - 懶載入- (AVAudioRecorder *)audioRecorder{
   
if (_audioRecorder == nil) {
       
//錄音相關 AVAudioSession *audioSession=[AVAudioSession sharedInstance];
       
//設定為播放和錄音狀態,以便可以在錄製完之後播放錄音
        [audioSession
setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
        [audioSession
setActive:YES error:nil];
       
       
//建立錄音檔案儲存路徑 NSURL * url = [self getSavePath];
       
//建立錄音格式設定 NSDictionary * setting = [self getAudioSetting];
       
//建立錄音機 NSError * error = nil;
       
_audioRecorder = [[AVAudioRecorder alloc] initWithURL:url settings:setting error:&error];
       
       
_audioRecorder.delegate = self;
       
if (error) {
           
NSLog(@"建立錄音機物件時發生錯誤,錯誤資訊:%@", error.localizedDescription);
           
return nil;
        }
    }
   
return _audioRecorder;
}

/**
 * 
建立播放器
 *
 * 
@return 播放器
 */

- (
AVAudioPlayer *)audioPlayer{
   
if (_audioPlayer == nil) {
       
//錄音相關 AVAudioSession *audioSession=[AVAudioSession sharedInstance];
       
//設定為播放和錄音狀態,以便可以在錄製完之後播放錄音
        [audioSession
setCategory:AVAudioSessionCategoryPlayback error:nil];
        [audioSession
setActive:YES error:nil];
       
NSURL * url = [self getSavePath];
       
       
NSError * error = nil;
       
_audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
       
_audioPlayer.volume = 1.0;
       
_audioPlayer.numberOfLoops = 0;
       
_audioPlayer.delegate = self;
        [
_audioPlayer prepareToPlay];
       
if (error) {
           
NSLog(@"建立播放器過程中發生錯誤,錯誤資訊:%@", error.localizedDescription);
           
return nil;
        }
    }
   
return _audioPlayer;