5

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

我的中断监听器调用

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

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

它在 iOS 6 上运行良好。

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

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

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

4

3 回答 3

1

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

查看此链接上的“音频中断处理技术”,我认为它会对您有很大帮助:https ://developer.apple.com/library/ios/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/HandlingAudioInterruptions/HandlingAudioInterruptions.html

祝你好运,Z。

于 2013-11-15T17:35:51.530 回答
1

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

你应该选择这个位目标 | 背景模式 | 来自 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
于 2015-10-26T19:40:56.087 回答
0

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

于 2015-05-20T22:20:57.017 回答