Я использую AVPlayer
для воспроизведения музыки. Моя проблема заключается в том, что после входящего вызова плеер не возобновляется. Как я могу справиться с этим при поступлении входящего вызова?
AVplayer возобновляется после входящего вызова
Ответ 1
Начиная с iOS 6 вы должны обрабатывать AVAudioSessionInterruptionNotification
и AVAudioSessionMediaServicesWereResetNotification
, перед этим вам нужно было использовать методы делегата.
Сначала вы должны позвонить в одноэлементную систему AVAudioSession и настроить ее для вашего желаемого использования.
Например:
AVAudioSession *aSession = [AVAudioSession sharedInstance];
[aSession setCategory:AVAudioSessionCategoryPlayback
withOptions:AVAudioSessionCategoryOptionAllowBluetooth
error:&error];
[aSession setMode:AVAudioSessionModeDefault error:&error];
[aSession setActive: YES error: &error];
Затем вы должны реализовать два метода для уведомлений, которые будет вызывать AVAudioSession:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleAudioSessionInterruption:)
name:AVAudioSessionInterruptionNotification
object:aSession];
Первый - для любого прерывания, которое будет вызвано из-за входящего вызова, будильника и т.д.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleMediaServicesReset)
name:AVAudioSessionMediaServicesWereResetNotification
object:aSession];
Второй, если медиасервер сбрасывается по какой-либо причине, вы должны обработать это уведомление, чтобы перенастроить аудио или сделать домашнее хозяйство. Кстати, словарь уведомлений не будет содержать никаких объектов.
Вот пример обработки прерывания воспроизведения:
- (void)handleAudioSessionInterruption:(NSNotification*)notification {
NSNumber *interruptionType = [[notification userInfo] objectForKey:AVAudioSessionInterruptionTypeKey];
NSNumber *interruptionOption = [[notification userInfo] objectForKey:AVAudioSessionInterruptionOptionKey];
switch (interruptionType.unsignedIntegerValue) {
case AVAudioSessionInterruptionTypeBegan:{
// • Audio has stopped, already inactive
// • Change state of UI, etc., to reflect non-playing state
} break;
case AVAudioSessionInterruptionTypeEnded:{
// • Make session active
// • Update user interface
// • AVAudioSessionInterruptionOptionShouldResume option
if (interruptionOption.unsignedIntegerValue == AVAudioSessionInterruptionOptionShouldResume) {
// Here you should continue playback.
[player play];
}
} break;
default:
break;
}
}
Обратите внимание, что вы должны возобновить воспроизведение, когда необязательное значение AVAudioSessionInterruptionOptionShouldResume
И для другого уведомления вы должны позаботиться о следующем:
- (void)handleMediaServicesReset {
// • No userInfo dictionary for this notification
// • Audio streaming objects are invalidated (zombies)
// • Handle this notification by fully reconfiguring audio
}
С уважением.
Ответ 2
AVAudioSession отправит уведомление, когда прерывание начнется и закончится. См. Обработка прерываний звука
- (id)init
{
if (self = [super init]) {
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:@selector(audioSessionInterrupted:) name:AVAudioSessionInterruptionNotification object:nil];
}
}
- (void)audioSessionInterrupted:(NSNotification *)notification
{
int interruptionType = [notification.userInfo[AVAudioSessionInterruptionTypeKey] intValue];
if (interruptionType == AVAudioSessionInterruptionTypeBegan) {
if (_state == GBPlayerStateBuffering || _state == GBPlayerStatePlaying) {
NSLog(@"Pausing for audio session interruption");
pausedForAudioSessionInterruption = YES;
[self pause];
}
} else if (interruptionType == AVAudioSessionInterruptionTypeEnded) {
if ([notification.userInfo[AVAudioSessionInterruptionOptionKey] intValue] == AVAudioSessionInterruptionOptionShouldResume) {
if (pausedForAudioSessionInterruption) {
NSLog(@"Resuming after audio session interruption");
[self play];
}
}
pausedForAudioSessionInterruption = NO;
}
}
Ответ 3
В некоторых случаях my AVPlayer
не возобновляет воспроизведение, даже если я вызываю play()
. Только перезагрузить плеер помогает мне решить проблему:
func interruptionNotification(_ notification: Notification) {
guard let type = notification.userInfo?[AVAudioSessionInterruptionTypeKey] as? UInt,
let interruption = AVAudioSessionInterruptionType(rawValue: type) else {
return
}
if interruption == .ended && playerWasPlayingBeforeInterruption {
player.replaceCurrentItem(with: AVPlayerItem(url: radioStation.url))
play()
}
}