AVAudioPlayer播放并实现了后台播放和远程控制
// 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项。
需要在后台实现播放页的各种上一首,下一首...各种功能, 还需要在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播放并实现了后台播放和远程控制的更多相关文章
- iOS从零开始学习直播之音频2.后台播放和在线播放
本篇主要讲音频的后台播放和在线播放. 后台播放 上一篇写的工程运行之后程序退至后台,发现运行不了,歌停止了,这显然不行,音乐后台播放是标配啊.今天就来讲一下后台播放. 1.在plist文件里,告诉 ...
- iOS后台播放音乐
iOS实现在后台播放音乐 iOS4之后就支持后台播放音频了.只需下面两步就可以实现后台播放音频操作了. 1. 在Info.plist中,添加"Required background mode ...
- iOS开发--QQ音乐练习,后台播放和锁屏界面
一.设置后台播放 首先允许程序后台播放 代码实现 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOpti ...
- iOS- 关于AVAudioSession的使用——后台播放音乐
1.前言 •AVAudioSession是一个单例,无需实例化即可直接使用.AVAudioSession在各种音频环境中起着非常重要的作用 •针对不同的音频应用场景,需要设置不同的音频会话分类 1 ...
- iOS AvPlayer AvAudioPlayer音频的后台播放问题
iOS 4开始引入的multitask,我们可以实现像ipod程序那样在后台播放音频了.如果音频操作是用苹果官方的AVFoundation.framework实现,像用AvAudioPlayer,Av ...
- iOS 后台播放音乐
在info.plist文件中添加 下面是后台播放音频的完整测试代码: 引入文件<AVFoundation/AVFoundation.h> //后台播放音频设置 AVAudioSession ...
- IOS后台运行 之 后台播放音乐
iOS 4开始引入的multitask,我们可以实现像ipod程序那样在后台播放音频了.如果音频操作是用苹果官方的AVFoundation.framework实现,像用AvAudioPlayer,Av ...
- iOS多媒体总结&进入后台播放音乐
1. 播放mp3需要导入框架,AVFoundation支持音频文件(.caf..aif..wav..wmv和.mp3)的播放. #import <AVFoundation/AVFoundatio ...
- iOS后台播放
### 音乐后台播放 * .当程序进入后台的时候,开启后台任务 ``` - (void)applicationDidEnterBackground:(UIApplication *) { // 开启后 ...
随机推荐
- Android之Notification介绍
Notification就是在桌面的状态通知栏.这主要涉及三个主要类: Notification:设置通知的各个属性. NotificationManager:负责发送通知和取消通知 Notifica ...
- js基础篇——call/apply、arguments、undefined/null
a.call和apply方法详解 call方法: 语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]]) 定义:调用一个对象的一个方法,以另一个对象替换当前对象 ...
- CompressHelper
public static string CompressString(string unCompressedString) { byte[] bytData = System.Text.Encodi ...
- SQL Server时间粒度系列----第6节基于当前日的小时数和分钟数与mysql unix_timestamp和from_unixtime的mssql实现
本文目录列表: 1.基于当前日的小时数和分钟数2.mysql unix_timestamp和from_unixtime的mssql实现 3.总结语 4.参考清单列表 基于当前日的小时数和分钟数 ...
- Linux 小工具学习之(1)——Wget十例[翻译]
在本博文中我们将学习一下wget这个工具.wget可以使用HTTP.HTTPS.和FTP等常见网络协议来从万维网(WWW)获取文件(从它的名字来源也可以看出 World Wide Web Get -& ...
- WCF项目中出现常见错误的解决方法:基础连接已经关闭: 连接被意外关闭
在我们开发WCF项目的时候,常常会碰到一些莫名其妙的错误,有时候如果根据它的错误提示信息,一般很难定位到具体的问题所在,而由于WCF服务的特殊性,调试起来也不是那么方便,因此往往会花费不少时间来进行跟 ...
- QQ--模拟登录
QQ--模拟登录 使用PC端模拟登录,主要使用的QQ空间登录地址测试. 首先,QQHelper的创建. #region Helper /// <summary> /// Helper // ...
- hibernate 注释说明
* @Entity -- 将一个类声明为一个实体 bean(即一个持久化 POJO 类) * @Id -- 注解声明了该实体 bean 的标识属性(对应表中的主 键). * @Table -- 注解声 ...
- Scalaz(28)- ST Monad :FP方式适用变量
函数式编程模式强调纯代码(pure code),主要实现方式是使用不可变数据结构,目的是函数组合(composability)最终实现函数组件的重复使用.但是,如果我们在一个函数p内部使用了可变量(m ...
- 关于线上的bug什么时候修复的思考
这里系统专门指的是那种用户量大的系统,比如有几百万或者上千万的注册会员.因为小系统因为用户量少,不存在这种思考,考虑有时候是多余的.另外还有内部系统,给自己公司内部人员使用的,即便是出现了问题,也不会 ...