1. 程式人生 > >iOS AvPlayer AvAudioPlayer音頻的後臺播放問題

iOS AvPlayer AvAudioPlayer音頻的後臺播放問題

ati aud pear 運行 uibutton task img ext 就會

王桂敏

iOS AvPlayer AvAudioPlayer音頻的後臺播放問題

iOS 4開始引入的multitask,我們可以實現像ipod程序那樣在後臺播放音頻了。如果音頻操作是用蘋果官方的AVFoundation.framework實現,像用AvAudioPlayer,AvPlayer播放的話,要實現完美的後臺音頻播放,依據app的功能需要,可能需要實現幾個關鍵的功能。

首先,播放音頻之前先要設置AVAudioSession模式,通常只用來播放的App可以設為AVAudioSessionCategoryPlayback即可。模式意義及其他模式請參考文檔。

  1. AVAudioSession *session = [AVAudioSession sharedInstance];
  2. [session setCategory:AVAudioSessionCategoryPlayback error:nil];
  3. [session setActive:YES error:nil];

1。通知OS該app支持background audio。缺省情況下,當按下home鍵時,當前正在運行的程序被suspend,狀態從active變成in-active,也就是說如果正在播放音頻,按下HOME後就會停止。這裏需要讓app在按在HOME後,轉到後臺運行而非被suspend,解決辦法是在程序的-info.plist中增加required background modes這個key項,並選擇App plays audio這個value項。

技術分享

2。現在按下HOME鍵後,程序退到後臺,但是聲音仍在播放。但是如果要實現播放列表的依次播放、循環播放,即放完一首後自動切換到下一首,問題來了,當App在後臺放完一首後,就會停下來。原因是在後臺運行時,一旦聲音停下來,程序也隨之suspend,因此在切換文件加載的間隙,程序就會被suspend。曾經有山寨的解決辦法是專門起一個player的實例連續不停的放同一無聲音片斷,阻止程序被suspend。這裏提供的方法是通過申請後臺taskID達到後臺切換播放文件的功能。

即聲明後臺task id,並通過beginBackgroundTaskWithExpirationHandler將App設為後臺Task,達到持續後臺運行的目的。我們知道一般情況下,按HOME將程序送到後臺,可以有5或10秒時間可以進行一些收尾工作,具體時間[[UIApplication sharedApplication] backgroundTimeRemaining]返回值。超時後app會被suspend,現在要做的就是用[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL]開始後臺任務,可以將後臺運行超時時間長時間的延長,具體延長多少時間還是見返回值,總之對於放段時間音樂應該夠了。另一個問題是每個開始的後臺任務,都必須用endBackgroundTask來結束。 因此,在每次開始播放後啟動新的後臺任務,同時結束上一個後臺任務:

首先,要在viewdidload中

  1. [UIApplication sharedApplication] beginReceivingRemoteControlEvents];
否則,無法切換到下一首,接下來

  1. UIBackgroundTaskIdentifier newTaskId = UIBackgroundTaskInvalid;
  2. [avPlayer play];
  3. newTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];
  4. if (newTaskId != UIBackgroundTaskInvalid && oldTaskId != UIBackgroundTaskInvalid) {
  5. [[UIApplication sharedApplication] endBackgroundTask: oldTaskId];}
  6. oldTaskId = newTaskId;

當然,還有更方便的辦法就是在resignActive時beginBackgroundTaskWithExpirationHandler:並在BecomeActive中endBackgroundTask:

3。我們知道,ipod播放程序在後臺時,雙擊HOME鍵,會有個控制界面,可以對它進行播放控制。

技術分享

如果您想讓您的app可以像ipod一樣在後臺也可以方便的通過雙擊HOME鍵來控制,就要用到遠程控制事件了。

首先在viewdidload等初始化的地方聲明App接收遠程控制事件,並在相應地方結束聲明

  1. - (void) viewWillAppear:(BOOL)animated
  2. {
  3. [super viewWillAppear:animated];
  4. [UIApplication sharedApplication] beginReceivingRemoteControlEvents];
  5. [self becomeFirstResponder];
  6. }
  7. - (void) viewWillDisappear:(BOOL)animated
  8. {
  9. [super viewWillDisappear:animated];
  10. [UIApplication sharedApplication] endReceivingRemoteControlEvents];
  11. [self resignFirstResponder];
  12. }

定義

  1. - (BOOL)canBecomeFirstResponder
  2. {
  3. return YES;
  4. }

最後定義 remoteControlReceivedWithEvent,處理具體的播放、暫停、前進、後退等具體事件

  1. - (void) remoteControlReceivedWithEvent: (UIEvent *) receivedEvent {
  2. if (receivedEvent.type == UIEventTypeRemoteControl) {
  3. switch (receivedEvent.subtype) {
  4. case UIEventSubtypeRemoteControlTogglePlayPause:
  5. [self playButtonPressed:playButton];
  6. [self testing];
  7. break;
  8. case UIEventSubtypeRemoteControlPreviousTrack:
  9. [self rewButtonReleased:(UIButton *)rewButton];
  10. break;
  11. case UIEventSubtypeRemoteControlNextTrack:
  12. [self ffwButtonReleased:(UIButton *)ffwButton];
  13. break;
  14. default:
  15. break;
  16. }
  17. }
  18. }

4. 至此,您有播放App已經相當完美了,還有最後一個問題,那就是當用戶使用耳機時,問題又來了。系統默認當插入耳機時,正在播放的聲音不中斷,直接切換到耳機播放,而當拔出耳機時,播放停止。如果這種行為滿足您的要求,那OK,否則您就需要進一步研究耳機檢測和聲音路由切換的問題。

iOS AvPlayer AvAudioPlayer音頻的後臺播放問題