【问题标题】:How to restore the audio session after an audio interruption in iOS 7?如何在 iOS 7 中音频中断后恢复音频会话?
【发布时间】:2013-11-02 16:51:14
【问题描述】:

在 iOS 7 中,在我的音频中断侦听器被调用后,任何恢复音频会话的尝试似乎都会以静默方式失败。

我的中断监听器调用

NSError *activationError = nil;
[[AVAudioSession sharedInstance] setActive:YES error:&activationError];

但是闹钟一响,应用程序的音频会话就停止了。侦听器以适当的开始和结束状态被调用。

它在 iOS 6 上运行良好。

我听说这是 iOS 7 中的bug,并且有解决方法,但找不到。

有人知道 Apple 提供的解决方法或技术说明的链接吗?

编辑:我发现我必须使用AVAudioSessionCategoryPlayback 而不是kAudioSessionCategory_AmbientSound。现在它起作用了。但这不是我想要的类别。

【问题讨论】:

    标签: iphone objective-c ipad ios7 avaudiosession


    【解决方案1】:

    根据 Apple 的音频会话编程指南,您应该聆听并响应中断处理程序中的变化。这意味着您的代码也可以/应该根据接收到的参数 interruptState 处理中断的结束。

    在这个链接上查看“音频中断处理技巧”,我想对你有很大帮助:https://developer.apple.com/library/ios/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/HandlingAudioInterruptions/HandlingAudioInterruptions.html

    祝你好运, Z.

    【讨论】:

    • 编程指南没有提供太多帮助:零示例代码。在您使用音频单元的情况下,它只会说“重新激活音频会话”,我正在这样做(没有任何错误)但声音保持静音。
    【解决方案2】:

    您可以在下面看到我的代码。但首先,

    你应该选择这个位目标 |背景模式 |来自 Capabilities 的音频、Airplay 和画中画。

    //  ViewController.m
    //  AVAudioPlayer
    
    #import "ViewController.h"
    
    @import AVFoundation;
    @import MediaPlayer;
    
    @interface ViewController ()
    
    @property (strong, nonatomic) AVAudioPlayer *audioPlayer;
    @property (weak, nonatomic) IBOutlet UISlider *volumeSlider;
    @property (weak, nonatomic) IBOutlet UISlider *rateSlider;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        [self setupAudio];
    }
    
    - (void) setupAudio {
        NSError *error;
        [[AVAudioSession sharedInstance] setActive:YES error:&error];
        if (error != nil) {
            NSAssert(error == nil, @"");
        }
    
        [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error];
        if (error != nil) {
            NSAssert(error == nil, @"");
        }
    
        NSURL *soundURL = [[NSBundle mainBundle] URLForResource:@"SoManyTimes" withExtension:@"mp3"];
        self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error:&error];
        if (error != nil) {
            NSAssert(error == nil, @"");
        }
    
        //[self.audioPlayer setVolume:0.8];
        self.audioPlayer.enableRate = YES;
        [self.audioPlayer prepareToPlay];
        [self.audioPlayer setVolume:self.volumeSlider.value];
    
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioInterrupt:) name:AVAudioSessionInterruptionNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioRouteChanged:) name:AVAudioSessionRouteChangeNotification object:nil];
    
        MPRemoteCommandCenter *commandCenter = [MPRemoteCommandCenter sharedCommandCenter];
        [commandCenter.playCommand addTarget:self action:@selector(playButtonPressed:)];
        [commandCenter.stopCommand addTarget:self action:@selector(stopButtonPressed:)];
        [commandCenter.pauseCommand addTarget:self action:@selector(stopButtonPressed:)];
    
    }
    
    - (void) audioRouteChanged:(NSNotification*)notification {
        NSNumber *reason = (NSNumber*)[notification.userInfo valueForKey:AVAudioSessionRouteChangeReasonKey];
        switch ([reason integerValue]) {
            case AVAudioSessionRouteChangeReasonOldDeviceUnavailable:
            case AVAudioSessionRouteChangeReasonNoSuitableRouteForCategory:
                [self stopButtonPressed:nil];
                break;
    
            default:
                break;
        }
    }
    
    - (void) audioInterrupt:(NSNotification*)notification {
        NSNumber *interruptionType = (NSNumber*)[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey];
        switch ([interruptionType integerValue]) {
            case AVAudioSessionInterruptionTypeBegan:
                [self stopButtonPressed:nil];
                break;
            case AVAudioSessionInterruptionTypeEnded:
            {
                if ([(NSNumber*)[notification.userInfo valueForKey:AVAudioSessionInterruptionOptionKey] intValue] == AVAudioSessionInterruptionOptionShouldResume) {
                    [self playButtonPressed:nil];
                }
                break;
            }
            default:
                break;
        }
    }
    
    - (IBAction)playButtonPressed:(id)sender {
        BOOL played = [self.audioPlayer play];
        if (!played) {
            NSLog(@"Error");
        }
    
        MPMediaItemArtwork *albumArt = [[MPMediaItemArtwork alloc] initWithImage:[UIImage imageNamed:@"CoverArt"]];
    
        NSDictionary *songInfo = @{
    
                                   MPMediaItemPropertyTitle:@"So Many Times",
                                   MPMediaItemPropertyArtist:@"The Jellybricks",
                                   MPMediaItemPropertyAlbumTitle:@"Soap Opera",
                                   MPMediaItemPropertyArtwork:albumArt,
                                   MPMediaItemPropertyPlaybackDuration:@(self.audioPlayer.duration),
                                   MPNowPlayingInfoPropertyElapsedPlaybackTime:@(self.audioPlayer.currentTime),
    
                                   };
    
        [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:songInfo];
    
    }
    
    - (IBAction)stopButtonPressed:(id)sender {
        [self.audioPlayer stop];
    }
    
    - (IBAction)volumeSliderChanged:(UISlider*)sender {
        [self.audioPlayer setVolume:sender.value];
    }
    
    - (IBAction)rateSliderChanged:(UISlider*)sender {
        [self.audioPlayer setRate:sender.value];
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    - (void) dealloc {
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    
    @end
    

    【讨论】:

      【解决方案3】:

      我也在使用AVAudioSessionCategoryPlayback 类别,但中断不会自动恢复播放。查看Detecting active AVAudioSessions on iOS device。所选答案包含有关如何处理会话中断的详细说明。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-09
        • 2012-03-17
        • 1970-01-01
        相关资源
        最近更新 更多