AV Foundation - 在其他活动声音上面播放音频

问题:

在播放音频时让其他程序静音,或者在其他程序的音频之上播放音频。 

AVAudioSession 类由 AVFoundation 框架引入。每个 iOS 应用都有一个音频会话。这个会话可以被 AVAudioSession 类的 sharedInstance 类方法访问,如下: 

AVAudioSession *audioSession = [AVAudioSession sharedInstance];


在获得一个 AVAudioSession 类的实例后,你就能通过调用音频会话对象的 setCategory:error:实例方法,来从 iOS 应用可用的不同类别中作出选择。下面列出了可供使用的音频会话类别: 

 AVAudioSessionCategoryAmbient 

这个类别不会停止其他应用的声音,相反,它允许你的音频播放于其他应用的声音之 上,比如 iPod。你的应用的主 UI 线程会工作正常。调用 AVAPlayer 的 prepareToPlay 和 play 方法都将返回 YES。

AVAudioSessionCategorySoloAmbient 

 这个非常像 AVAudioSessionCategoryAmbient 类别,除了会停止其他程序的音频回放,比如 iPod 程序。当设备被设置为静音模式,你的音频回放将会停止。

AVAudioSessionCategoryRecord

这会停止其他应用的声音(比如 iPod)并让你的应用也不能初始化音频回放(比如 AVAudioPlayer)。在这种模式下,你只能进行录音。使用这个类别,调用 AVAudioPlayer 的 prepareToPlay 会返回 YES,但是调用 play 方法将返回 NO。主 UI 界面会照常工作。这时, 即使你的设备屏幕被用户锁定了,应用的录音仍会继续。

AVAudioSessionCategoryPlayback

这个类别会禁止其他应用的音频回放(比如 iPod 应用的音频回放)。你可以使用 AVAudioPlayer 的 prepareToPlay 和 play 方法,在你的应用中播放声音。主 UI 界面会照常工作。这时,即使屏幕被锁定或者设备为静音模式,音频回放都会继续。

AVAudioSessionCategoryPlayAndRecord

这个类别允许你的应用中同时进行声音的播放和录制。当你的声音录制或播放开始后, 其他应用的声音播放将会停止。主 UI 界面会照常工作。这时,即使屏幕被锁定或者设备为 静音模式,音频回放和录制都会继续。 

AVAudioSessionCategoryAudioProcessing  

这个类别用于应用中进行音频处理的情形,而不是音频回放或录制。设置了这种模式, 你在应用中就不能播放和录制任何声音。调用 AVAPlayer 的 prepareToPlay 和 play 方法都将 返回 NO。其他应用的音频回放,比如 iPod,也会在此模式下停止。 


例子:写一个音频播放器,它能 在其他应用的音频回放之上播放自己的音频文件。我们从下面这个方法开始: 

 

- (void)playOnOtherMusic{

    //设置音频类别

    NSError *audioSessionError = nil;

    AVAudioSession *audioSession = [AVAudioSession sharedInstance];

    if ([audioSession setCategory:AVAudioSessionCategoryAmbient error:&audioSessionError]) {

        NSLog(@"设置音频类别成功");

    }else{

        NSLog(@"不能设置音频类别");

    }

    //创建播放器并播放

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        NSString *filePath = [[NSBundle mainBundle]pathForResource:@"MySong" ofType:@"mp3"];

        NSData *fileData = [NSData dataWithContentsOfFile:filePath];

        NSError *audioPlayerError = nil;

        AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc]initWithData:fileData error:&audioPlayerError];

        if (audioPlayer != nil) {

            audioPlayer.delegate = self;

            if ([audioPlayer prepareToPlay] && [audioPlayer play]) {

                NSLog(@"Successfully started playing.");

            }else{

                NSLog(@"Failed to play the audio file.");

                audioPlayer = nil;

            }

        }else{

            NSLog(@"Could not instantiate the audio player.");

        }

    });

}

接下来,我们继续处理 AVAudioPlayerDelegate 协议方法: 

- (void)audioPlayerBeginInterruption:(AVAudioPlayer *)player{

    /* The audio session has been deactivated here */被打断

}

- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player withFlags:(NSUInteger)flags{

//打断结束

    if (flags == AVAudioSessionInterruptionOptionShouldResume){

        [player play];

    }

}

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{

//播放结束

    if (flag){

        NSLog(@"Audio player stopped correctly.");

    } else {

        NSLog(@"Audio player did not stop correctly."); }

    if ([player isEqual:self.audioPlayer]){

        self.audioPlayer = nil;

    } else {

        /* This is not the audio player */

    }

}

可以看到,我们在视图控制器的 playOnOtherMusic 实例方法中使用了 AVAudioSession 的共享实例,将我们的应用的音频分类设置为 AVAudioSessionCategoryAmbient,这样就允许 了我们的应用可以在其他应用的音频回放上面播放声音。 

 




你可能感兴趣的:(iOS开发-音频和视频)