曾經被我們忽略的AVAudioSession

AVAudioSession是用來管理和平衡多個App的(揚聲器、麥克瘋)的資源的使用。
例如設備在背后進行播放音樂時,這時候用戶進入我們的App,需要播放一小段視頻時,這個時候,我們應該如何處理?

  • 中斷音樂播放?
  • 暫時中斷音樂播放,等小視頻播放完畢喚醒背后音樂繼續播放?
  • 與音樂混音一起播放?
  • 與音樂混音播放暫時壓低背后音樂的聲音,等小視頻播放完畢恢復背后音樂的聲音大小?
    這些處理方式都是依靠AVAudioSession來處理的。
1.AVAudioSession 的 Category

我們進入 AVAudioSession 的Category可以發現有7種 Category 可供選擇。

AVF_EXPORT NSString *const AVAudioSessionCategoryAmbient;

/*  Use this category for background sounds.  Other music will stop playing. */
AVF_EXPORT NSString *const AVAudioSessionCategorySoloAmbient;

/* Use this category for music tracks.*/
AVF_EXPORT NSString *const AVAudioSessionCategoryPlayback;

/*  Use this category when recording audio. */
AVF_EXPORT NSString *const AVAudioSessionCategoryRecord;

/*  Use this category when recording and playing back audio. */
AVF_EXPORT NSString *const AVAudioSessionCategoryPlayAndRecord;

/*  Use this category when using a hardware codec or signal processor while
 not playing or recording audio. */
AVF_EXPORT NSString *const AVAudioSessionCategoryAudioProcessing NS_DEPRECATED_IOS(3_0, 10_0) __TVOS_PROHIBITED __WATCHOS_PROHIBITED;

/*  Use this category to customize the usage of available audio accessories and built-in audio hardware.
 For example, this category provides an application with the ability to use an available USB output 
 and headphone output simultaneously for separate, distinct streams of audio data. Use of 
 this category by an application requires a more detailed knowledge of, and interaction with, 
 the capabilities of the available audio routes.  May be used for input, output, or both.
 Note that not all output types and output combinations are eligible for multi-route.  Input is limited
 to the last-in input port. Eligible inputs consist of the following:
    AVAudioSessionPortUSBAudio, AVAudioSessionPortHeadsetMic, and AVAudioSessionPortBuiltInMic.  
 Eligible outputs consist of the following: 
    AVAudioSessionPortUSBAudio, AVAudioSessionPortLineOut, AVAudioSessionPortHeadphones, AVAudioSessionPortHDMI, 
    and AVAudioSessionPortBuiltInSpeaker.  
 Note that AVAudioSessionPortBuiltInSpeaker is only allowed to be used when there are no other eligible 
 outputs connected.  */
AVF_EXPORT NSString *const AVAudioSessionCategoryMultiRoute
  • AVAudioSessionCategoryAmbient 僅支持播放,不會打斷不支持混音的App,使用這種模式,你的App的聲音會與背后的音樂App一起發出聲音。 如果是在鎖屏或者靜音鍵的情況下你App的音頻會終止。
  • AVAudioSessionCategorySoloAmbient 僅支持播放,會打斷不支持混音的App,使用這種模式,你的App的聲音會打斷背后的音樂App。 如果是在鎖屏或者靜音鍵的情況下你App的音頻會終止。 這種模式是系統的默認模式。
  • AVAudioSessionCategoryPlayback 僅支持播放,默認會打斷不支持混音的App。如果是在鎖屏或者靜音鍵的情況下你App的音頻不會終止。
  • AVAudioSessionCategoryRecord 僅支持錄制,會打斷不支持混音的App。如果是在鎖屏或者靜音鍵的情況下仍可錄制。
  • AVAudioSessionCategoryPlayAndRecord 支持播放且支持錄制,默認會打斷不支持混音的App。如果是在鎖屏或者靜音鍵的情況下仍可播放聲音或者錄制。
  • AVAudioSessionCategoryMultiRoute 支持播放且支持錄制,會打斷不支持混音的App。如果是在鎖屏或者靜音鍵的情況下仍可播放聲音或者錄制。
  • AVAudioSessionCategoryAudioProcessing 不支持播放且不支持錄音,會打斷不支持混音的App。iOS10 之后被棄用。
2.AVAudioSession 的 AVAudioSessionCategoryOptions

AVAudioSession 的AVAudioSessionCategoryOptions 同樣也是一個枚舉。

    /* MixWithOthers is only valid with AVAudioSessionCategoryPlayAndRecord, AVAudioSessionCategoryPlayback, and  AVAudioSessionCategoryMultiRoute */
    AVAudioSessionCategoryOptionMixWithOthers           = 0x1,

    /* DuckOthers is only valid with AVAudioSessionCategoryAmbient, AVAudioSessionCategoryPlayAndRecord, AVAudioSessionCategoryPlayback, and AVAudioSessionCategoryMultiRoute */
    AVAudioSessionCategoryOptionDuckOthers              = 0x2,

    /* AllowBluetooth is only valid with AVAudioSessionCategoryRecord and AVAudioSessionCategoryPlayAndRecord */
    AVAudioSessionCategoryOptionAllowBluetooth  __TVOS_PROHIBITED __WATCHOS_PROHIBITED      = 0x4,

    /* DefaultToSpeaker is only valid with AVAudioSessionCategoryPlayAndRecord */
    AVAudioSessionCategoryOptionDefaultToSpeaker __TVOS_PROHIBITED __WATCHOS_PROHIBITED     = 0x8,

    /* InterruptSpokenAudioAndMixWithOthers is only valid with AVAudioSessionCategoryPlayAndRecord, AVAudioSessionCategoryPlayback, and AVAudioSessionCategoryMultiRoute */
    AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers NS_AVAILABLE_IOS(9_0) = 0x11,

    /* AllowBluetoothA2DP is only valid with AVAudioSessionCategoryPlayAndRecord */
    AVAudioSessionCategoryOptionAllowBluetoothA2DP API_AVAILABLE(ios(10.0), watchos(3.0), tvos(10.0)) = 0x20,

    /* AllowAirPlay is only valid with AVAudioSessionCategoryPlayAndRecord */
    AVAudioSessionCategoryOptionAllowAirPlay API_AVAILABLE(ios(10.0), tvos(10.0)) __WATCHOS_PROHIBITED = 0x40,
  • AVAudioSessionCategoryOptionMixWithOthers 當你的App包含聲音播放時,設置這個選項在激活會話時不會打斷其他App的音頻播放。
    適用于以下category:
    • AVAudioSessionCategoryPlayback
    • AVAudioSessionCategoryPlayAndRecord
    • AVAudioSessionCategoryMultiRoute
  • AVAudioSessionCategoryOptionDuckOthers 當你的App包含聲音播放時,設置這個選項在激活會話時會降低其他App的聲音播放。
    適用于以下category:
    • AVAudioSessionCategoryAmbient
    • AVAudioSessionCategoryPlayAndRecord
    • AVAudioSessionCategoryPlayback
    • AVAudioSessionCategoryMultiRoute
  • AVAudioSessionCategoryOptionAllowBluetooth 允許可免提藍牙設備可使用輸入通道
    適用于以下category:
    • AVAudioSessionCategoryRecord
    • AVAudioSessionCategoryPlayAndRecord
  • AVAudioSessionCategoryOptionDefaultToSpeaker 在沒有其他通道的時候默認選擇內置揚聲器
    適用于以下category:
    • AVAudioSessionCategoryPlayAndRecord
  • AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers 你的App偶爾的使用音頻播放。
    適用于以下category:
    • AVAudioSessionCategoryPlayback
    • AVAudioSessionCategoryPlayAndRecord
    • AVAudioSessionCategoryMultiRoute
  • AVAudioSessionCategoryOptionAllowBluetoothA2DP 立體聲藍牙。
    適用于以下category:
    • AVAudioSessionCategoryPlayAndRecord
  • AVAudioSessionCategoryOptionAllowAirPlay 遠程AirPlay設備。
    適用于以下category:
    • AVAudioSessionCategoryPlayAndRecord
3. 使用AVAudioSession 的 Category 和 AVAudioSessionCategoryOptions 調整各種音頻模式
1.播放音視頻的時候直接中斷背后的音樂播放。

這種情況下,我們直接將category 設置為 AVAudioSessionCategorySoloAmbient即可,當然你不做任何處理系統也會進行默認模式處理。很多App也是這種模式。

    AVAudioSession *session = [AVAudioSession sharedInstance];
    NSError * error = nil;
    [session setCategory:AVAudioSessionCategorySoloAmbient error:&error];
    if (error) {
        NSLog(@"%@",error);
    }
2.播放音視頻的時候暫時中斷背后的音樂,播放完畢后再繼續背后的音樂。

這種情況下,category設置與1的相同,然后在播放前 增加下面的代碼告訴背后的音樂App你將要占用音頻焦點。

[[AVAudioSession sharedInstance] setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];

在暫停播放或者App退到后臺后暫停播放前,告訴背后的音樂App你取消音頻焦點的占用。

[[AVAudioSession sharedInstance] setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];
3.播放音視頻的時候與背后音樂App混音一起播放

這種情況下,我們直接將category 設置為 AVAudioSessionCategoryAmbient即可。

    AVAudioSession *session = [AVAudioSession sharedInstance];
    NSError * error = nil;
    [session setCategory:AVAudioSessionCategoryAmbient error:&error];
    if (error) {
        NSLog(@"%@",error);
    }
4.播放音視頻的時候暫時壓低背后音樂的聲音,等音視頻播放完畢恢復背后音樂的聲音大小

這種情況下,需要設置category為AVAudioSessionCategoryAmbient,AVAudioSessionCategoryOptions設置為AVAudioSessionCategoryOptionDuckOthers

 AVAudioSession *session = [AVAudioSession sharedInstance];
    NSError * error = nil;
    [session setCategory:AVAudioSessionCategoryAmbient withOptions:AVAudioSessionCategoryOptionDuckOthers error:&error];
    if (error) {
        NSLog(@"%@",error);
    }

然后在播放前 增加下面的代碼告訴背后的音樂App你將要占用音頻焦點。

[[AVAudioSession sharedInstance] setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];

在暫停播放或者App退到后臺后暫停播放前,告訴背后的音樂App你取消音頻焦點的占用。

[[AVAudioSession sharedInstance] setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];

以上是一些AVAudioSession 的 Category 和 AVAudioSessionCategoryOptions 配合使用的幾種模式的舉例,具體要根據自己的實際需要進行調整。Demo下載地址

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,488評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,034評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,327評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,554評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,337評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,883評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,975評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,114評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,625評論 1 332
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,555評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,737評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,244評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,973評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,615評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,343評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,699評論 2 370

推薦閱讀更多精彩內容