首先,播放音頻以前先要設置AVAudioSession模式,一般只用來播放的App能夠設爲AVAudioSessionCategoryPlayback便可。模式意義及其餘模式請參考文檔。session
- AVAudioSession *session = [AVAudioSession sharedInstance];
- [session setCategory:AVAudioSessionCategoryPlayback error:nil];
- [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項。app
2。如今按下HOME鍵後,程序退到後臺,可是聲音仍在播放。可是若是要實現播放列表的依次播放、循環播放,即放完一首後自動切換到下一首,問題來了,當App在後臺放完一首後,就會停下來。緣由是在後臺運行時,一旦聲音停下來,程序也隨之suspend,所以在切換文件加載的間隙,程序就會被suspend。曾經有山寨的解決辦法是專門起一個player的實例連續不停的放同一無聲音片段,阻止程序被suspend。這裏提供的方法是經過申請後臺taskID達到後臺切換播放文件的功能。oop
即聲明後臺task id,並經過beginBackgroundTaskWithExpirationHandler將App設爲後臺Task,達到持續後臺運行的目的。咱們知道通常狀況下,按HOME將程序送到後臺,能夠有5或10秒時間能夠進行一些收尾工做,具體時間[[UIApplication sharedApplication] backgroundTimeRemaining]返回值。超時後app會被suspend,如今要作的就是用[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL]開始後臺任務,能夠將後臺運行超時時間長時間的延長,具體延長多少時間仍是見返回值,總之對於放段時間音樂應該夠了。另外一個問題是每一個開始的後臺任務,都必須用endBackgroundTask來結束。 所以,在每次開始播放後啓動新的後臺任務,同時結束上一個後臺任務:
首先,要在viewdidload中ui
- [UIApplication sharedApplication] beginReceivingRemoteControlEvents];
不然,沒法切換到下一首,接下來
- UIBackgroundTaskIdentifier newTaskId = UIBackgroundTaskInvalid;
-
- [avPlayer play];
- newTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];
- if (newTaskId != UIBackgroundTaskInvalid && oldTaskId != UIBackgroundTaskInvalid) {
- [[UIApplication sharedApplication] endBackgroundTask: oldTaskId];}
- oldTaskId = newTaskId;
固然,還有更方便的辦法就是在resignActive時beginBackgroundTaskWithExpirationHandler:並在BecomeActive中endBackgroundTask: spa
3。咱們知道,ipod播放程序在後臺時,雙擊HOME鍵,會有個控制界面,能夠對它進行播放控制。
若是您想讓您的app能夠像ipod同樣在後臺也能夠方便的經過雙擊HOME鍵來控制,就要用到遠程控制事件了。.net
首先在viewdidload等初始化的地方聲明App接收遠程控制事件,並在相應地方結束聲明blog
- - (void) viewWillAppear:(BOOL)animated
- {
- [super viewWillAppear:animated];
- [UIApplication sharedApplication] beginReceivingRemoteControlEvents];
- [self becomeFirstResponder];
- }
-
- - (void) viewWillDisappear:(BOOL)animated
- {
- [super viewWillDisappear:animated];
- [UIApplication sharedApplication] endReceivingRemoteControlEvents];
- [self resignFirstResponder];
- }
定義
- - (BOOL)canBecomeFirstResponder
- {
- return YES;
- }
最後定義 remoteControlReceivedWithEvent,處理具體的播放、暫停、前進、後退等具體事件
- - (void) remoteControlReceivedWithEvent: (UIEvent *) receivedEvent {
- if (receivedEvent.type == UIEventTypeRemoteControl) {
-
- switch (receivedEvent.subtype) {
-
- case UIEventSubtypeRemoteControlTogglePlayPause:
- [self playButtonPressed:playButton];
- [self testing];
- break;
-
- case UIEventSubtypeRemoteControlPreviousTrack:
- [self rewButtonReleased:(UIButton *)rewButton];
- break;
-
- case UIEventSubtypeRemoteControlNextTrack:
- [self ffwButtonReleased:(UIButton *)ffwButton];
- break;
-
- default:
- break;
- }
- }
- }
4. 至此,您有播放App已經至關完美了,還有最後一個問題,那就是當用戶使用耳機時,問題又來了。系統默認當插入耳機時,正在播放的聲音不中斷,直接切換到耳機播放,而當拔出耳機時,播放中止。若是這種行爲知足您的要求,那OK,不然您就須要進一步研究耳機檢測和聲音路由切換的問題。事件