簡述
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 初始化
-
從URL加載音頻,傳回 AVAudioPlayer 對象initWithContentsOfURL: error:
-
加載NSdata對象的音頻檔案,傳回 AVAudioPlayer 對象initWithData: error:
AVAudioPlayer方法調用
-
開始或恢複播放,調用該方法時,如果該音頻還沒有準備好,程式會隐士執行- (BOOL)play
方法- (BOOL)prepareToPlay
-
暫停- (void)pause
-
停止- (void)stop
-
在某個時間點播放- (BOOL)playAtTime:(NSTimeInterval)time NS_AVAILABLE(10_7, 4_0)
-
準備開始播放- (BOOL)prepareToPlay
-
更新音頻測量值,注意如果要更新音頻測量值必須設定meteringEnabled為YES,通過音頻測量值可以即時獲得音頻分貝等資訊- (void)updateMeters
-
獲得指定聲道的分貝峰值,注意如果要獲得分貝峰值必須在此之前調用updateMeters方法- (float)averagePowerForChannel:(NSUInteger)channelNumber
使用 AVAudioPlayer 讀取音頻資訊
-
播放器的音頻增益,值:0.0~1.0volume
-
立體聲設定 設為pan NS_AVAILABLE(10_7, 4_0)
則左邊播放 設為-1.0
則中央播放 設為0.0
則右邊播放1.0
-
是否允許改變播放速率enableRate
-
播放速率rate NS_AVAILABLE(10_8, 5_0)
(半速播放) ~0.5
(倍速播放) 注2.0
是正常速度1.0
-
是否正在播放音頻playing
-
循環次數,如果要單曲循環,設定為負數numberOfLoops
-
該音頻的聲道次數 (隻讀)numberOfChannels
-
該音頻時長duration
-
該音頻的播放點currentTime
-
輸出裝置播放音頻的時間,注意如果播放中被暫停此時間也會繼續累加deviceCurrentTime
-
音頻檔案路徑,隻讀url
-
音頻資料,隻讀data
-
獲得或設定播放聲道channelAssignments
代理方法
-
音頻播放完成- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag;
-
音頻解碼發生錯誤- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError * __nullable)error
-
如果音頻被中斷,比如有電話呼入,該方法就會被回調,該方法可以儲存目前播放資訊,以便恢複繼續播放的進度- (void)audioPlayerBeginInterruption:(AVAudioPlayer *)player
代碼
AVAudioPlayer 初始化
首先導入兩首格式為 mp3 的歌曲,再導入歌手圖檔
在 ViewController.h 導入
#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/MediaPlayer.h>
然後必須持有一個 AVAudioPlayer 對象,若此對象不是屬性,則無法播放
@property (nonatomic , strong) AVAudioPlayer *player;
添加控件如圖所示,給控件命名
storyboard
擷取制定 url 對象
NSURL *url = [[NSBundle mainBundle] URLForResource:@"吳亦凡-時間煮雨" withExtension:@"mp3"];
初始化 AVAudioPlayer 對象
self.player = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:nil];
設定代理
self.player.delegate = self;
這樣就播放器就初始化完成了
将storyboard裡面
開始
按鈕綁定
- (IBAction)start:(id)sender
方法
- (IBAction)start:(id)sender {
if ([self.player isPlaying]) {
[self.startBtn setBackgroundImage:[UIImage imageNamed:@"播放"] forState:];
[self.player pause];
}
else
{
[self.startBtn setBackgroundImage:[UIImage imageNamed:@"暫停"] forState:];
[self.player play];
}
if (_timer == nil) {
_timer = [NSTimer scheduledTimerWithTimeInterval: target:self selector:@selector(updateProgress) userInfo:nil repeats:YES];
}
}
注: 上訴代碼中定義了一個
NSTimer
變量,因為播放器沒有播放程序的委托,是以隻能自定義NSTimer變量對播放器進行監控
@property (strong, nonatomic) NSTimer *timer;
将storyboard裡面
停止
按鈕綁定
- (IBAction)stop:(id)sender
方法
- (IBAction)stop:(id)sender {
[self.player stop];
//計時器停止
[_timer invalidate];
//釋放定時器
_timer = nil;
}
設定剛才綁定的定時器調用方法
updateProgress
-(void)updateProgress{
//進度條顯示播放進度
self.progress.progress = self.player.currentTime/self.player.duration;
self.info1.text = [NSString stringWithFormat:@"目前播放時間%f",self.player.currentTime];
}
實作
AVAudioPlayer
的委托方法
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
if (player == _player && flag) {
[self.startBtn setBackgroundImage:[UIImage imageNamed:@"播放"] forState:];
}
}
-(void)audioPlayerBeginInterruption:(AVAudioPlayer *)player{
if (player == _player){
NSLog(@"播放被中斷");
}
}
此時,音樂就可以播放了!!!
但是,人們使用音樂大都是背景播放,那麼如何添加背景播放支援呢?
背景播放
在項目裡
info.plist
右鍵
open As
--
source code
添加代碼:
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
</array>
同樣,代碼裡面也要添加背景播放支援
//設定鎖屏仍能繼續播放
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
這樣 音樂在背景就可以播放了!!
那麼很多點傳播放器都有一個功能,那就是在使用者拔掉耳機的時候,暫停播放
監聽播放裝置
//添加通知,拔出耳機後暫停播放
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(routeChange:) name:AVAudioSessionRouteChangeNotification object:nil];
/**
* 一旦輸出改變則執行此方法
*
* @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];
//原裝置為耳機則暫停
if ([portDescription.portType isEqualToString:@"Headphones"]) {
[self.player pause];
}
}
}
這樣就能在拔掉耳機的時候,暫停播放了!!!
但是似乎還是差了一些什麼,好像鎖屏界面空空如也啊!!!
定制鎖屏界面
設定背景播放時顯示的東西,例如歌曲名字,圖檔等
要用到
<MediaPlayer/MediaPlayer.h>
這個庫,剛才已經導入過
- (void)setPlayingInfo {
// 設定背景播放時顯示的東西,例如歌曲名字,圖檔等
MPMediaItemArtwork *artWork = [[MPMediaItemArtwork alloc] initWithImage:[UIImage imageNamed:@"吳亦凡.jpg"]];
NSDictionary *dic = @{MPMediaItemPropertyTitle:@"時間煮雨",
MPMediaItemPropertyArtist:@"吳亦凡",
MPMediaItemPropertyArtwork:artWork
};
[[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:dic];
}
這樣,圖檔就在鎖屏界面顯示了,不過,鎖屏界面上面的三個按鈕,怎麼控制播放呢!!
接收鎖屏歌曲按鈕控制 (上一首,播放,下一首)
首先,你要在一個繼承
UIResponder
類裡面接收遠端控制,本文以 ViewController 為例
添加如下代碼,接受遠端控制和取消遠端控制。
- (void)viewDidAppear:(BOOL)animated {
// 接受遠端控制
[self becomeFirstResponder];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
}
- (void)viewDidDisappear:(BOOL)animated {
// 取消遠端控制
[self resignFirstResponder];
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
}
接收方法設定
- (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;
}
}
}
效果圖:
播放頁面
鎖屏頁面
這樣,播放器的基本功能就已經完成 !! 代碼多有不祥之處,時間匆忙,敬請諒解,不實之處,請多包涵!!
Demo位址:
點此下載下傳
作者:TianBai
連結:http://www.jianshu.com/p/589999e53461
來源:簡書