1. 程式人生 > >iOS 播放音訊的幾種方法

iOS 播放音訊的幾種方法

  • System Sound Services
  • AVAudioPlayer 類
  • Audio Queue Services
  • OpenAL

1. System Sound Services

System Sound Services是最底層也是最簡單的聲音播放服務,呼叫 AudioServicesPlaySystemSound 這個方法就可以播放一些簡單的音訊檔案,使用此方法只適合播放一些很小的提示或者警告音,因為它有很多限制:

■ 聲音長度要小於 30 秒
■ In linear PCM 或者 IMA4 (IMA/ADPCM) 格式的
■ 打包成 .caf, .aif, 或者 .wav 的檔案
■ 不能控制播放的進度
■ 呼叫方法後立即播放聲音
■ 沒有迴圈播放和立體聲控制

另外,它還可以呼叫系統的震動功能,方法也很簡單。具體的程式碼可以參考官方的示例 SysSound
,但是官方的示例只有一些簡單的用法,從文件中我們發現可以通過 AudioServicesAddSystemSoundCompletion 方法為音訊播放新增CallBack 函式,有了 CallBack 函式我們可以解決不少問題,比如可以克服 System Sound Services本身不支援迴圈播放的問題。

2. AVAudioPlayer 類

AVAudioPlayer 是 AVFoundation.framework 中定義的一個類,所以使用要先在工程中引入AVFoundation.framework。我們可以把 AVAudioPlayer看作是一個高階的播放器,它支援廣泛的音訊格式,主要是以下這些格式:

■ AAC
■ AMR(AdaptiveMulti-Rate, aformatforspeech)
■ ALAC(AppleLossless)
■ iLBC(internetLowBitrateCodec, anotherformatforspeech)
■ IMA4(IMA/ADPCM)
■ linearPCM(uncompressed)
■ µ-lawanda-law
■ MP3(MPEG-1audiolayer3

AVAudioPlayer可以播放任意長度的音訊檔案、支援迴圈播放、可以同步播放多個音訊檔案、控制播放進度以及從音訊檔案的任意一點開始播放等,更高階的功能可以參考 AVAudioPlayer的文件 

。要使用 AVAudioPlayer的物件播放檔案,你只需為其指定一個音訊檔案並設定一個實現了 AVAudioPlayerDelegate協議的 delegate 物件。

只要將 AVAudioPlayer 的 numberOfLoops屬性設為負數,音訊檔案就會一直迴圈播放直到呼叫 stop 方法。

AVAudioPlayer 同樣支援Callback,這是 AVAudioPlayerDelegate 的一個可選delegate 方法:

- (void )audioPlayerDidFinishPlaying: (AVAudioPlayer *) player successfully:(BOOL ) flag{ 

    if  (player== self .player&& flag == YES) { 

        NSLog(@"Playbackfinish." );

    } 

}

另外,你可以隨時控制 AVAudioPlayer物件的播放、暫停以及停止,通過判斷物件的狀態,分別呼叫 play、pause 和 stop 方法即可:

- (IBAction) playOrPause:(id ) sender{ 

    //if playing, pause 

    if  (self .player.playing){ 

        [self .playerpause]; 

    //if stopped or paused, startplaying 

    } else  { 

        [self .playerplay]; 

    }

雖然 AVAudioPlayer可以播放很多格式,但是我們在實際開發過程中還是最好使用一些沒有壓縮的格式,比如 WAVE檔案,這樣可以減少系統處理單元的資源佔用,以便更好的完成程式的其他功能。另外,在使用 AVAudioPlayer 連續播放 mp3這類經過壓縮的音訊檔案時,在連線處可能出現一定的間隔時間。

3. Audio Queue Services

如果以上兩種音訊播放的解決方案都無法滿足你的需求,那麼我想你肯定需要使用 Audio QueueServices。使用 Audio Queue Services對音訊進行播放,你可以完全實現對聲音的控制。例如,你可以在聲音資料從檔案讀到記憶體緩衝區後對聲音進行一定處理再進行播放,從而實現對音訊的快速/慢速播放的功能。

4. OpenAL

OpenAL 是一套跨平臺的開源的音訊處理介面,與圖形處理的 OpenGL類似,它為音訊播放提供了一套更加優化的方案。它最適合開發遊戲的音效,用法也與其他平臺下相同。

本篇主要講AVAudioPlayer,

AVAudioPlayer類封裝了播放單個聲音的能力。播放器可以用NSURL或者NSData來初始化,要注意的是NSURL不可以是網路url而必須是本地檔案url,因為AVAudioPlayer不具備播放網路音訊的能力。

一個AVAudioPlayer只能播放一個音訊,如果你想混音你可以建立多個AVAudioPlayer例項,每個相當於混音板上的一個軌道。

一、建立一個播放器

AVAudioPlayer *player =[[AVAudioPlayerallocinitWithContentsOfURL:[NSURLfileURLWithPath:[[NSBundlemainBundlepathForResource:@"星月神話" ofType:@"mp3"]]error:nil];//使用本地URL建立


AVAudioPlayer *player= [[AVAudioPlayer alloc] initWithData:Data error:nil];//使用NSData建立

我之前講過AVAudio不可以播放網路URL,但是可以播放NSData,我們似乎受到了啟發,我們可以通過網路URL去建立NSData,然後再通過AVAudioPlayer來播放NSData,這樣是不是就可以播放網路音樂了?但是此法並不可取,因為AVAudioPlayer只能播放一個完整的檔案,並不支援流式播放,所以必須是緩衝完才能播放,所以如果網路檔案過大抑或是網速不夠豈不是要等很久?所以播放網路音訊我們一般用音訊佇列。

二、播放器屬性

建立一個AVAudioPlayer以後你就可以對它的各種屬性進行訪問或設定了。

1、音量

player.volume =0.8;//0.0-1.0之間

2、迴圈次數

player.numberOfLoops =3;//預設只播放一次

3、播放位置  

 player.currentTime =15.0;//可以指定從任意位置開始播放

4、聲道數

NSUInteger channels= player.numberOfChannels;//只讀屬性


5、持續時間

NSTimeInterval duration =player.duration;//獲取持續時間


6、儀表計數

player.meteringEnabled =YES;//開啟儀表計數功能

[playerupdateMeters];//更新儀表計數


三、播放聲音

[player prepareToPlay];//分配播放所需的資源,並將其加入內部播放佇列

[playerplay];//播放

[playerstop];//停止


四、代理方法

這個類對應的AVAudioPlayerDelegater的委託方法。audioPlayerDidFinishPlaying:successfully:當音訊播放完成之後觸發。當播放完成之後,可以將播放按鈕的文字重新回設定成:Play Audio File

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag

{

   //播放結束時執行的動作

   [audioButton setTitle:@"PlayAudio File" forState:UIControlStateNormal];

}

- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)playererror:(NSError *)error;

{

    //解碼錯誤執行的動作

}


- (void)audioPlayerBeginInterruption:(AVAudioPlayer *)player;

{

    //處理中斷的程式碼

}


audioPlayerEndInterruption:,當程式被應用外部打斷之後,重新回到應用程式的時候觸發。在這裡當回到此應用程式的時候,繼續播放音樂。

- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player

{

   [audioPlayer play];

}

 AVAudioPlayer就介紹到這吧。