公司下個版本計劃要做音頻的錄制與播放,這塊沒怎么接觸過,一邊學習一邊踩坑,下面就給大家做個分享,共同進步。這里也貼出我寫的DEMO(代碼使用了鏈式編程思想,也是學習階段,歡迎指正),歡迎使用和star!
錄音
音頻任務(wù)初始化
我們這里用的是NB的AVFoundation框架,這里使用AudioSession來對音頻任務(wù)做處理,無論是錄制還是播放都需要做這一步。初始化任務(wù):
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *sessionError;
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:&sessionError];
if(session == nil){
NSLog(@"Error creating session: %@", [sessionError description]);
}else{
[session setActive:YES error:nil];//激活當前session
}
如果不做初始化,直接使用AudioRecorder的話,錄制出來是沒有任何聲音的,下面幾點就是原因,也是它的主要功能:
1.為app選擇輸入輸出的路由 (通過揚聲器還是聽筒播放)
2.協(xié)調(diào)音頻播放的app之間的關(guān)聯(lián),以及系統(tǒng)的聲音處理
3.處理被其他apps打斷
4.創(chuàng)建一個錄音或者播放音樂的任務(wù)
而這里的參數(shù)AVAudioSessionCategoryPlayAndRecord需要說明一下,可以根據(jù)實際情況選擇:
* AVAudioSessionCategorySoloAmbient
會停止其他程序的音頻播放。當設(shè)備被設(shè)置為靜音模式,app也同樣被停止
* AVAudioSessionCategoryRecord
僅用來錄音,無法播放音頻
* AVAudioSessionCategoryPlayback
會停止其它音頻播放,并且能在后臺播放,鎖屏and靜音模式下均可
* AVAudioSessionCategoryPlayAndRecord
能播也能錄,播放默認聲音是從聽筒出來
* AVAudioSessionCategoryAmbient
app的聲音可與其它app共存,但鎖屏和靜音情況會被停止,除非當前app是唯一播放的app
初始化錄音器
錄音需要調(diào)用AVAudioRecorder,下面代碼用于初始化錄音器:
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
playName = [NSString stringWithFormat:@"%@/play.aac",docDir];
//錄音設(shè)置
recorderSettingsDict =[[NSDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithInt:kAudioFormatMPEG4AAC],AVFormatIDKey,
[NSNumber numberWithInt:8000],AVSampleRateKey,
[NSNumber numberWithInt:1],AVNumberOfChannelsKey,
AVAudioQualityHigh,AVEncoderAudioQualityKey,
nil];
NSError *error = nil;
//必須真機上測試,模擬器上可能會崩潰
_recorder = [[AVAudioRecorder alloc] initWithURL:[NSURL URLWithString:playName] settings:recorderSettingsDict error:&error];
先給大家看一下初始化字典里面的參數(shù):
AVFormatIDKey——音頻格式,主要有一下支持格式:
kAudioFormatLinearPCM
kAudioFormatMPEG4AAC
kAudioFormatAppleLossless
kAudioFormatAppleMA4
kAudioFormatiLBC
kAudioFormatULaw
選擇kAudioFormatLinearPCM會將未壓縮的音頻流寫入到文件中.這種格式保真度最高,不過相應(yīng)的文件也最大.選擇諸如kAudioFormatMPEG4AAC或者kAudioFormatAppleMA4的壓縮格式會顯著縮小文件,也能保證高質(zhì)量的音頻內(nèi)容。我這里選擇的是kAudioFormatMPEG4AAC,而且安卓和蘋果都支持播放。
AVSampleRateKey——采樣率,單位HZ,采樣率越小聲音質(zhì)量越低,通常有8000/44100/96000,采樣率必須要設(shè)為11025才能使轉(zhuǎn)化成mp3格式后不會失真
AVNumberOfChannelsKey——聲道數(shù),1或2,除非使用外部硬件,否則通常應(yīng)當創(chuàng)建單聲道錄音。通常單聲道足以滿足我們錄音功能的需要。
AVEncoderAudioQualityKey——錄音音質(zhì),是一個枚舉值,這里我選AVAudioQualityHigh中等質(zhì)量。
更多參考鏈接
開始錄制
_recorder.meteringEnabled = YES;//設(shè)置yes才能監(jiān)測輸入的音量大小,可以用作用戶界面反饋
[_recorder record];
volumeTimer = [NSTimer scheduledTimerWithTimeInterval:volumeObserverMargin target:weakSelf selector:@selector(levelTimer:) userInfo:nil repeats:YES];//新建一個計時器用作測量音量大小
監(jiān)測音量
//輸入聲音的分貝大小計算
[_recorder updateMeters];
const double ALPHA = 0.05;
double peakPowerForChannel = pow(10, (0.05 * [_recorder peakPowerForChannel:0]));
lowPassResults = ALPHA * peakPowerForChannel + (1.0 - ALPHA) * lowPassResults;
停止錄音
_recorder stop];
_recorder = nil;
//結(jié)束定時器
[volumeTimer invalidate];
volumeTimer = nil;
播放本地錄音
這里分兩步操作,一是播放本地音頻,二是進行進度監(jiān)聽
播放本地音頻
[playerLocal play];
progressTimer = [NSTimer scheduledTimerWithTimeInterval:playerTimeObserverMargin target:self selector:@selector(recorderTimeViewer) userInfo:nil repeats:YES];//新建計時器監(jiān)聽播放進度
播放進度監(jiān)聽
NSLog(@"總時長:%f--當前時間點:%f",_playerLocal.duration,_playerLocal.currentTime);
播放網(wǎng)絡(luò)音頻
_songItem = [[AVPlayerItem alloc]initWithURL:url];
_playerNetwork = [[AVPlayer alloc]initWithPlayerItem:_songItem];
[_playerNetwork play];
獲取網(wǎng)絡(luò)資源總時長的方法:
netAudioTime = CMTimeGetSeconds(_songItem.asset.duration);
Tips
1..plist文件中加入麥克風請求權(quán)限
2.如果需要播放網(wǎng)絡(luò)音頻,添加App Transport Security Settings下的Allow Arbitrary Loads并設(shè)置為YES
3.如果需要app支持后臺播放音頻,需要打開Capabilities下面Background Modes下面的Audio,AirPlay,and Picture in Picture選項,但是審核的時候蘋果如果認為你沒有必要打開這個功能,會被拒哦!
4.不用外接設(shè)備錄音和播放會聲音小,解決辦法是播放前加入下面代碼:
NSError *audioError = nil;
BOOL success = [audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&audioError];
if(!success)
{
NSLog(@"error doing outputaudioportoverride - %@", [audioError localizedDescription]);
}
Tips one more
完整功能的demo已經(jīng)更新,分別實現(xiàn)了錄音、播放本地錄音和播放網(wǎng)絡(luò)音頻的播放、暫停、繼續(xù)、停止。使用可以參照demo。