之前寫了一個簡單的音樂APP,可以在同時使用 AudioUnit 同時進行錄音與播放。使用手機測試錄音與播放是沒問題的,但是當我想要將程式改為在手機端錄音,透過 AirPlay 在電視上播放時卻發生問題,問題現象是手機上不會出現 AirPlay 選項。
以下記錄使用 Audio Unit 各種實驗與其結果:
1. 先了解 Audio 運作時可以設定的各種模式
摘錄 Apple 定義的 AudioSession Category/Mode 設定值
Table B-1 Audio session category behavior
Category identifiers
|
Silenced by the Ring/Silent switch and by screen locking see note
|
Interrupts non-mixable apps audio
|
Allows audio input (recording) and output (playback)
|
AVAudioSessionCategoryAmbient
|
Yes
|
No
|
Output only
|
AVAudioSessionCategoryAudioProcessing
|
–
|
Yes
|
No input and no output
|
AVAudioSessionCategoryMultiRoute
|
No
|
Yes
|
Input and output
|
AVAudioSessionCategoryPlayAndRecord
|
No
|
Yes by default; no by using override switch
|
Input and output
|
AVAudioSessionCategoryPlayback
|
No
|
Yes by default; no by using override switch
|
Output only
|
AVAudioSessionCategoryRecord
|
No (recording continues with the screen locked)
|
Yes
|
Input only
|
AVAudioSessionCategorySoloAmbient
|
Yes
|
Yes
|
Output only
|
Table B-2 Modes and associated categories
Mode identifiers
|
Compatible categories
|
AVAudioSessionModeDefault
|
All
|
AVAudioSessionModeVoiceChat
|
AVAudioSessionCategoryPlayAndRecord
|
AVAudioSessionModeGameChat
|
AVAudioSessionCategoryPlayAndRecord
|
AVAudioSessionModeVideoRecording
|
AVAudioSessionCategoryPlayAndRecord
AVAudioSessionCategoryRecord
|
AVAudioSessionModeMoviePlayback
|
AVAudioSessionCategoryPlayback
|
AVAudioSessionModeMeasurement
|
AVAudioSessionCategoryPlayAndRecord
AVAudioSessionCategoryRecord
AVAudioSessionCategoryPlayback
|
AVAudioSessionModeVideoChat
|
AVAudioSessionCategoryPlayAndRecord
|
因為此 APP 同時有 Audio In/Audio Out,所以能夠選擇的設定如下
- AVAudioSessionCategoryMultiRoute
- AVAudioSessionCategoryPlayAndRecord
- AVAudioSessionModeDefault
- AVAudioSessionModeVoiceChat
- AVAudioSessionModeGameChat
- AVAudioSessionModeVideoRecording
- AVAudioSessionModeMeasurement
- AVAudioSessionModeVideoChat
2. 測試不同 Audio Session Mode 與 Audio Unit 同時啟用時所造成的影響
以下僅為個人實驗結果,當 APP 啟動後,若設定為下列 Category/Mode 不會出現 Airplay選項。
- AVAudioSessionCategoryMultiRoute
- AVAudioSessionCategoryPlayAndRecord
- AVAudioSessionModeGameChat
- AVAudioSessionModeVideoRecording
- AVAudioSessionModeVoiceChat
圖例如下:

當 APP 啟動後,若設定為下列 Category/Mode 可以出現 Airplay選項。
- AVAudioSessionModeDefault
- AVAudioSessionModeMeasurement
- AVAudioSessionModeVideoChat
此時已經可以正常播放音樂,圖例如下:
但是一旦當APP開始進行錄音時,卻會變成只有 "iPhone" 與 "iPhone擴音"可選
圖例如下:

設定方式舉例如下:
[[sharedInstance] setCategory: AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker|AVAudioSessionCategoryOptionMixWithOthers error:&setCategoryErr];
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionModeDefault error:&setCategoryErr];
經過上述實驗,我會懷疑是否使用Audio Unit 進行錄音時,便無法使用Airplay。
3. 設定 APP Capabilities,設定 Background Modes 支援 Audio and Airplay,如下圖:

此作法也是沒用。
結論:本來想作好此功能之後,可以把家裡電視跟舊iPhone結合成卡拉OK,沒想到一直試不出來,只好作罷。如果有好心人試出這個功能,麻煩請教教我啊,謝謝。
參考資料
- Audio Session Categories and Modes
- Jawbone/AudioSessionManager
- AudioSessionProgrammingGuide
- EnrichYourAppforAirPlay