iOS 錄音,播放,轉碼MP3,上傳語音檔案
阿新 • • 發佈:2019-02-18
//語音檔案 AVAudioRecorder *recorder; NSTimer *timer; NSString *urlPlay; BOOL isPlay; #pragma mark ========= 語音檔案 ========== - (void)audio { AVAudioSession *a=[AVAudioSession sharedInstance]; [a setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; [a setActive:YES error:nil]; //錄音設定 NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] init]; //錄音格式 無法使用 [recordSetting setValue :[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey: AVFormatIDKey]; //取樣率 [recordSetting setValue :[NSNumber numberWithFloat:44100] forKey: AVSampleRateKey];//44100.0 //通道數 [recordSetting setValue :[NSNumber numberWithInt:2] forKey: AVNumberOfChannelsKey]; //線性取樣位數 [recordSetting setValue :[NSNumber numberWithInt:16] forKey: AVLinearPCMBitDepthKey]; //音訊質量,取樣質量 [recordSetting setValue:[NSNumber numberWithInt:AVAudioQualityMin] forKey:AVEncoderAudioQualityKey]; NSString *strUrl = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; urlPlay = [NSString stringWithFormat:@"%@/lll.lpcm", strUrl]; NSError *error; //初始化 recorder = [[AVAudioRecorder alloc]initWithURL:[NSURL URLWithString:urlPlay] settings:recordSetting error:&error]; //開啟音量檢測 recorder.meteringEnabled = YES; recorder.delegate = self; } //開始錄音 - (IBAction)speak_touchDown:(id)sender { if(isPlay==NO){ _speakBackView.frame=CGRectMake(ScreenWidth/2-75,ScreenHeight/2-130,150, 150); _speakBackView.backgroundColor=[UIColor colorWithWhite:0.000 alpha:0.6]; _speakBackView.layer.cornerRadius=10; _speakBackView.clipsToBounds=YES; [self.view addSubview:_speakBackView]; //建立錄音檔案,準備錄音 if ([recorder prepareToRecord]) { //開始 [recorder record]; } //設定定時檢測 timer = [NSTimer scheduledTimerWithTimeInterval:0 target:self selector:@selector(detectionVoice) userInfo:nil repeats:YES]; } } //拖動取消錄音 - (IBAction)speak_drag:(id)sender { if(isPlay==NO){ [_speakBackView removeFromSuperview]; //刪除錄製檔案 [recorder deleteRecording]; [recorder stop]; [timer invalidate]; } } //錄音完成 - (IBAction)speak_touchUpinset:(id)sender { [timer invalidate]; if (isPlay==NO) { [_speakBackView removeFromSuperview]; double cTime = recorder.currentTime; if (cTime > 1) {//如果錄製時間<2 不傳送 NSLog(@"發出去"); //顯示錄音時間 [_btn_speak setTitle:[NSString stringWithFormat:@"%.1lf\" 播放",cTime] forState:UIControlStateNormal]; //錄音時候的標誌 UIImage *image=[UIImage imageNamed:@"speak_read"]; image=[image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; [_btn_speak setImage:image forState:UIControlStateNormal]; _btn_cancelSpeak.hidden=NO; isPlay=YES; //新開執行緒進行解碼 [NSThread detachNewThreadSelector:@selector(audio_PCMtoMP3) toTarget:self withObject:nil]; }else { //刪除記錄的檔案 [recorder deleteRecording]; } [recorder stop]; } //點選時候播放與暫停 else{ if (self.avPlay.playing) { [_btn_speak setTitle:[NSString stringWithFormat:@"%.1lf\" 播放",_avPlay.duration] forState:UIControlStateNormal]; [self.avPlay stop]; return; } [_btn_speak setTitle:@"暫停" forState:UIControlStateNormal]; AVAudioPlayer *player = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL URLWithString:urlPlay] error:nil]; self.avPlay = player; self.avPlay.delegate=self; [self.avPlay prepareToPlay]; [self.avPlay play]; NSLog(@"%f",_avPlay.duration); } } //刪除錄音檔案 - (IBAction)cancelSpeak:(id)sender { [_avPlay stop]; _saveModel.speakUrl=nil; [recorder deleteRecording]; isPlay=NO; _btn_cancelSpeak.hidden=YES; [_btn_speak setTitle:@"按住 說話" forState:UIControlStateNormal]; [_btn_speak setImage:nil forState:UIControlStateNormal]; } - (void)detectionVoice { [recorder updateMeters];//重新整理音量資料 //獲取音量的平均值 [recorder averagePowerForChannel:0]; //音量的最大值 [recorder peakPowerForChannel:0]; double lowPassResults = pow(10, (0.05 * [recorder peakPowerForChannel:0])); NSLog(@"%lf",lowPassResults); if(0<lowPassResults&&lowPassResults<=0.125) { [_speak_iamgeV setImage:[UIImage imageNamed:@"record_animate_01"]]; }else if (0.125<lowPassResults&&lowPassResults<=0.25) { [_speak_iamgeV setImage:[UIImage imageNamed:@"record_animate_02"]]; }else if (0.25<lowPassResults&&lowPassResults<=0.375) { [_speak_iamgeV setImage:[UIImage imageNamed:@"record_animate_03"]]; }else if (0.375<lowPassResults&&lowPassResults<=0.50) { [_speak_iamgeV setImage:[UIImage imageNamed:@"record_animate_04"]]; }else if (0.50<lowPassResults&&lowPassResults<=0.625) { [_speak_iamgeV setImage:[UIImage imageNamed:@"record_animate_05"]]; }else if (0.625<lowPassResults&&lowPassResults<=0.75) { [_speak_iamgeV setImage:[UIImage imageNamed:@"record_animate_06"]]; }else if (0.75<lowPassResults&&lowPassResults<=0.875) { [_speak_iamgeV setImage:[UIImage imageNamed:@"record_animate_07"]]; }else { [_speak_iamgeV setImage:[UIImage imageNamed:@"record_animate_08"]]; } } - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{ [_btn_speak setTitle:[NSString stringWithFormat:@"%.1lf\" 播放",_avPlay.duration] forState:UIControlStateNormal]; } #pragma mark ===== 轉換成MP3檔案===== - (void)audio_PCMtoMP3 { NSString *strUrl = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; //NSString *mp3FileName = [strUrl lastPathComponent]; //mp3FileName = [mp3FileName stringByAppendingString:@".mp3"]; NSString *mp3FilePath = [strUrl stringByAppendingPathComponent:@"lll.mp3"]; @try { int read, write; FILE *pcm = fopen([urlPlay 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, 44100); 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 { strUrl = mp3FilePath; _saveModel.speakUrl=[NSURL URLWithString:strUrl]; NSLog(@"MP3生成成功: %@",strUrl); } } #pragma mark ========= 上傳 ========== [self.httpMgr POST:@"http://xuyingtest.sinaapp.com/uploadfile.php" parameters:nilconstructingBodyWithBlock:^ void(id<AFMultipartFormData> formData) { [formData appendPartWithFileURL:self.audioReorder.url name:@"file" error:nil]; } success:^ void(AFHTTPRequestOperation * operation, id responseObject) { NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:nil]; if (dict[@"error"]) { NSLog(@" up success error :%@",dict[@"error"]); } else { NSLog(@"upload file ok!:%@",dict[@"success"]); } } failure:^void(AFHTTPRequestOperation * operation, NSError * error) { NSLog(@"%@",error.localizedDescription); }];