簡介
IOS 通過 <em>音頻會話(Audio Session)</em> 和 <code>AVAudioSession</code> 中的 <strong>API</strong> 來實現對于不同 App 之間、同一 App 內及硬件層面的各種音頻行為。
kk說:為了語句的通順,Audio一詞在本系列文章中可能會被翻譯為音頻或聲音,特此說明。
<code>AVAudioSession</code> 中的 API 可以處理類似這樣的問題:
- 手機在從鈴聲切換到靜音模式時,App 中的音頻是否需要靜音?舉例來說,旨在幫助用戶在會議中做筆記的 App 應當在手機處于靜音模式時靜音,以免打擾他人;而具有發音功能的詞典類 App,則應保證不被手機的模式影響,在用戶需要的時候播放聲音。
- 當 App 開始播放聲音的時候,系統已經在播放的其他聲音是否需要關閉?用于讓用戶跟著背景音樂利用 App 中的功能來進行合奏的 App 中,背景音樂當然要繼續;但如果 App 的功能是網絡電臺,那么就應該讓其他的聲音都停止。
IOS 設備中的音頻使用場景十分復雜:用戶隨時可能插拔耳機、接打電話,系統的鬧鐘也可能在使用其他音頻的過程中響起。開發者只需要編寫少量調用音頻會話 API 的代碼,就可以配置音頻會話的屬性,從而優雅的對系統請求作出回應。
概覽
使用 <code>AVAudioSession</code> 可以:
- 選擇合適的音頻輸入輸出源(route)
- 決定如何從其他 App 中集成音頻
- 處理來自其他 App 的“騷擾”
- 為某一類型的 App 自動配置音頻屬性?(automatically configure audio for the type of app you are creating)
一次音頻會話中包含了一系列的音頻行為
音頻會話是 App 和 IOS 之間的媒介,用來為 App 配置相關的音頻屬性和行為。在加載過程中,App 會自動創建一個音頻會話的單例。
用類別(categories)來描述音頻 role
<i>音頻會話類別</i>是用來描述音頻行為的主要機制。通過設置類別可以表明:App是否使用音頻輸入輸出源,在播放音頻時是否支持其他背景音樂的播放,以及一些其他的屬性。開發者設計的音頻行為應當符合用戶的期望。
開發者可以通過七個類別和一些override and modifier switches,結合 App 的身份來定制音頻 role。不同的類別分別支持后臺播放(playback)、錄音和后臺錄音等功能。當系統了解 App 的音頻 role 后,會為其提供合適的硬件資源,令其免于受到設備上的其他音頻事件的干擾。
kk說:想不出合適的詞來表達 role 的含義,用“身份”或“角色”都顯得有些模糊,因此不做翻譯
音頻類別的套路(Modes Customize Categories)
用戶對于特定種類的 App 中(聲音的)處理方式會有特定的期待。某一類別的行為會表現為一種套路。舉例來說,系統可能會為使用默認模式和錄像模式的 App 選擇不同的麥克風作為音頻輸入,或者為用于錄像場景的 App 啟用麥克風信號處理。
kk說:這一段翻譯不好,原文如下:
Users expect certain behaviors from certain categories of apps. Modes specialize the behavior of a given category. For example, when an app uses the Video Recording mode, the system may choose a different built-in microphone than it would if it was using the default mode. The system may also engage microphone signal processing that is tuned for video recording use cases.
基于通知(Notifications)的中斷處理機制(interruption handling)
<i>音頻中斷(audio interruption)</i>指的是音頻會話被關閉的行為,會導致 App 中的音頻立即停止。當一個未被系統歸類為可以和自己混合的其他音頻會話啟用時,就會中斷當前的 App。當中斷發生時,系統會向 App 發出一個“你被中斷”信號,App可以在接到這個信號的時候完成保存狀態、更新UI等操作。
開發者可以通過向 <code>AVAudioSession </code> 中的 <code>AVAudioSessionInterruptionNotification </code> 注冊來處理中斷。開發者應該重寫 <code>beginInterruption</code> 和 <code>endInterruption</code> 方法,來減小對用戶造成的中斷,并提供最優雅的中斷恢復方案。
基于通知的音頻源切換處理
用戶在插拔外接音頻設備或插拔耳機的時候,會期待系統能夠按自己的想法進行輸入輸出源的切換。IOS Human Interface Guidelines 中關于聲音的章節描述了這些用戶期待,并提供了一些關于如何滿足這個期待的指導。通過向 <code>AVAudioSessionRouteChangeNotification </code> 中注冊來處理音頻源的切換。
對類別的特性進行調整
開發者可以用不同的方式來對音頻會話類別進行調整,來改變類別的屬性,包括:
- 允許(缺省條件下不能與其他音頻混合的)類別與其他(來自QQ音樂等 App 的)音頻混合。
- 將音頻的輸出源從輸入源改為擴音器。
- 允許藍牙音頻輸入源。
- 在播放 App 的音頻時,要求降低其他的 App 音頻的音量。
- 在運行時為 App 選擇最優的硬件設備。在 App 運行時,開發者的代碼可以根據當前的設備環境及用戶插拔設備引發的變化,進行動態的調整和適應。
前置知識
在學習這些內容前,開發者需要對 Cocoa Touch 開發有一定的了解(App Programming Guide for IOS 中關于Core Audio和Core Audio Overview中的章節)。同時,由于音頻會話通常會基于終端用戶實際的使用場景,因此也需要對IOS設備,和 IOS Human Interface Guidelines有所了解。
其他
參見以下資料:
- AVAudioSession Class Reference,官方手冊中關于AudioSession類的介紹
- AddMusic,樣例代碼,展示如何協調app間的音頻操作
kk說:以上內容翻譯自蘋果官方文檔,僅供學習,請勿用于商業用途,侵刪。轉載注明出處。