iOS AVAudioPlayer(音訊播放)

joker_king發表於2018-12-19

AVAudioPlayer

在iOS程式中,音訊播放隨處可見,有的聲音只有1秒,有的聲音好幾分鐘 。iOS支援的音訊格式AAC、ALAC、IMA4、linear、MP3。 AVAudioPlayer類用於回放音訊資料。是一個易於使用的類,它提供了大量的功能。使用該類可以實現音訊的載入,播放,暫停,停止。需要加入AVFoundation.framework框架,在使用的類中引入<AVFoundation/AVFoundation.h>。

播放系統音(system sound service)

使用AudioToolbox framework。這個框架可以將比較短的聲音註冊到 system sound服務上。被註冊到system sound服務上的聲音稱之為 system sounds。它必須滿足下面幾個條件。

  • 播放的時間不能超過30秒
  • 資料必須是 PCM或者IMA4流格式
  • 必須被打包成下面三個格式之一:Core Audio Format (.caf), Waveform audio (.wav), 或者 Audio Interchange File (.aiff)

示例程式碼

    //得到音訊資源的路徑
    NSString *newPath = [[NSBundle mainBundle]pathForResource:@"6365" ofType:@"wav"];
    //由於使用音訊路徑的時候為NSURL型別,所以我們需要將檔案路徑轉換為NSURL型別
    NSURL *newurl = [NSURL fileURLWithPath:newPath];
    //需要建立一個soundID,因為播放系統聲音的時候,系統找尋的是soundID,soundID的範圍為1000-2000之間。
    SystemSoundID soundID;
    /*根據聲音的路徑建立ID    (__bridge在兩個框架之間強制轉換型別,值轉換記憶體,不修改記憶體管理的
     許可權)在轉換資料型別的時候,不希望該物件的記憶體管理許可權發生改變,原來是MRC型別,轉換了還是 MRC。*/
    AudioServicesCreateSystemSoundID((__bridge CFURLRef _Nonnull)(newurl), &soundID);
    //播放音訊
    AudioServicesPlayAlertSound(soundID);
    //新增震動,只有在iphone上才可以,模擬器沒有效果。
    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
複製程式碼

播放自定義的音訊

    NSString *soundPath = [[NSBundle mainBundle]pathForResource:@"1111" ofType:@"mp3"];
    NSURL *soundUrl = [NSURL fileURLWithPath:soundPath];
    //初始化播放器物件
    self.audioPlay = [[AVAudioPlayer alloc]initWithContentsOfURL:soundUrl error:nil];
    //設定聲音的大小
    self.audioPlay.volume = 0.5;//範圍為(0到1);
    //設定迴圈次數,如果為負數,就是無限迴圈
    self.audioPlay.numberOfLoops =-1;
    //設定播放進度
    self.audioPlay.currentTime = 0;
    //準備播放
    [self.audioPlay prepareToPlay];
    [self.audioPlay play];
複製程式碼

為音訊新增播放暫停和停止按鈕

首先我們需要一個計時器,來計算當前歌曲的進度,在這裡我們把進度條的最大值設定為歌曲的總時長,這樣在播放音樂的時候,我們把進度條的value值設定為當前歌曲播放的時間,這樣進度條就會跟隨著歌曲的播放而前進。 示例程式碼:一個計時器的懶載入方法,用這個方法建立一個計時器是最簡單的,它不需要我們手動把它新增到迴圈池中,只需要把repeats的值設定為YES它就會自動迴圈。

- (NSTimer *)timer{
    if (!_timer) {
        _timer = [NSTimer scheduledTimerWithTimeInterval:0 target:self 
selector:@selector(timerAction) userInfo:nil repeats:YES];
        [_timer setFireDate:[NSDate distantFuture]];//在建立計時器的時候把計時器先暫停。
    }return _timer;
}
複製程式碼

下面我們需要在計時器的回撥方法中讓進度條跟隨著歌曲前進。通過把value值設定為當前的時間,來實現我們的目的。

- (void)timerAction{
    self.slider.maximumValue = self.audioPlay.duration;
    self.slider.minimumValue = 0;
    self.slider.value = self.audioPlay.currentTime;
    NSLog(@"%.2f",self.audioPlay.currentTime);//在這裡列印了一下歌曲當前的時間
}
複製程式碼

歌曲的播放方法

- (IBAction)musicPlay:(id)sender {
    BOOL isPlay = [self.audioPlay play];
    if (isPlay) {//在這裡判斷歌曲是否播放,如果播放了,就立刻馬上啟動計時器。
        [self.timer setFireDate:[NSDate distantPast]];
    }else{
        NSLog(@"音訊錯誤");
    }
}
複製程式碼

暫停方法

- (IBAction)musicSuspended:(id)sender {
    [self.audioPlay pause];//音訊暫停
    [self.timer setFireDate:[NSDate distantFuture]];//暫停計時器
}
複製程式碼

停止方法

- (IBAction)musicStop:(id)sender {
    [self.audioPlay stop];
    self.audioPlay.currentTime = 0;//將播放的進度設定為初始狀態
    [self.timer invalidate];//銷燬計時器
    self.timer = nil;
}
複製程式碼

這樣我們就能簡單的實現讓進度條跟隨歌曲移動的需求了 。 ##實現讓歌曲的快退快進 首先我們需要給滑塊新增兩個監測滑塊值改變的回撥方法

[self.slider addTarget:self action:@selector(touchUp) 
forControlEvents:UIControlEventValueChanged|UIControlEventTouchUpInside];//當滑塊上的按鈕的
位置發生改變,或者被按下時,我們需要讓歌曲先暫停。
    [self.slider addTarget:self action:@selector(touchDown) 
forControlEvents:UIControlEventTouchUpInside|UIControlEventTouchUpOutside|UIControlEventTouchCancel];//當滑塊被鬆開,
按到外面了,或者取消時,我們需要讓歌曲的播放從當前的時間開始播放。
複製程式碼

下面我們來看看這兩個方法的回撥方法 首先來看第一個

-(void)touchUp{
    if ([self.audioPlay isPlaying]){//判斷歌曲是否正在播放,如果正在播放就讓歌曲暫停,否則什麼也不做。
        [self musicSuspended:nil];//在這裡我們需要呼叫歌曲的暫停方法,實現歌曲的暫停。
    }
}
複製程式碼

第二個

-(void)touchDown{
    self.audioPlay.currentTime = self.slider.value;//把歌曲當前播放的時間設定為進度條的值
    [self musicPlay:nil];//呼叫歌曲的播放方法。
}
複製程式碼

以上就是實現歌曲的播放、暫停、停止,和它快退快進的方法了。其他的現實,以後再進行添補。

相關文章