簡述
AVAudioPlayer 是一個屬于 AVFoundation.framework 的一個類,它的功能類似于一個功能強大的播放器,AVAudioPlayer 支持廣泛的音頻格式,主要是以下這些格式。
- AAC
- AMR (Adaptive multi-Rate,一種語音格式)
- ALAC (Apple lossless Audio Codec)
- iLBC (internet Low Bitrate Codec,另一種語音格式)
- IMA4 (IMA/ADPCM)
- linearPCM (uncompressed)
- u-law 和 a-law
- MP3 (MPEG-Laudio Layer 3)
AVAudioPlayer 的使用
AVAudioPlayer 初始化
-
initWithContentsOfURL: error:從URL加載音頻,返回 AVAudioPlayer 對象 -
initWithData: error:加載NSdata對象的音頻文件,返回 AVAudioPlayer 對象
AVAudioPlayer方法調(diào)用
-
- (BOOL)play開始或恢復(fù)播放,調(diào)用該方法時,如果該音頻還沒有準備好,程序會隱士執(zhí)行- (BOOL)prepareToPlay方法 -
- (void)pause暫停 -
- (void)stop停止 -
- (BOOL)playAtTime:(NSTimeInterval)time NS_AVAILABLE(10_7, 4_0)在某個時間點播放 -
- (BOOL)prepareToPlay準備開始播放 -
- (void)updateMeters更新音頻測量值,注意如果要更新音頻測量值必須設(shè)置meteringEnabled為YES,通過音頻測量值可以即時獲得音頻分貝等信息 -
- (float)averagePowerForChannel:(NSUInteger)channelNumber獲得指定聲道的分貝峰值,注意如果要獲得分貝峰值必須在此之前調(diào)用updateMeters方法
使用 AVAudioPlayer 讀取音頻信息
-
volume播放器的音頻增益,值:0.0~1.0 -
pan NS_AVAILABLE(10_7, 4_0)立體聲設(shè)置 設(shè)為-1.0則左邊播放 設(shè)為0.0則中央播放 設(shè)為1.0則右邊播放 -
enableRate是否允許改變播放速率 -
rate NS_AVAILABLE(10_8, 5_0)播放速率0.5(半速播放) ~2.0(倍速播放) 注1.0是正常速度 -
playing是否正在播放音頻 -
numberOfLoops循環(huán)次數(shù),如果要單曲循環(huán),設(shè)置為負數(shù) -
numberOfChannels該音頻的聲道次數(shù) (只讀) -
duration該音頻時長 -
currentTime該音頻的播放點 -
deviceCurrentTime輸出設(shè)備播放音頻的時間,注意如果播放中被暫停此時間也會繼續(xù)累加 -
url音頻文件路徑,只讀 -
data音頻數(shù)據(jù),只讀 -
channelAssignments獲得或設(shè)置播放聲道
代理方法
-
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag;音頻播放完成 -
- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError * __nullable)error音頻解碼發(fā)生錯誤 -
- (void)audioPlayerBeginInterruption:(AVAudioPlayer *)player如果音頻被中斷,比如有電話呼入,該方法就會被回調(diào),該方法可以保存當前播放信息,以便恢復(fù)繼續(xù)播放的進度
代碼
AVAudioPlayer 初始化
首先導(dǎo)入兩首格式為 mp3 的歌曲,再導(dǎo)入歌手圖片
在 ViewController.h 導(dǎo)入
#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/MediaPlayer.h>
然后必須持有一個 AVAudioPlayer 對象,若此對象不是屬性,則無法播放
@property (nonatomic , strong) AVAudioPlayer *player;
添加控件如圖所示,給控件命名

獲取制定 url 對象
NSURL *url = [[NSBundle mainBundle] URLForResource:@"吳亦凡-時間煮雨" withExtension:@"mp3"];
初始化 AVAudioPlayer 對象
self.player = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:nil];
設(shè)置代理
self.player.delegate = self;
這樣就播放器就初始化完成了
將storyboard里面 開始 按鈕綁定 - (IBAction)start:(id)sender 方法
- (IBAction)start:(id)sender {
if ([self.player isPlaying]) {
[self.startBtn setBackgroundImage:[UIImage imageNamed:@"播放"] forState:0];
[self.player pause];
}
else
{
[self.startBtn setBackgroundImage:[UIImage imageNamed:@"暫停"] forState:0];
[self.player play];
}
if (_timer == nil) {
_timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(updateProgress) userInfo:nil repeats:YES];
}
}
注: 上訴代碼中定義了一個 NSTimer 變量,因為播放器沒有播放進程的委托,所以只能自定義NSTimer變量對播放器進行監(jiān)控
@property (strong, nonatomic) NSTimer *timer;
將storyboard里面 停止 按鈕綁定 - (IBAction)stop:(id)sender 方法
- (IBAction)stop:(id)sender {
[self.player stop];
//計時器停止
[_timer invalidate];
//釋放定時器
_timer = nil;
}
設(shè)置剛才綁定的定時器調(diào)用方法updateProgress
-(void)updateProgress{
//進度條顯示播放進度
self.progress.progress = self.player.currentTime/self.player.duration;
self.info1.text = [NSString stringWithFormat:@"當前播放時間%f",self.player.currentTime];
}
實現(xiàn) AVAudioPlayer 的委托方法
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
if (player == _player && flag) {
[self.startBtn setBackgroundImage:[UIImage imageNamed:@"播放"] forState:0];
}
}
-(void)audioPlayerBeginInterruption:(AVAudioPlayer *)player{
if (player == _player){
NSLog(@"播放被中斷");
}
}
此時,音樂就可以播放了!??!
但是,人們使用音樂大都是后臺播放,那么如何添加后臺播放支持呢?
后臺播放
在項目里 info.plist 右鍵 open As -- source code 添加代碼:
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
</array>
同樣,代碼里面也要添加后臺播放支持
//設(shè)置鎖屏仍能繼續(xù)播放
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
這樣 音樂在后臺就可以播放了!!
那么很多播放器都有一個功能,那就是在用戶拔掉耳機的時候,暫停播放
監(jiān)聽播放設(shè)備
//添加通知,拔出耳機后暫停播放
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(routeChange:) name:AVAudioSessionRouteChangeNotification object:nil];
/**
* 一旦輸出改變則執(zhí)行此方法
*
* @param notification 輸出改變通知對象
*/
-(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];
//原設(shè)備為耳機則暫停
if ([portDescription.portType isEqualToString:@"Headphones"]) {
[self.player pause];
}
}
}
這樣就能在拔掉耳機的時候,暫停播放了?。。?/p>
但是似乎還是差了一些什么,好像鎖屏界面空空如也?。。?!
定制鎖屏界面
設(shè)置后臺播放時顯示的東西,例如歌曲名字,圖片等
要用到 <MediaPlayer/MediaPlayer.h> 這個庫,剛才已經(jīng)導(dǎo)入過
- (void)setPlayingInfo {
// 設(shè)置后臺播放時顯示的東西,例如歌曲名字,圖片等
MPMediaItemArtwork *artWork = [[MPMediaItemArtwork alloc] initWithImage:[UIImage imageNamed:@"吳亦凡.jpg"]];
NSDictionary *dic = @{MPMediaItemPropertyTitle:@"時間煮雨",
MPMediaItemPropertyArtist:@"吳亦凡",
MPMediaItemPropertyArtwork:artWork
};
[[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:dic];
}
這樣,圖片就在鎖屏界面顯示了,不過,鎖屏界面上面的三個按鈕,怎么控制播放呢?。?/p>
接收鎖屏歌曲按鈕控制 (上一首,播放,下一首)
首先,你要在一個繼承 UIResponder 類里面接收遠程控制,本文以 ViewController 為例
添加如下代碼,接受遠程控制和取消遠程控制。
- (void)viewDidAppear:(BOOL)animated {
// 接受遠程控制
[self becomeFirstResponder];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
}
- (void)viewDidDisappear:(BOOL)animated {
// 取消遠程控制
[self resignFirstResponder];
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
}
接收方法設(shè)置
- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
if (event.type == UIEventTypeRemoteControl) { //判斷是否為遠程控制
switch (event.subtype) {
case UIEventSubtypeRemoteControlPlay:
if (![_player isPlaying]) {
[_player play];
}
break;
case UIEventSubtypeRemoteControlPause:
if ([_player isPlaying]) {
[_player pause];
}
break;
case UIEventSubtypeRemoteControlNextTrack:
NSLog(@"下一首");
break;
case UIEventSubtypeRemoteControlPreviousTrack:
NSLog(@"上一首 ");
break;
default:
break;
}
}
}
效果圖:


這樣,播放器的基本功能就已經(jīng)完成 ?。? 代碼多有不祥之處,時間匆忙,敬請諒解,不實之處,請多包涵!!
Demo地址:
點此下載