//  ViewController.h
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h> @class AVAudioPlayer; @interface PlayViewController : UIViewController<AVAudioPlayerDelegate> @property(nonatomic, strong) AVAudioPlayer *player; + (PlayViewController *)defaultPlayVC; //将该播放页面定义成单例 @end
//  ViewController.m
#import "PlayViewController.h" @interface PlayViewController () @property (retain, nonatomic) IBOutlet UIButton *suspendBtn; //暂停按钮
@property (retain, nonatomic) IBOutlet UIButton *formerBtn; //上一首按钮
@property (retain, nonatomic) IBOutlet UIButton *nextBtn; //下一首按钮
@property (retain, nonatomic) IBOutlet UISlider *slider; //滑块
@property (retain, nonatomic) NSArray *musicUrlArray; //音乐网址数组
@property (retain, nonatomic) NSArray *musicAllTimeArray; //音乐时间数组
@property (retain, nonatomic) NSTimer *timer; //计时器
@property (assign, nonatomic) int currentIndex; //当前音频下标 @end @implementation PlayViewController
#pragma mark 单例初始化方法
+ (PlayViewController *)defaultPlayVC {
static PlayViewController *playVC = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
playVC = [[PlayViewController alloc] init];
});
return playVC;
} - (void)viewDidLoad {
[super viewDidLoad];
self.currentIndex = 0;
self.musicUrlArray = [NSArray arrayWithObjects:@"http://fdfs.xmcdn.com/group10/M08/D4/2E/wKgDaVZ9EYaQ-j48AFIOaAXL-wM019.mp3",
@"http://fdfs.xmcdn.com/group13/M09/D4/17/wKgDXVZ6fR2wR1E8AFuO_VClRZA066.mp3",
@"http://fdfs.xmcdn.com/group16/M0A/D5/16/wKgDbFZ89SqyFGWGAHoEKd7yPsw709.mp3",
@"http://fdfs.xmcdn.com/group8/M01/D4/34/wKgDYFZ6y1nR6QpZAEDVy7rUTTc247.mp3",
@"http://fdfs.xmcdn.com/group9/M00/D4/EF/wKgDZlZ7aLGCQEEDAHMsQsurq_Y170.mp3",
@"http://fdfs.xmcdn.com/group12/M07/D4/C4/wKgDW1Z70rWxoDA7ABAp1lwS5nI990.mp3", nil];
self.musicAllTimeArray = [NSArray arrayWithObjects:@(1344.36), @(1500.04), @(1999.06), @(1062.22), @(1886.96), @(264.76), nil]; //滑块
self.slider.minimumValue = 0;
[self.slider addTarget:self action:@selector(changValue:) forControlEvents:UIControlEventValueChanged]; //添加滑动事件
[self.slider setThumbImage:[UIImage imageNamed:@"playProcessDot_n"]forState:UIControlStateNormal]; //播放音频之前先要设置AVAudioSession模式 是它可以后台播放
//并且要在plist文件中 添加required background modes这个key项,并选择"App plays audio or streams audio/video using AirPlay"这个value项。
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
[session setActive:YES error:nil]; [self playerCurrentMusic];
} -(void)playerCurrentMusic { //创建串行队列 (放入线程中,免得页面假死)
dispatch_queue_t serialQueue = dispatch_queue_create("com.audio.www", DISPATCH_QUEUE_SERIAL);
dispatch_async(serialQueue, ^{ NSString *url = self.musicUrlArray[self.currentIndex];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
self.player = [[AVAudioPlayer alloc] initWithData:data error:nil];
self.player.delegate = self;
[self.player prepareToPlay];
[self.player play]; //滑块
CGFloat allTime = [self.musicAllTimeArray[self.currentIndex] floatValue];
self.slider.maximumValue = allTime; //计时器只能在主线程中
dispatch_async(dispatch_get_main_queue(), ^{
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(reloadAction) userInfo:nil repeats:YES];
});
});
} #pragma mark -- 每1秒 给进度条赋一次值
-(void)reloadAction {
if ([self.player isPlaying]) {
self.slider.value = self.player.currentTime;
}
} #pragma mark 点击暂停
- (IBAction)suspendAction:(UIButton *)sender {
sender.selected = !sender.selected;
if (sender.selected) {
[self.player pause]; //暂停
[sender setTitle:@"播放" forState:UIControlStateSelected];
} else {
[self.player play]; //播放
[sender setTitle:@"暂停" forState:UIControlStateNormal];
}
} #pragma mark 点击上一首
- (IBAction)formerAction:(UIButton *)sender {
[self myPlayFormer]; //播放上一首
} #pragma mark 点击下一首
- (IBAction)nextAction:(UIButton *)sender {
[self myPlayNext]; //播放下一首
} #pragma mark 上一首
-(void)myPlayFormer {
if (self.currentIndex > 0) {
[self.player pause];
self.currentIndex--;
[self playerCurrentMusic];
}
}
#pragma mark 下一首
-(void)myPlayNext {
if (self.currentIndex < self.musicUrlArray.count - 1) {
[self.player pause];
self.currentIndex++;
[self playerCurrentMusic];
}
} /***************** 控制台 *****************/
#pragma mark -- 声明App接收远程控制事件
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
} #pragma mark -- App结束声明接收远程控制事件
- (void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
[self resignFirstResponder];
} #pragma mark -- 接受控制台的控制事件
- (void)remoteControlReceivedWithEvent: (UIEvent *) receivedEvent {
if (receivedEvent.type == UIEventTypeRemoteControl) {
//判断点击按钮的类型
switch (receivedEvent.subtype) { case UIEventSubtypeRemoteControlPlay:
[self.player play]; //播放
break;
case UIEventSubtypeRemoteControlPause:
[self.player pause]; //暂停
break;
case UIEventSubtypeRemoteControlPreviousTrack:
[self myPlayFormer]; //播放上一首
break;
case UIEventSubtypeRemoteControlNextTrack:
[self myPlayNext]; //播放下一首
break;
default:
break;
}
}
} #pragma mark 实现后台播放完一首后, 继续播放下一首
- (BOOL)canBecomeFirstResponder {
return YES;
} /***************** AVAudioPlayer 代理 *****************/
#pragma mark -- 后台播放被打断, 继续恢复播放 (比如打电话...)
- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player withOptions:(NSUInteger)flags {
[self.player play];
}
#pragma mark -- 播放完当前声音后,播放下一首
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
if (self.currentIndex < self.musicUrlArray.count - 1) {
self.currentIndex++;
[self playerCurrentMusic];
}
} #pragma mark -- 滑块滑动改变播放进度(代理方法)
-(void)changValue:(UISlider *)slider {
//拖动滑块时, 停止计时器
[self.timer invalidate];
self.player.currentTime = slider.value;
//开始计时器
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(reloadAction) userInfo:nil repeats:YES];
}

想要实现后台播放(即程序进入后台,音乐继续播放)需要修改plist文件:

1.添加required background modes这个key项,并选择"App plays audio or streams audio/video using AirPlay"这个value项。
2.XCode7.1以上获取网络数据,需要修改plist文件
在Info.plist中添加App Transport Security Settings类型Dictionary。
在App Transport Security Settings下添加Allow Arbitrary Loads类型Boolean,值设为YES

需要在后台实现播放页的各种上一首,下一首...各种功能, 还需要在Appdelegate.m的background方法里:

- (void)applicationDidEnterBackground:(UIApplication *)application {

    //程序进入后台后, 为了让音乐继续播放, 在此方法里创建该代理播放页, 并指定它播放器的代理
PlayViewController *player = [PlayViewController defaultPlayVC];
player.player.delegate = player;
}

当前工程Demo地址: http://download.csdn.net/detail/margaret_mo/9412069

AVAudioPlayer播放并实现了后台播放和远程控制的更多相关文章

  1. iOS从零开始学习直播之音频2.后台播放和在线播放

    本篇主要讲音频的后台播放和在线播放. 后台播放   上一篇写的工程运行之后程序退至后台,发现运行不了,歌停止了,这显然不行,音乐后台播放是标配啊.今天就来讲一下后台播放. 1.在plist文件里,告诉 ...

  2. iOS后台播放音乐

    iOS实现在后台播放音乐 iOS4之后就支持后台播放音频了.只需下面两步就可以实现后台播放音频操作了. 1. 在Info.plist中,添加"Required background mode ...

  3. iOS开发--QQ音乐练习,后台播放和锁屏界面

    一.设置后台播放 首先允许程序后台播放 代码实现 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOpti ...

  4. iOS- 关于AVAudioSession的使用——后台播放音乐

    1.前言 •AVAudioSession是一个单例,无需实例化即可直接使用.AVAudioSession在各种音频环境中起着非常重要的作用 •针对不同的音频应用场景,需要设置不同的音频会话分类   1 ...

  5. iOS AvPlayer AvAudioPlayer音频的后台播放问题

    iOS 4开始引入的multitask,我们可以实现像ipod程序那样在后台播放音频了.如果音频操作是用苹果官方的AVFoundation.framework实现,像用AvAudioPlayer,Av ...

  6. iOS 后台播放音乐

    在info.plist文件中添加 下面是后台播放音频的完整测试代码: 引入文件<AVFoundation/AVFoundation.h> //后台播放音频设置 AVAudioSession ...

  7. IOS后台运行 之 后台播放音乐

    iOS 4开始引入的multitask,我们可以实现像ipod程序那样在后台播放音频了.如果音频操作是用苹果官方的AVFoundation.framework实现,像用AvAudioPlayer,Av ...

  8. iOS多媒体总结&进入后台播放音乐

    1. 播放mp3需要导入框架,AVFoundation支持音频文件(.caf..aif..wav..wmv和.mp3)的播放. #import <AVFoundation/AVFoundatio ...

  9. iOS后台播放

    ### 音乐后台播放 * .当程序进入后台的时候,开启后台任务 ``` - (void)applicationDidEnterBackground:(UIApplication *) { // 开启后 ...

随机推荐

  1. asp.net App_Code文件夹相关操作

    最近用到了App_Code文件夹,想要实现动态编译文件的方式,即替换文件夹中的类文件从而达到实时修改代码的效果,类似web.config,网上查到的资料基本都是把文件夹中的类文件修改属性为" ...

  2. ASP.NET MVC部分视图PartialView的使用

    在ASP.NET MVC项目中,部分视图PartialVieww使用很广.它实际就是在ASP.NET环境的用户自定义控件UserControl. 在控制器中,创建一个视图操作Action和一个部分视图 ...

  3. html5掷骰子的小demo

    代码如下: <!DOCTYPE> <html> <title>柯乐义</title> <head> <script> var l ...

  4. thinkphp端口配置

    <?php return array( //'配置项'=>'配置值' 'MODULE_ALLOW_LIST' => array('Home'), 'DEFAULT_MODULE' = ...

  5. html初始化页面和a标签无下划线

    body, div, p, h1, h2, h3, h4, h5, h6, ul, ol, li, dl, dd, dt, img, form { padding:0px; margin:0px; b ...

  6. PHPUnit单元测试中类protected/private方法测试

    这里首先有一个问题要考虑的是,这类方法是否要被测试? 理论上,这类方法都会被其它public类型的方法调用,只要对那些public的方法做充分的测试,就可以保证这些方法的可靠性,就没有必要再测了.好像 ...

  7. LGLTagsView

    做项目的时候经常会用到标签,比如说现在很多项目中搜索历史用标签展示 和 选择某个产品的不同属性用标签展示....网上的有很多封装好的标签,但是作为一个上进的程序员,都希望能有一个自己写的.其实也是一种 ...

  8. 计划任务crontab

    安装crontab服务 1, yum install -y vixie-cron 如果提示crond命令不存在,可能被误删除了,CentOS下可以通过这个命令重新安装: yum -y install ...

  9. Guava学习笔记:Guava新增集合类型-Bimap

    BiMap提供了一种新的集合类型,它提供了key和value的双向关联的数据结构. 通常情况下,我们在使用Java的Map时,往往是通过key来查找value的,但是如果出现下面一种场景的情况,我们就 ...

  10. Nginx详解-服务器集群

    Nginx是什么 代理服务器:一般是指局域网内部的机器通过代理服务器发送请求到互联网上的服务器,代理服务器一般作用在客户端.应用比如:GoAgent,FQ神器.  一个完整的代理请求过程为:客户端首先 ...