一、AVAudioPlayer简介

AVAudioPlayer在AVFoundation框架下,所以我们要导入AVFoundation.framework。

AVAudioPlayer类封装了播放单个声音的能力。播放器可以用NSURL或者NSData来初始化,要注意的是NSURL并不可以是网络url而必须是本地文件URL,

因为 AVAudioPlayer不具备播放网络音频的能力,如果要播放网络URL,需要先转化为NSData.但是此法并不可取,

因为AVAudioPlayer只能播放一个完整的文件,并不支持流式播放,所以必须是缓冲完才能播放,所以如果网络文件过大抑或是网速不够岂不是要等很久?

所以播放网络音频我们一般用音频队列。播放较大的音频或者要对音频有精确的,这种情况会选择使用AVFoundation.framework中的AVAudioPlayer来实现。

AVAudioPlayer不支持边下边播,所以只能下载到本地再播放,这是他的缺点。但是AVAudioPlayer能够精确控制播放进度、音量、播放速度等属性,这是很强大的优点。

注意:需要添加AVFoundation.framework

、AVAudioPlayer使用

1.实例化方法
    - (instancetype)initWithContentsOfURL:(NSURL *)url error:(NSError **)outError;
    
    2.预加载资源
    - (BOOL)prepareToPlay;

3.遵守协议
    AVAudioPlayerDelegate

4.播放完成之后回调以下方法
    - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag;

先搭建UI吧,直接上图:

#import "AVAudioPlayerViewController.h"
#import <AVFoundation/AVFoundation.h> @interface AVAudioPlayerViewController ()
{
//声明一个播放器
AVAudioPlayer *_musicPlay;//音乐播放器
} - (IBAction)playAction:(id)sender;//播放
- (IBAction)pauseAction:(id)sender;//暂停
- (IBAction)voiceAction:(UISlider *)sender;//音量
- (IBAction)progressAction:(UISlider *)sender;//进度 @property (weak, nonatomic) IBOutlet UISlider *progressSlider;//进度条
@property (nonatomic,strong)NSTimer *myTimer;//声明一个定时器类型的成员变量 @end @implementation AVAudioPlayerViewController - (void)viewDidLoad {
[super viewDidLoad]; //获取资源路径 需要事先导入本地音频内容
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"1" ofType:@"mp3"];
NSLog(@"%@",filePath); NSURL *URL =[NSURL fileURLWithPath:filePath];
_musicPlay = [[AVAudioPlayer alloc] initWithContentsOfURL:URL error:nil];
//实例化音乐播放器
// _musicPlay = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:filePath] error:nil]; //设置音量大小处于中等强度
_musicPlay.volume = 0.5;
//循环次数,默认是1
    _musicPlay.numberOfLoops = 1;
   //    声道数
    NSUInteger channels = _musicPlay.numberOfChannels;//只读属性 //预加载资源
if ([_musicPlay prepareToPlay]) { NSLog(@"准备完毕"); } //设置总进度大小
self.progressSlider.maximumValue = _musicPlay.duration; }
#pragma mark- 各类触发事件
-(void)change:(NSTimer *)sender{ //每一秒钟设置一下进度值 播放位置
self.progressSlider.value = _musicPlay.currentTime; } #pragma mark- AVAudioPlayer相关的方法
- (IBAction)playAction:(id)sender {
//播放
[_musicPlay play]; self.myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(change:) userInfo:nil repeats:YES];
} - (IBAction)pauseAction:(id)sender {
//暂停
[_musicPlay pause];
//停止定时器
[self.myTimer invalidate];
NSLog(@"%f",_musicPlay.currentTime);
} - (IBAction)voiceAction:(UISlider *)sender { //改变音量大小
_musicPlay.volume = sender.value; } - (IBAction)progressAction:(UISlider *)sender { //设置进度
_musicPlay.currentTime = sender.value; }

代理方法

加入播放出现异常,或者被更高级别的系统任务打断,我们的程序还没来得及收场就挂了,怎么办?不急,我们可以通过几个委托方法很好地处理所有的情形。

首先给player设置委托是必须的:

  1. player.delegate = self;
  1. - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer*)player successfully:(BOOL)flag{
  2. //播放结束时执行的动作
  3. }
  4. - (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer*)player error:(NSError *)error{
  5. //解码错误执行的动作
  6. }
  7. - (void)audioPlayerBeginInteruption:(AVAudioPlayer*)player{
  8. //处理中断的代码
  9. }
  10. - (void)audioPlayerEndInteruption:(AVAudioPlayer*)player{
  11. //处理中断结束的代码
  12. }

 三、AVAudioPlayer扩展

1) 如何做后台播放

1> 在plist文件下添加 key : Required background modes,并设置item0 = App plays audio or streams audio/video using AirPlay

2> 设置AVAudioSession的类型为AVAudioSessionCategoryPlayback并且调用setActive::方法启动会话。

AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
[audioSession setActive:YES error:nil];

正常来说,当app退到后台,程序处于悬挂状态,即暂停播放。
 在iOS中每个应用都有一个音频会话,这个会话就通过AVAudioSession来表示。
 AVAudioSession同样存在于AVFoundation框架中,它是单例模式设计,通过sharedInstance进行访问。在使用Apple设备时大家会发现有些应用只要打开其他音频播放就会终止,而有些应用却可以和其他应用同时播放,在多种音频环境中如何去控制播放的方式就是通过音频会话来完成的。

下面是音频会话的几种会话模式:

注意 : 前面的代码中也提到设置完音频会话类型之后需要调用setActive::方法将会话激活才能起作用。

(2) 如何做输出改变监听(拔出耳机音乐暂停播放)

ios6.0后还可以监听输出改变通知。通俗来说,就是拔出耳机,音乐播放暂停。
代码如下:

//添加观察者
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(routeChange:) name:AVAudioSessionRouteChangeNotification object:nil];

// 通知方法
- (void)routeChange:(NSNotification*)notification
{

NSDictionary *dic = notification.userInfo;

int changeReason = [dic[AVAudioSessionRouteChangeReasonKey] intValue];

//等于AVAudioSessionRouteChangeReasonOldDeviceUnavailable表示旧输出不可用
    if (changeReason == AVAudioSessionRouteChangeReasonOldDeviceUnavailable)
    {
        AVAudioSessionRouteDescription *routeDescription=dic[AVAudioSessionRouteChangePreviousRouteKey];
        AVAudioSessionPortDescription *portDescription= [routeDescription.outputs firstObject];
        //原设备为耳机则暂停
        if ([portDescription.portType isEqualToString:@"Headphones"])
        {
            //这边必须回调到主线程
            dispatch_async(dispatch_get_main_queue(), ^{

self.playOrPause.selected = NO;

});

[self pauseMusic];
        }
    }

}//输出改变通知

(3) 歌词轮播实现思路

歌词应该是 时间 和 对应歌词 的字典类型数据结构。用UITableView实现。获取播放器当前播放时间,查找字典找到对应的key,进而找到对应的NSIndexPath,滚动到当前cell在屏幕中央即可。

(4) 关于定时器的小细节

关于NSLoopMode的问题
由于+ (NSTimer *)scheduledTimerWithTimeInterval:..; 此时的timer会被加入到当前线程的runloop中,默认为NSDefaultRunLoopMode。如果当前线程是主线程,某些事件,如UIScrollView的拖动时,会将runloop切换到NSEventTrackingRunLoopMode模式,在拖动的过程中,默认的NSDefaultRunLoopMode模式中注册的事件是不会被执行的。从而此时的timer也就不会触发。

解决方案:把创建好的timer手动添加到指定模式中,此处为NSRunLoopCommonModes,这个模式其实就是NSDefaultRunLoopMode与NSEventTrackingRunLoopMode的结合。

[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];

AVAudioPlayer的更多相关文章

  1. iOS播放器 - AVAudioPlayer

    今天记录一下AVAudioPlayer,这个播放器类苹果提供了一些代理方法,主要用来播放本地音频. 其实也可以用来播放网络音频,只不过是将整个网络文件下载下来而已,在实际开发中会比较耗费流量不做推荐. ...

  2. AVAudioPlayer播放本地音频

    AVAudioPlayer苹果官方上说一般用于播放本地音频,不能用于播放网络上的音频. 具体的代码:先导入 #import <AVFoundation/AVFoundation.h> // ...

  3. AVAudioPlayer播放并实现了后台播放和远程控制

    // ViewController.h #import <UIKit/UIKit.h> #import <AVFoundation/AVFoundation.h> @class ...

  4. iOS -- AVAudioPlayer播放音乐

    一. AVAudioPlayer:                          声明音乐控件AVAudioPlayer,必须声明为全局属性变量,否则可能不会播放,AVAudioPlayer只能播 ...

  5. initializer for conditional binding must have optional type not AVAudioPlayer

    if let buttonBeep = self.setupAudioPlayerWithFile("ButtonTap", type: "wav") {    ...

  6. iOS - AVAudioPlayer 音频播放

    前言 NS_CLASS_AVAILABLE(10_7, 2_2) @interface AVAudioPlayer : NSObject @available(iOS 2.2, *) public c ...

  7. 音乐播放器 AVAudioPlayer、定时器、UISlider

    #import <UIKit/UIKit.h> #import <AVFoundation/AVFoundation.h> @interface ViewController ...

  8. AVAudioplayer时error解决 创建失败 ERror creating player: Error Domain=NSOSStatusErrorDomain Code=2003334207 "(null)"

    AVAudioplayer 有两个初始化方法: 1.[[AVAudioPlayer alloc] initWithData:musicData error&e]; 2.[[AVAudioPla ...

  9. IOS AVAUDIOPLAYER 播放器使用

    1. 导入 AVFoundation.framework 2.导入头文件  #import <AVFoundation/AVFoundation.h> 3. player = [[AVAu ...

随机推荐

  1. Introducing Holographic Emulation

    Holographic Emulation is a new feature that vastly reduces iteration time when developing holographi ...

  2. mininet中iperf sever自动退出

    使用iperf 在mininet进行吞吐量测试是常用的方法,之前结束iperf server的方法是运行os.system('pkill iperf')命令. 但是这种方式iperf server有可 ...

  3. 连接有密码的mongodb

    mongoose: db.openSet("mongodb://admin:pass@192.168.1.100:27017/mydb");

  4. 解读ASP.NET 5 & MVC6系列(10):Controller与Action

    我们知道在MVC5和之前的版本,两个框架的生命周期是不一样的,在新版MVC6中,MVC Controller/Web API Controller已经合二为一了,本章我们主要讲解Controller和 ...

  5. 使用markdown

    一.在windows下使用markdown MarkdownPad:MarkdownPad is a full-featured markdown editor for windows. Awsomi ...

  6. 如何解决ajax重复提交的问题

    如下一段代码: 先忽略我没引jquery.js的问题,这是一个案例. 当我们点击提交时,控制台输出两次e,在network里查看,可以看到我们的ajax传输了两次,造成了数据重复提交. 一种解释为bu ...

  7. SQL基础语法(五)

    SQL INSERT INTO 语句INSERT INTO 语句 INSERT INTO 语句用于向表格中插入新的行. 语法:INSERT INTO 表名称 VALUES (值1, 值2,....) ...

  8. js中的原型prototype

    var arr1 = new Array(12,34,98,43,38,79,56,1); arr1.sum=function (){ var result = 0; for(var i=0; i&l ...

  9. 关于mirai病毒的一些研究

    首页好像只能显示随笔,之前发在文章里面的,见文章http://www.cnblogs.com/mrchang/articles/6210681.html

  10. UVA725

    虽然是暴力求解,但是也要观察条件,尽量提高效率.如本题,原本要枚举10个数,但是分析可知通过枚举fghij就可以了. #include<stdio.h> #include<strin ...