首先,播放音频以前先要设置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,不然您就须要进一步研究耳机检测和声音路由切换的问题。事件