2014年1月17日 星期五

iOS -- 播放聲音的 API

在 iOS 設備上有許多播放聲音的方法,那麼應該選擇什麼樣的方式呢?
以下根據個人的經驗,分析不同情景下適用的處理方式。

iOS 可以使用數種方法播放聲音,根據用法的難易度,由簡單到困難列舉如下:
  • System Sound Service
  • AVAudioPlayer
  • AVPlayer
  • Audio Queue Service
  • OpenAL
  • Audio Unit
下圖為 Audio Framework,可由此得知不同方法之間的階層關係

System Sound Service (Available in iOS 2.0 and later)

此服務提供使用者播放系統音效,並且針對音頻內容有以下限制
  • 音頻數據格式必須是linear PCM 或者 IMA4.
  • 音頻文件格式必須是CAF,AIF,或者 WAV。
  • 音頻長度必須小於 30 秒 (註:手機鈴聲??)
適用情況:用於播放系統音效,例如按下按鍵、收到訊息時的音效,另外還可以控制手機震動
程式範例: 
// 定義音頻檔案路徑
NSString *path = [[NSBundlemainBundle]pathForResource:@"systemSound"
ofType:@"caf"];

// 建立 SystemSoundID 並關聯到正確的音效檔案路徑
SystemSoundID soundID;
AudioServicesCreateSystemSoundID((__bridgeCFURLRef)[NSURLfileURLWithPath:path], &soundID);

// 播放音頻
AudioServicesPlaySystemSound(soundID);

//若要同時播放音頻與震動
AudioServicesPlayAlertSound(soundID);

//若只需要震動
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

AVAudioPlayer (Available in iOS 2.2 and later)

支援的音頻數據格式
  • ALAC (Apple Lossless)
  • HE-AAC (MPEG-4 High Efficiency AAC)
  • iLBC (internet Low Bitrate Codec, another format for speech)
  • IMA4 (IMA/ADPCM)
  • Linear PCM (uncompressed, linear pulse-code modulation)
  • MP3 (MPEG-1 audio layer 3)
  • µ-law and a-law
  • AAC (MPEG-4 Advanced Audio Coding)
iOS 針對 AAC, MP3, ALAC 會使用硬體進行解碼。
適用情況: 
播放系統內或是遠端的音樂檔案,
程式範例:(參考 avtouch)
// 定義音頻檔案路徑
NSString *fileURL = [[NSBundlemainBundle]pathForResource:@"test"
ofType:@"caf"];

// 建立 AVAudioPlayer 
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
player.delegate = self;

// 播放音頻
[player play]

// 暫停播放
[player pause]

// 停止播放
[player stop]

AVPlayer (Available in iOS 4.0 and later)

支援的音頻數據格式
  • ALAC (Apple Lossless)
  • HE-AAC (MPEG-4 High Efficiency AAC)
  • iLBC (internet Low Bitrate Codec, another format for speech)
  • IMA4 (IMA/ADPCM)
  • Linear PCM (uncompressed, linear pulse-code modulation)
  • MP3 (MPEG-1 audio layer 3)
  • µ-law and a-law
  • AAC (MPEG-4 Advanced Audio Coding)
iOS 針對 AAC, MP3, ALAC 會使用硬體進行解碼。
適用情況: 
播放系統內或是遠端的多媒體檔案,可用來控制影像與聲音的同步。當需要播放的檔案同時有影像與聲音時,便選擇此方式。
程式範例: 
請直接參考 AVPlayerDemo

Audio Queue Service (Available in iOS 2.0 and later)

支援的音頻數據格式,摘錄Apple官方文件說明如下
  • Linear PCM.
  • Any compressed format supported natively on the Apple platform you are developing for. (此部份應該就是AVAudioPlayer支援的格式)
  • Any other format for which a user has an installed codec. (codec就是軟體解碼模組,例如ffmpeg)
適用情況: 
播放系統內的音樂,此音樂可以是一個檔案或是一段緩衝區。若要播放網路收到的音頻,就得要使用此種方式。
程式範例: 
請參考這篇 FFMPEG --  在 iOS 設備上播放 AAC 音樂

OpenAL

支援的音頻數據格式: 
OpenAL 是跨平台的音頻播放API,並沒有硬性規定支援的數據格式,其支援程度應該與Audio Queue Service相同,只要平台上有對應的 decode codec,就可能可以進行播放。
適用情況:
播放系統內的音樂,此音樂可以是一個檔案或是一段緩衝區。若有跨平台的需要,才採用此方式。
程式範例: 
參考此篇 http://ohno789.blogspot.tw/2013/08/openal-on-ios.html

Audio Unit

最底層的音頻處理方式 ,支援的音頻數據格式:
上述所有音頻格式。
適用情況: 
需要即時的反應時間,或是動態的更改音頻設定時,例如:實作VoIP服務。
程式範例: 
請參考https://developer.apple.com/library/mac/samplecode/sc2195/Introduction/Intro.html 

參考資料: