2016年3月9日 星期三

iOS - Enable AirPlay for your APP

之前寫了一個簡單的音樂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,沒想到一直試不出來,只好作罷。如果有好心人試出這個功能,麻煩請教教我啊,謝謝。

參考資料
  1. Audio Session Categories and Modes
  2. Jawbone/AudioSessionManager 
  3. AudioSessionProgrammingGuide
  4. EnrichYourAppforAirPlay


[Embedded] how to check heap corruption

上週的 linux news 提到 iOS 上的一個問題,Analysis of iOS & OS X Vulnerability: CVE-2016-1722,指出了 heap overflow 的問題。這篇新聞提醒了自己,應該要將之前的實戰經驗做一下整理了。本篇會針對如何找到 heap corruption 的方法作一整理。