我的iOS 7应用程序在必要时发出文本.
我想做的是让用户在我的运行时收听他的音乐或播客(或使用音频的任何其他应用).
预期的行为是,当我的应用说话时,其他音频会混音或躲避,然后其他音频会在之后的初始级别恢复音量.
我已经尝试了很多方法来实现这个目标,但没有什么是足够好的,因为我在代码之后列出了我面临的问题.
我目前的实现基于在播放或文本到语音之前创建会话,如下所示:
- + (void)setAudioActive {
- [[self class] setSessionActiveWithMixing:YES];
- }
播放/演讲结束后,我将我设置为闲置如下:
- + (void)setAudioIdle {
- [[self class] setSessionActiveWithMixing:NO];
- }
核心功能,根据活动参数处理会话设置,如下所示:
- + (void)setSessionActiveWithMixing:(BOOL)active
- {
- NSError *error = NULL;
- BOOL success;
- AVAudioSession *session = [AVAudioSession sharedInstance];
- static NSInteger counter = 0;
- success = [session setActive:NO error:&error];
- if (error) {
- DDLogError(@"startAudioMixAndBackground: session setActive:NO,%@",error.description);
- }
- else {
- counter--; if (counter<0) counter = 0;
- }
- if (active) {
- AVAudioSessionCategoryOptions options = AVAudioSessionCategoryOptionAllowBluetooth
- //|AVAudioSessionCategoryOptionDefaultToSpeaker
- |AVAudioSessionCategoryOptionDuckOthers
- ;
- success = [session setCategory://AVAudioSessionCategoryPlayback
- AVAudioSessionCategoryPlayAndRecord
- withOptions: options
- error: &error];
- if (error) {
- // Do some error handling
- DDLogError(@"startAudioMixAndBackground: setCategory:AVAudioSessionCategoryPlayback,error.description);
- }
- else {
- //activate the audio session
- success = [session setActive:YES error:&error];
- if (error) {
- DDLogError(@"startAudioMixAndBackground: session setActive:YES,error.description);
- }
- else {
- counter++;
- }
- }
- }
- DDLogInfo(@"Audio session counter is: %ld",counter);
- }
我目前的问题是:
1)当我的应用程序开始讲话时,我听到声音中有一些小故障,这使它不好;
2)当我将路由连接到蓝牙时,基础音频(比如播客或iPod音乐)变得非常低并且听起来很嘈杂,这使得我的解决方案仅仅无法使用,我的用户将拒绝此级别的低质量.
3)当其他蓝牙连接的设备试图发出声音时(例如汽车或实例中的GPS),我的应用程序没有收到任何中断(或我处理错误),请参阅我的代码如下:
- - (void)startAudioMixAndBackground {
- // initialize our AudioSession -
- // this function has to be called once before calling any other AudioSession functions
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioSessionDidChangeInterruptionType:)
- name:AVAudioSessionInterruptionNotification object:[AVAudioSession sharedInstance]];
- // set our default audio session state
- [[self class] setAudioIdle];
- [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
- if ([self canBecomeFirstResponder]) {
- [self becomeFirstResponder];
- }
- @synchronized(self) {
- self.okToPlaySound = YES;
- }
- //MPVolumeSettingsAlertShow();
- }
- // want remote control events (via Control Center,headphones,bluetooth,AirPlay,etc.)
- - (void)remoteControlReceivedWithEvent:(UIEvent *)event
- {
- if (event.type == UIEventTypeRemoteControl)
- {
- switch(event.subtype)
- {
- case UIEventSubtypeRemoteControlPause:
- case UIEventSubtypeRemoteControlStop:
- [[self class] setAudioIdle];
- break;
- case UIEventSubtypeRemoteControlPlay:
- [[self class] setAudioActive];
- break;
- default:
- break;
- }
- }
- }
- #pragma mark - Audio Support
- - (void)audioSessionDidChangeInterruptionType:(NSNotification *)notification
- {
- AVAudioSessionInterruptionType interruptionType = [[[notification userInfo]
- objectForKey:AVAudioSessionInterruptionTypeKey] unsignedIntegerValue];
- if (AVAudioSessionInterruptionTypeBegan == interruptionType)
- {
- DDLogVerbose(@"Session interrupted: --- Begin Interruption ---");
- }
- else if (AVAudioSessionInterruptionTypeEnded == interruptionType)
- {
- DDLogVerbose(@"Session interrupted: --- End Interruption ---");
- }
- }
解决方法
您的问题很可能是由于您正在设置的类别:AVAudioSessionCategoryPlayAndRecord. PlayAndRecord类别不允许您的应用与其他应用混合/播放音频.你应该在这里再次引用音频会话类别的文档:
https://developer.apple.com/library/ios/documentation/avfoundation/reference/AVAudioSession_ClassReference/Reference/Reference.html.看起来AVAudioSessionCategoryAmbient可能更像你想要的.