Подтвердить что ты не робот

Фоновый звук не возобновляется после вызова

Мой фоновый звук прекрасно работает почти все время. Экран заблокирован или отключен. Но когда пользователь имеет приложение в фоновом режиме и получает вызов, даже если пользователь не отвечает на звонок, фоновый звук не возобновляется после окончания прерывания.

Музыкальное приложение правильно возобновляет фоновый звук, если он был прерван.

Мне не хватает какого-либо свойства или мне нужно иметь обратный вызов или задать фоновую задачу, чтобы продолжить фоновое выполнение звука после прерывания? Или это то, что мы не можем сделать?

4b9b3361

Ответ 1

Мы возобновляем наш звук после исходящего вызова и входящего вызова, когда приложение находится в фоновом режиме.

Мы воспроизводим аудио с AVAudioPlayer и слушаем AVAudioSessionInterruptionNotification. Apple автоматически приостанавливает работу AVAudioPlayer для вас, и когда вы скажете, что он возобновит работу после того, как вы получили прерывание, Apple снова настроит ваш сеанс. См. Таблицу 3-2 из Обработка прерываний звука по рекомендациям, если вы используете другие типы аудиотехнологий.

Подпишитесь на уведомление:

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onAudioSessionEvent:) name:AVAudioSessionInterruptionNotification object:nil];

Обработать уведомление:

- (void) onAudioSessionEvent: (NSNotification *) notification
{
    //Check the type of notification, especially if you are sending multiple AVAudioSession events here
    if ([notification.name isEqualToString:AVAudioSessionInterruptionNotification]) {
        NSLog(@"Interruption notification received!");

        //Check to see if it was a Begin interruption
        if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] isEqualToNumber:[NSNumber numberWithInt:AVAudioSessionInterruptionTypeBegan]]) {
            NSLog(@"Interruption began!");

        } else {
            NSLog(@"Interruption ended!");
            //Resume your audio
        }
    }
}

Ответ 2

По моему опыту я обнаружил, что мне пришлось "подождать секунду или два", прежде чем пытаться снова открыть аудиоустройство. Я думаю, что после того, как ОС переключится обратно в ваше приложение с помощью вызова, приложение по-прежнему отключается.

что-то вроде этого, когда вы вернетесь на передний план после того, как узнаете, что ваш аудио-сеанс остановлен:

            dispatch_time_t restartTime = dispatch_time(DISPATCH_TIME_NOW, 
                                                      1.5LL * NSEC_PER_SEC);

            dispatch_after(restartTime, dispatch_get_global_queue(0, 0), ^{ 
                [audioSystem restart]; 
            });

Ответ 3

Я использую Xamarin, так что это С#, но для меня работает следующий код. Я сначала установил, что мой AppDelegate реализует методы делегирования AVAudioSession, включая IAVAudioSessionDelegate

            public partial class AppDelegate: UIApplicationDelegate, IAVAudioSessionDelegate

Я добавил переменную в класс AppDelegate для сеанса аудио

            public static AVAudioSession AudioSession;

В переопределении метода FinishedLaunching:

            AudioSession = AVAudioSession.SharedInstance();
            AudioSession.Delegate = this;
            error = AudioSession.SetCategory( AVAudioSessionCategory.Playback, AVAudioSessionCategoryOptions.DuckOthers );
            AudioSession.SetMode( new NSString( "AVAudioSessionModeMoviePlayback" ), out error );

Два соответствующих метода делегата в AppDelegate.cs:

            [Export( "beginInterruption" )]
            public void BeginInterruption()
            {
                 PlayerViewController.BeginSessionInterruption();
            }

            [Export( "endInterruptionWithFlags:" )]
            public void EndInterruption( AVAudioSessionInterruptionFlags flags )
            {  // ignore the flags so we're not dependent on the interrupting event saying that we can resume
                 PlayerViewController.ResumeAfterSessionInterruption();
            }

My AppDelegate также имеет переопределение OnActivated для включения видеодорожек, если это видеообъявление, и переопределение DidEnterBackground для отключения дорожек медиа-видео, но все равно воспроизводить аудио.

В методе PlayerViewController.BeginSessionInterruption() я не могу посмотреть на Player.Rate, чтобы проверить, работает ли плеер в то время, потому что прерывание сигнала тревоги или телефонный звонок уже приостановили проигрыватель. В разделе "Ответ на прерывания" руководства по программированию сеансов Apple Audio с добавлением моего внимания:

  • Ваше приложение активно, воспроизведение аудио.
  • Приходит телефонный звонок. Система активирует сеанс аудиозаписей телефонов.
  • Система деактивирует ваш сеанс аудио. На этом этапе воспроизведение * в приложении прекратилось *.
  • Система вызывает функцию обратного вызова прослушивателя прерывания, указывающую, что ваш сеанс отключен. ...

Кнопка My PlayerViewController Play имеет свойство Paused для переключения между Play и Pause и рисования соответствующего изображения кнопки. Поэтому вместо проверки Player.Rate, я смотрю, является ли свойство кнопки Paused ложным:

            public void BeginSessionInterruption()
            {
                 PlayerWasRunningOnInterruption = !btnPlay.Paused;
                 TogglePlayPause( true );  // put the Play button into the Paused state to agree with the player being stopped
            }

            public void ResumeAfterSessionInterruption()
            {
                NSError error;
                AppDelegate.AudioSession.SetActive( true, AVAudioSessionSetActiveOptions.NotifyOthersOnDeactivation, out error );  // always reactivate the audio session

                if ( PlayerWasRunningOnInterruption )
                {
// rewind a little bit
// call btnPlayClick to resume the playback as if the user pressed the Play button
                }
            }

Ответ 4

если вы только обнаруживаете статус вызова, вы можете использовать CTCallCenter, но если вы хотите обнаружить прерывание (включая прерывание вызова), вы можете использовать AVAudioSessionInterruptionNotification, и если вы хотите поддержать фон, вы должны добавить такой код:

  [[AVAudioSession sharedInstance] setActive:YES error:nil];
  [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];

прежде чем вы возобновите воспроизведение музыки в background.hope, это может помочь.

Ответ 5

Для меня работают только два варианта:

  • перезагрузить AVPlayer или AVAudioPlayer после завершения прерывания

    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()
    }
    

    }

  • использовать

AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, with: .mixWithOthers)

Ответ 6

Я пробовал в течение 3 часов, наконец, получил его, вот что я сделал

#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>

@interface ViewController ()

    @property(strong, nonatomic)AVAudioPlayer *player;
    @property(strong)AVAudioSession *session;
@end

@implementation ViewController


- (IBAction)playsound:(id)sender

{

   NSURL *url=[[NSURL alloc]initWithString:[[NSBundle mainBundle]       pathForResource:@"sound" ofType:@"mp3"]];
NSError *err;

    self.player=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:&err];
    [self.player setDelegate:self];
    [self.player setVolume:2.5];

    self.session=[AVAudioSession sharedInstance];

    [self.player prepareToPlay];
    [self.player play];

}

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag

{

    NSError *err;
    [self.session setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&err];



}


@end