1. Mac和iOS的音頻環(huán)境
Mac上提供了靈活自由的音頻環(huán)境,你可以同時(shí)聽(tīng)歌,看電影,錄制音頻,也不會(huì)沖突。但是
iOS系統(tǒng)利用音頻會(huì)話(audio Session)提供了一個(gè)可管理的音頻環(huán)境。
2.理解音頻會(huì)話
- 在APPDelegate中 配置音頻會(huì)話,如果不配置會(huì)導(dǎo)致手機(jī)“靜音”后不會(huì)導(dǎo)致 音頻播放不出來(lái)。
// 配置音頻會(huì)話
AVAudioSession * audioSession = [AVAudioSession sharedInstance];
NSError * error ;
// 設(shè)置分類
if (![audioSession setCategory:AVAudioSessionCategoryPlayback error:&error]) {
NSLog(@"%@",error.description);
}
// 激活會(huì)話
if (![audioSession setActive:YES error:&error]) {
NSLog(@"%@",error.description);
}
-
在Capabilities中設(shè)置 ,允許后臺(tái)播放音頻。
image.png 處理中斷事件
添加 AVAudioSession 的中斷通知 AVAudioSessionInterruptionNotification
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioInterruptionNotifiction:) name:AVAudioSessionInterruptionNotification object:[AVAudioSession sharedInstance]];
中斷類型有兩種AVAudioSessionInterruptionTypeBegan 中斷開(kāi)始;AVAudioSessionInterruptionTypeEnded中斷結(jié)束
#pragma mark -- 接收到音頻中斷 通知
- (void)audioInterruptionNotifiction:(NSNotification *)noti{
NSDictionary * info = noti.userInfo;
AVAudioSessionInterruptionType type = [info[AVAudioSessionInterruptionTypeKey] unsignedIntegerValue];
if (type == AVAudioSessionInterruptionTypeBegan) {
// 中斷開(kāi)始 執(zhí)行停止播放操作
}else if (type == AVAudioSessionInterruptionTypeEnded){
AVAudioSessionInterruptionOptions options = [info[AVAudioSessionInterruptionOptionKey] unsignedIntegerValue];
if (options == AVAudioSessionInterruptionOptionShouldResume) {
// 表明會(huì)話已經(jīng)重新激活 可以再次播放
}
}
}
- 音頻線路改變
添加線路改變通知
// 音頻線路改變通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioRouteChangeNotification:) name:AVAudioSessionRouteChangeNotification object:[AVAudioSession sharedInstance]];
#pragma mark -- 接收音頻線路改變 通知
- (void)audioRouteChangeNotification:(NSNotification *)noti{
NSDictionary * info = noti.userInfo;
AVAudioSessionRouteChangeReason reason = [info[AVAudioSessionRouteChangeReasonKey] unsignedIntegerValue];
// 音頻線路改變的原因 有很多
if (reason == AVAudioSessionRouteChangeReasonOldDeviceUnavailable) {
// 音頻線路改變的原因是 舊設(shè)備不可用 (如耳機(jī)拔掉)
// 判斷之前的音頻的輸出設(shè)備
AVAudioSessionRouteDescription * previousRoute = info[AVAudioSessionRouteChangePreviousRouteKey];
AVAudioSessionPortDescription * previousOutput = previousRoute.outputs.firstObject;
NSString * portType= previousOutput.portType;
if ([portType isEqualToString:AVAudioSessionPortHeadphones]) {
// 耳機(jī)拔掉 停止播放
}
}
}
3.使用AVAudioPlayer 播放音頻
self.audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL URLWithString:@""] error:nil];
self.audioPlayer.numberOfLoops = -1;// 無(wú)限循環(huán)
self.audioPlayer.enableRate = YES;//必須在調(diào)用prepareToPlay之前設(shè)置。YES:可以對(duì)播放率進(jìn)行控制
self.audioPlayer.volume = 0.5;//(0,1)音量
self.audioPlayer.pan = 0.0;//(-1,1) 立體聲
[self.audioPlayer prepareToPlay];
[self.audioPlayer playAtTime:0.2f];// 從哪里開(kāi)始播放
self.audioPlayer.currentTime = 0.0f;// 播放進(jìn)度回到原點(diǎn)
4.使用AVRecorder 錄制音頻
// 設(shè)置 錄制音配 配置
NSDictionary * audioSettings = @{
AVFormatIDKey:@(kAudioFormatMPEG4AAC),
AVSampleRateKey :@22050.0f,
AVNumberOfChannelsKey:@1
};
NSError * error ;
self.audioRecorder = [[AVAudioRecorder alloc]initWithURL:[NSURL URLWithString:@""] settings:audioSettings error:&error];
[self.audioRecorder prepareToRecord];
音頻格式 -- AVFormatIDKey
kAudioFormatMPEG4AAC = 'aac ',采樣率 -- AVSampleRateKey
采樣率:輸入的模擬音頻信號(hào)每秒的采樣數(shù),
采樣率低 (如8kHz) 會(huì)導(dǎo)致粗粒感,文件??;
采樣率高 (如44.1kHz)質(zhì)量高,文件大;
標(biāo)準(zhǔn)采樣率:8000,16000,22050,44100。通道數(shù) -- AVNumberOfChannelsKey
1 :?jiǎn)温暤?br> 2 :立體聲麥克風(fēng)權(quán)限
<key>NSMicrophoneUsageDescription</key>
<string>xxxx想訪問(wèn)您的麥克風(fēng),進(jìn)行語(yǔ)音通話。</string>
5.音頻測(cè)量
- (void)levels{
self.audioRecorder.meteringEnabled = YES;// 支持對(duì)音頻的e測(cè)量
// 保證讀取的級(jí)別是最新的
[self.audioRecorder updateMeters];
// 想通道0 請(qǐng)求平均值
float aver = [self.audioRecorder averagePowerForChannel:0];
// 想通道0 請(qǐng)求峰值
float peak = [self.audioRecorder peakPowerForChannel:0];
}
