iOS 開發 中級:Audio之利用AVAudioPlayer實現SystemSoundService的功能

來源:互聯網
上載者:User

在以前的博文中,我們已經講解了AVAudioPlayer和SystemSoundService的用法。這兩種功能在一定程度上都適合作為遊戲音效的播放方式。而兩者也各有其優缺點。下面我們來總結一下有哪些:

1)AVAudioPlayer的優點

(1)可以播放任意長度音樂;

(2)可以迴圈播放;

(3)可以控制播放的時間;

(4)可以控制聲道的音量實現立體聲效果;

(5)可以調整音量。

2)AVAudioPlayer的缺點

(1)播放之前必須先載入,不能立即播放;

(2)一次一個AudioPlayer只能播放所載入的音樂,不能同時播放好幾次同樣的音樂。

(3)沒有震動效果

3)SystemSoundService的優點:

(1)能夠立即播放

(2)能夠在同一時間播放多次音樂

(3)可以加上震動效果

4)SystemSoundService的缺點:

(1)不能迴圈播放

(2)不能控制播放時間

(3)不能控制聲道

(4)不能控制音量

(5)不能暫停音樂


我們發現,這兩種音樂播放方式的優缺點幾乎是完全互補的。那麼,有什麼用呢?

關鍵:我們這裡考慮的是遊戲音效的播放!都是短時間的音頻播放!

想象一下遊戲,有時候我們要重複的播放一個音效,有時候我們想來一個震動,有時候我們需要在短時間內播放同一個音頻多次!

因此,我們可以考慮綜合兩者的功能!

辦法:

          利用AVAudioPlayer來實現SystemSoundService的效果!彌補AVAudioPlayer的缺點


我們先明確一下我們需要的功能:

(1)初始化後即可立即播放

(2)能在一個時間段內播放同一音頻多次。這個再做個詳細說明:我們使用AVAudioPlayer時,play後必須等其停止了才能重新播放。我們這裡要改進的是即使前面的播放還沒有結束,我們也可以啟動新的播放,這個特別適用於播放敲擊的聲音,這樣我們會感覺聽到多個敲擊的聲音,而不是只有一個。記住這裡不是講和其他的AVAudioPlayer混音。

(3)能迴圈播放

(4)能暫停停止播放

(5)能播放震動和播放音頻並震動

(6)能調節聲道

(7)能調節音量


下面我們通過建立一個自訂的類來實現。

下面是標頭檔的代碼:

#import <AVFoundation/AVFoundation.h>#import <AudioToolbox/AudioToolbox.h>@interface SRAudioPlayer : NSObject{    AVAudioPlayer *_audioPlayer1;    AVAudioPlayer *_audioPlayer2;}@property (nonatomic,assign) float pan;    // 調節聲道平衡@property (nonatomic,assign) float volume; // 調節音量// 初始化- (id)initWithContentsOfURL:(NSURL *)URL error:(NSError *__autoreleasing *)outError;// 播放一次- (void)playOnce;// 迴圈播放- (void)playInfinite;// 播放並震動- (void)playOnceWithVibrate;- (void)pause;- (void)stop;// 震動- (void)vibrate;@end

我們在這裡弄了兩個AVAudioPlayer的執行個體,目的就是類比能在一個時間段內播放同一音頻多次。


下面是m檔案的代碼:

#import "SRAudioPlayer.h"@implementation SRAudioPlayer{    BOOL _isPlayingAudioPlayer1;}- (id)initWithContentsOfURL:(NSURL *)URL error:(NSError *__autoreleasing *)outError{    if ((self = [super init])) {        _audioPlayer1 = [[AVAudioPlayer alloc] initWithContentsOfURL:URL error:outError];        _audioPlayer2 = [[AVAudioPlayer alloc] initWithContentsOfURL:URL error:outError];                [_audioPlayer1 prepareToPlay];        [_audioPlayer2 prepareToPlay];    }    return self;}- (void)setPan:(float)pan{    if (_pan != pan) {        _pan = pan;        _audioPlayer1.pan = pan;        _audioPlayer2.pan = pan;    }}- (void)setVolume:(float)volume{    if (_volume != volume) {        _volume = volume;        _audioPlayer1.volume = volume;        _audioPlayer2.volume = volume;    }}- (void)playOnce{    _audioPlayer1.numberOfLoops = 1;    if (!_isPlayingAudioPlayer1) {        if (!_audioPlayer1.isPlaying) [_audioPlayer1 play];        else _audioPlayer1.currentTime = 0.0f;        _isPlayingAudioPlayer1 = YES;    } else {        if (!_audioPlayer2.isPlaying)[_audioPlayer2 play];        else _audioPlayer2.currentTime = 0.0f;        _isPlayingAudioPlayer1 = NO;    }}- (void)playInfinite{    [_audioPlayer2 pause];    _audioPlayer1.currentTime = 0.0f;    _audioPlayer1.numberOfLoops = -1;  }- (void)playOnceWithVibrate  //1{    _audioPlayer1.numberOfLoops = 1;    if (!_isPlayingAudioPlayer1) {        if (!_audioPlayer1.isPlaying) [_audioPlayer1 play];        else _audioPlayer1.currentTime = 0.0f;        _isPlayingAudioPlayer1 = YES;    } else {        if (!_audioPlayer2.isPlaying)[_audioPlayer2 play];        else _audioPlayer2.currentTime = 0.0f;        _isPlayingAudioPlayer1 = NO;    }    [self vibrate];}- (void)pause{    [_audioPlayer1 pause];    [_audioPlayer2 pause];}- (void)stop{    [_audioPlayer1 stop];    [_audioPlayer2 stop];}- (void)vibrate{    AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);}@end

這裡主要是說一下功能實現的trick:

我們通過兩個播放器。這裡時候,如果我們使用了playOnce 方法,那麼我們就判斷當前是哪個播放器在播放,如果是播放器1,那麼我們就用播放器2來播放。另一方面,如果兩個播放器同時都在播放,我們就將播放時間拉到頭,這樣就和重新播放一樣。通過這樣的方式,我們在播放音效時就會感覺是多個音頻。當然,如果要仿得更好的話,就是多弄幾個AVAudioPlayer,不過這樣會消耗更多的資源。


好了,就說到這吧!如果有不清楚或者發現程式有bug的可以發評論哈!


[本文為原創文章,如需轉寄,請註明出處:來自songrotek的部落格!謝謝合作]

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.