本文轉自:http://blog.csdn.net/xy5811/article/details/8563137
選擇一個Category
AVAudioSessionCategoryAmbient
或 kAudioSessionCategory_AmbientSound
——用於非以語音爲主的應用,使用這個category的應用會隨着靜音鍵和屏幕關閉而靜音。並且不會中止其它應用播放聲音,可以和其它自帶應用如iPod,safari等同時播放聲音。注意:該Category無法在後臺播放聲音
AVAudioSessionCategorySoloAmbient
或 kAudioSessionCategory_SoloAmbientSound
——類似於AVAudioSessionCategoryAmbient 不同之處在於它會中止其它應用播放聲音。
這個category爲默認category。該Category無法在後臺播放聲音
AVAudioSessionCategoryPlayback
或 kAudioSessionCategory_MediaPlayback
——用於以語音爲主的應用,使用這個category的應用不會隨着靜音鍵和屏幕關閉而靜音。
AVAudioSessionCategoryRecord
或 kAudioSessionCategory_RecordAudio———
用於需要錄音的應用,設置該category後,除了來電鈴聲,鬧鐘或日曆提醒之外的其它系統聲音都不會被播放。該Category只提供單純錄音功能。
AVAudioSessionCategoryPlayAndRecord
或 kAudioSessionCategory_PlayAndRecord
——用於既需要播放聲音又需要錄音的應用,語音聊天應用(如微信)應該使用這個category。該Category提供錄音和播放功能。
AVAudioSessionCategoryAudioProcessing
或 kAudioSessionCategory_AudioProcessing————
當需要進行離線語音處理時使用這個category,這裏我也不太明白離線語音處理是什麼概念,希望有知道的可以解釋下。
注意:並不是一個應用只能使用一個category,程序應該根據實際需要來切換設置不同的category,舉個例子,錄音的時候,需要設置爲AVAudioSessionCategoryRecord,當錄音結束時,應根據程序需要更改category爲爲AVAudioSessionCategoryAmbient,AVAudioSessionCategorySoloAmbient或AVAudioSessionCategoryPlayback中的一種。
Property
kAudioSessionProperty_OverrideCategoryMixWithOthers 允許和其他app同時播放聲音
kAudioSessionProperty_OtherMixableAudioShouldDuck 允許和其他app同時播放聲音,但會將其他app的聲音變小
如果想實現既能在後臺播放聲音,又能隨着靜音鍵而靜音的功能,可以這麼做:
- setCategory(AVAudioSessionCategoryPlayBack);
- playSound();
- setCategory(AVAudioSessionCategoryAmbient);
設置Category
- <span style="font-size: 14px;">NSError *setCategoryError = nil;
- BOOL success = [[AVAudioSession sharedInstance]
- setCategory: AVAudioSessionCategoryAmbient
- error: &setCategoryError];
- if (!success) { /* handle the error in setCategoryError */ }</span>
切換到揚聲器
按照蘋果官方文檔的說法,只有在category設置爲AVAudioSessionCategoryPlayAndRecord時才能從揚聲器播放聲音,這一點我還未證實。
總之,按照官方文檔的說法,先設置category爲AVAudioSessionCategoryPlayAndRecord,然後通過重寫audio route屬性來重定向音頻。
audio route屬性有以下兩個,一個是默認的聽筒,另一個則是揚聲器。
- enum {
- kAudioSessionOverrideAudioRoute_None = 0,
- kAudioSessionOverrideAudioRoute_Speaker = 'spkr'
- };
- UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
- AudioSessionSetProperty (
- kAudioSessionProperty_OverrideAudioRoute
- sizeof (audioRouteOverride),
- &audioRouteOverride
- );
- UInt32 doChangeDefaultRoute = 1;
- AudioSessionSetProperty (
- kAudioSessionProperty_OverrideCategoryDefaultToSpeaker,
- sizeof (doChangeDefaultRoute),
- &doChangeDefaultRoute
- );
這兩種方法區別在於:
使用kAudioSessionProperty_OverrideAudioRoute時,當發生任何中斷如插拔耳機時,audio route就會重置回聽筒,你必須再設置一次。
使用kAudioSessionProperty_OverrideCategoryDefaultToSpeaker則除非你更改category,否則會一直生效。
下面給出一段仿微信的切換揚聲器和聽筒代碼:
- [[UIDevice currentDevice] setProximityMonitoringEnabled:YES]; //建議在播放之前設置yes,播放結束設置NO,這個功能是開啓紅外感應
- //添加監聽
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(sensorStateChange:)
- name:@"UIDeviceProximityStateDidChangeNotification"
- object:nil];
- //處理監聽觸發事件
- -(void)sensorStateChange:(NSNotificationCenter *)notification;
- {
- //如果此時手機靠近面部放在耳朵旁,那麼聲音將通過聽筒輸出,並將屏幕變暗(省電啊)
- if ([[UIDevice currentDevice] proximityState] == YES)
- {
- NSLog(@"Device is close to user");
- [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
- }
- else
- {
- NSLog(@"Device is not close to user");
- [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
- }
- }
- //初始化播放器的時候如下設置
- UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
- AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,
- sizeof(sessionCategory),
- &sessionCategory);
- UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
- AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,
- sizeof (audioRouteOverride),
- &audioRouteOverride);
- AVAudioSession *audioSession = [AVAudioSession sharedInstance];
- //默認情況下揚聲器播放
- [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
- [audioSession setActive:YES error:nil];