2、AVAudioPlayer

AVAudioPlayer音頻播放器

  
- (void)viewDidLoad {
    [super viewDidLoad];
    _player = [self playForFile:@"guitar"];
}


- (AVAudioPlayer *)playForFile:(NSString *)file{
    NSURL *fileUrl = [[NSBundle mainBundle] URLForResource:file withExtension:@"mp3"];
    NSError *error;
    AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:fileUrl error:&error];
    if (player) {
        player.numberOfLoops = -1;//無限循環(huán)播放
        player.enableRate = YES;//允許設(shè)置播放速率
        [player prepareToPlay];
    }else{
        NSLog(@"Error creating player : %@",[error localizedDescription]);
    }
    return player;
}


- (void)play{
    if (![_player isPlaying]) {
       [_player play];
    }
}

- (void)stop{
    if ([_player isPlaying]) {
       [_player stop];
       _player.currentTime = 0.0;
    }
}

此時運營程序并調(diào)用play方法,音樂會響起。但是如果此時切換手機左側(cè)的“鈴音/靜音”開關(guān),或者點擊手機鎖屏按鈕,正在播放的聲音會消失。現(xiàn)在我們要對AVAudioSession進行配置,可在 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions中配置以下代碼

AVAudioSession *sessioin = [AVAudioSession sharedInstance];
if (![sessioin setCategory:AVAudioSessionCategoryPlayback error:nil]) {
   NSLog(@"error....");
}
if (![sessioin setActive:YES error:nil]) {
   NSLog(@"error.....");
}

此時再切換“鈴音/靜音”開關(guān)時音樂播放已經(jīng)不受影響了,但是點擊鎖屏按鈕時音樂還是會暫停,接下來設(shè)置info.plist文件

Required background modes中添加App plays audio or streams audio/video using AirPlay
或者在Source Code中添加
<key>UIBackgroundModes</key>
<array>
    <string>audio</string>
</array>

接下來再次切換“鈴音/靜音”、點擊鎖屏按鈕時音樂播放不會再暫停了

處理中斷事件
當(dāng)接到來電或者其它應(yīng)用占用音頻播放時,音頻播放會消失暫停。當(dāng)正在播放的音頻被暫停時,AVAudioSession會發(fā)出通知AVAudioSessionInterruptionNotification,接下來處理AVAudioSessionInterruptionNotification通知

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioInterruption:) name:AVAudioSessionInterruptionNotification object:nil];

- (void) audioInterruption:(NSNotification *)notifi{
    AVAudioSessionInterruptionType    type = [[notifi.userInfo objectForKey:AVAudioSessionInterruptionTypeKey] unsignedIntegerValue];
    AVAudioSessionInterruptionOptions options = [[notifi.userInfo objectForKey:AVAudioSessionInterruptionOptionKey] unsignedIntegerValue];
    if (type == AVAudioSessionInterruptionTypeBegan) {
        //中斷音樂播放
        [self stop];
    }else if (type == AVAudioSessionInterruptionTypeEnded && options == AVAudioSessionInterruptionOptionShouldResume) {
        //中斷結(jié)束,繼續(xù)播放音樂
        [self play];
    }
}

AVAudioSessionInterruptionTypeAVAudioSessionInterruptionOptions是一個枚舉類型

typedef NS_ENUM(NSUInteger, AVAudioSessionInterruptionType)
{
    AVAudioSessionInterruptionTypeBegan = 1,  /* the system has interrupted your audio session */
    AVAudioSessionInterruptionTypeEnded = 0,  /* the interruption has ended */
};

/* For use with AVAudioSessionInterruptionNotification */
typedef NS_OPTIONS(NSUInteger, AVAudioSessionInterruptionOptions)
{
    AVAudioSessionInterruptionOptionShouldResume = 1
};

對線路改變的影響
當(dāng)插拔耳機、連接斷開藍牙耳機等操作時,AVAudioSession會發(fā)出音頻線路變化通知AVAudioSessionRouteChangeNotification

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioRouteChanged:) name:AVAudioSessionRouteChangeNotification object:nil];

- (void) audioRouteChanged:(NSNotification *)notifi{
    AVAudioSessionRouteChangeReason reason = [[notifi.userInfo objectForKey:AVAudioSessionRouteChangeReasonKey] unsignedIntegerValue];
    if (reason == AVAudioSessionRouteChangeReasonOldDeviceUnavailable) {
        [self stop];
    }
}

AVAudioSessionRouteChangeReason枚舉類型

typedef NS_ENUM(NSUInteger, AVAudioSessionRouteChangeReason)
{
    AVAudioSessionRouteChangeReasonUnknown = 0,
    AVAudioSessionRouteChangeReasonNewDeviceAvailable = 1,
    AVAudioSessionRouteChangeReasonOldDeviceUnavailable = 2,
    AVAudioSessionRouteChangeReasonCategoryChange = 3,
    AVAudioSessionRouteChangeReasonOverride = 4,
    AVAudioSessionRouteChangeReasonWakeFromSleep = 6,
    AVAudioSessionRouteChangeReasonNoSuitableRouteForCategory = 7,
    AVAudioSessionRouteChangeReasonRouteConfigurationChange = 8 // added in iOS 7
};

/* values for AVAudioSessionRouteChangeReasonKey in AVAudioSessionRouteChangeNotification userInfo dictionary
AVAudioSessionRouteChangeReasonUnknown
The reason is unknown.
AVAudioSessionRouteChangeReasonNewDeviceAvailable
A new device became available (e.g. headphones have been plugged in).
AVAudioSessionRouteChangeReasonOldDeviceUnavailable
The old device became unavailable (e.g. headphones have been unplugged).
AVAudioSessionRouteChangeReasonCategoryChange
The audio category has changed (e.g. AVAudioSessionCategoryPlayback has been changed to AVAudioSessionCategoryPlayAndRecord).
AVAudioSessionRouteChangeReasonOverride
The route has been overridden (e.g. category is AVAudioSessionCategoryPlayAndRecord and the output
has been changed from the receiver, which is the default, to the speaker).
AVAudioSessionRouteChangeReasonWakeFromSleep
The device woke from sleep.
AVAudioSessionRouteChangeReasonNoSuitableRouteForCategory
Returned when there is no route for the current category (for instance, the category is AVAudioSessionCategoryRecord
but no input device is available).
AVAudioSessionRouteChangeReasonRouteConfigurationChange
Indicates that the set of input and/our output ports has not changed, but some aspect of their
configuration has changed. For example, a port's selected data source has changed.
*/

同時也可以根據(jù)AVAudioSessionPort判斷

if (reason == AVAudioSessionRouteChangeReasonOldDeviceUnavailable) {
        AVAudioSessionRouteDescription *routeDescription = [notifi.userInfo objectForKey:AVAudioSessionRouteChangePreviousRouteKey];
        AVAudioSessionPortDescription *portDes = routeDescription.outputs[0];
        NSString *portType = portDes.portType;
        //判斷播放音頻的設(shè)備
        if ([portType isEqualToString:AVAudioSessionPortHeadphones]) {
            [self stop];
        }
}
/* output port types */
AVF_EXPORT AVAudioSessionPort const AVAudioSessionPortLineOut          API_AVAILABLE(ios(6.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos); /* Line level output on a dock connector */
AVF_EXPORT AVAudioSessionPort const AVAudioSessionPortHeadphones       API_AVAILABLE(ios(6.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos); /* Headphone or headset output */
AVF_EXPORT AVAudioSessionPort const AVAudioSessionPortBluetoothA2DP    API_AVAILABLE(ios(6.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos); /* Output on a Bluetooth A2DP device */
AVF_EXPORT AVAudioSessionPort const AVAudioSessionPortBuiltInReceiver  API_AVAILABLE(ios(6.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos); /* The speaker you hold to your ear when on a phone call */
AVF_EXPORT AVAudioSessionPort const AVAudioSessionPortBuiltInSpeaker   API_AVAILABLE(ios(6.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos); /* Built-in speaker on an iOS device */
AVF_EXPORT AVAudioSessionPort const AVAudioSessionPortHDMI             API_AVAILABLE(ios(6.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos); /* Output via High-Definition Multimedia Interface */
AVF_EXPORT AVAudioSessionPort const AVAudioSessionPortAirPlay          API_AVAILABLE(ios(6.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos); /* Output on a remote Air Play device */
AVF_EXPORT AVAudioSessionPort const AVAudioSessionPortBluetoothLE     API_AVAILABLE(ios(7.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos); /* Output on a Bluetooth Low Energy device */

/* port types that refer to either input or output */
AVF_EXPORT AVAudioSessionPort const AVAudioSessionPortBluetoothHFP API_AVAILABLE(ios(6.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos); /* Input or output on a Bluetooth Hands-Free Profile device */
AVF_EXPORT AVAudioSessionPort const AVAudioSessionPortUSBAudio     API_AVAILABLE(ios(6.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos); /* Input or output on a Universal Serial Bus device */
AVF_EXPORT AVAudioSessionPort const AVAudioSessionPortCarAudio     API_AVAILABLE(ios(7.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos); /* Input or output via Car Audio */
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi閱讀 7,418評論 0 10
  • **2014真題Directions:Read the following text. Choose the be...
    又是夜半驚坐起閱讀 9,787評論 0 23
  • 最近,有朋友在公眾號后臺給我留言。講了他在工作生活中的苦惱,想問問我的意見。我感到很高興,能夠取得別人信任本身就是...
    記憶裁縫鋪閱讀 1,947評論 1 3
  • 正義是什么呢?我們首先想到的是法官,因為他們代表正義,是這個時代的驕傲。其次想到的就是那個雙眼被蒙住,左手持天平,...
    Bob老師閱讀 974評論 0 1
  • 二勝長相一般,身高不到一米七,但是能說會道,嘴甜如蜜,出去打工沒多久就談了一個美麗可愛的女朋友,女孩家沒有兄弟姐妹...
    氧氣萌主tbm閱讀 1,172評論 8 27