5

iOS 7 では、オーディオ中断リスナーが呼び出された後、オーディオ セッションを復元しようとすると、サイレント モードで失敗するようです。

割り込みリスナーの呼び出し

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

しかし、目覚まし時計が鳴るとすぐに、アプリのオーディオ セッションは終了します。リスナーは、適切な開始状態と終了状態で呼び出されます。

iOS 6 では問題なく動作しました。

これは iOS 7 のバグで、回避策があると聞きましたが、見つかりません。

Apple からの回避策またはテクニカル ノートへのリンクを知っている人はいますか?

編集: の代わりAVAudioSessionCategoryPlaybackに使用する必要があることがわかりましたkAudioSessionCategory_AmbientSound。今では動作します。しかし、それは私が望んでいたカテゴリーではありません。

4

3 に答える 3

1

以下の私のコードを見ることができます。でもまず、

このビット ターゲットを選択する必要があります | バックグラウンド モード | 機能からのオーディオ、エアプレイ、ピクチャー イン ピクチャー。

//  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 に答える
1

Apple のオーディオ セッション プログラミング ガイドに基づいて、割り込みハンドラーの変更をリッスンして対応する必要があります。これは、受信したパラメーター interruptState に基づいて、コードが中断の終了も処理できる/処理する必要があることを意味します。

このリンクの「オーディオ割り込み処理テクニック」をチェックしてください。

幸運を祈ります、Z.

于 2013-11-15T17:35:51.530 に答える
0

カテゴリも使用していAVAudioSessionCategoryPlaybackますが、中断しても自動的に再生が再開されません。iOS デバイスでのアクティブな AVAudioSession の検出を確認してください。選択した回答には、セッションの割り込みを処理する方法に関する詳細な手順が含まれています。

于 2015-05-20T22:20:57.017 に答える