天天看點

AVAudioPlayer音頻播放

簡述

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 初始化

  1. initWithContentsOfURL: error:

    從URL加載音頻,傳回 AVAudioPlayer 對象
  2. initWithData: error:

    加載NSdata對象的音頻檔案,傳回 AVAudioPlayer 對象

AVAudioPlayer方法調用

  1. - (BOOL)play

    開始或恢複播放,調用該方法時,如果該音頻還沒有準備好,程式會隐士執行

    - (BOOL)prepareToPlay

    方法
  2. - (void)pause

    暫停
  3. - (void)stop

    停止
  4. - (BOOL)playAtTime:(NSTimeInterval)time NS_AVAILABLE(10_7, 4_0)

    在某個時間點播放
  5. - (BOOL)prepareToPlay

    準備開始播放
  6. - (void)updateMeters

    更新音頻測量值,注意如果要更新音頻測量值必須設定meteringEnabled為YES,通過音頻測量值可以即時獲得音頻分貝等資訊
  7. - (float)averagePowerForChannel:(NSUInteger)channelNumber

    獲得指定聲道的分貝峰值,注意如果要獲得分貝峰值必須在此之前調用updateMeters方法

使用 AVAudioPlayer 讀取音頻資訊

  1. volume

    播放器的音頻增益,值:0.0~1.0
  2. pan NS_AVAILABLE(10_7, 4_0)

    立體聲設定 設為

    -1.0

    則左邊播放 設為

    0.0

    則中央播放 設為

    1.0

    則右邊播放
  3. enableRate

    是否允許改變播放速率
  4. rate NS_AVAILABLE(10_8, 5_0)

    播放速率

    0.5

    (半速播放) ~

    2.0

    (倍速播放) 注

    1.0

    是正常速度
  5. playing

    是否正在播放音頻
  6. numberOfLoops

    循環次數,如果要單曲循環,設定為負數
  7. numberOfChannels

    該音頻的聲道次數 (隻讀)
  8. duration

    該音頻時長
  9. currentTime

    該音頻的播放點
  10. deviceCurrentTime

    輸出裝置播放音頻的時間,注意如果播放中被暫停此時間也會繼續累加
  11. url

    音頻檔案路徑,隻讀
  12. data

    音頻資料,隻讀
  13. channelAssignments

    獲得或設定播放聲道

代理方法

  1. - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag;

    音頻播放完成
  2. - (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError * __nullable)error

    音頻解碼發生錯誤
  3. - (void)audioPlayerBeginInterruption:(AVAudioPlayer *)player

    如果音頻被中斷,比如有電話呼入,該方法就會被回調,該方法可以儲存目前播放資訊,以便恢複繼續播放的進度

代碼

AVAudioPlayer 初始化

首先導入兩首格式為 mp3 的歌曲,再導入歌手圖檔

在 ViewController.h 導入

#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/MediaPlayer.h>                

然後必須持有一個 AVAudioPlayer 對象,若此對象不是屬性,則無法播放

@property (nonatomic , strong) AVAudioPlayer *player;
           

添加控件如圖所示,給控件命名

AVAudioPlayer音頻播放

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;
        }
    }
}
           

效果圖:

AVAudioPlayer音頻播放

播放頁面

AVAudioPlayer音頻播放

鎖屏頁面

這樣,播放器的基本功能就已經完成 !! 代碼多有不祥之處,時間匆忙,敬請諒解,不實之處,請多包涵!!

Demo位址:

點此下載下傳

作者:TianBai

連結:http://www.jianshu.com/p/589999e53461

來源:簡書