2015-03-29 2 views
3

Я пытаюсь написать простое личное приложение для радио и имел неприятную проблему.Использование пульта дистанционного управления с AVPlayer в iOS 7 и 8

Я пытаюсь воспроизвести файл .pls (stream) с удаленного сервера с помощью AVPlayer, и мне удалось это сделать. Теперь я могу воспроизвести поток, но, как я упоминал в названии, я не могу дистанционно управлять параметром play/pause, когда приложение находится в фоновом режиме.

Я много искал в Интернете по этой теме и нашел два решения.

1 Как в Apple Remote Control Events Документация с использованием класса «MPRemoteCommandCenter» для обработки этого, но для этого решения я не могу найти никакого объяснения, как я буду использовать AVPlayer с ним. Это приводит меня ко второму решению, так как я понятия не имею, как использовать класс MPRemoteCommandCenter.

2- Как почти все люди упомянули о remoteControlReceivedWithEvent: способ. Однако, когда я пытаюсь использовать этот подход, я не могу ответить. Мой remoteControlReceivedWithEvent: метод никогда не вызывался. Вот мой код, как я реализовал поведение:

У меня есть два класса, один из которых называется EGPlayRadio.m, который содержит материалы AVPlayer и AVAudioSession, а другой - EGMainMenuViewController.m, который отображает кнопку воспроизведения и кнопку приостановки транслировать радио.

  • Я оплатил внимание к первому вызову [AVSession sharedInstance] перед вызовом [[UIApplication sharedApplication] beginReceivingRemoteControlEvents] метода.

  • Также я обратил внимание на это, предоставляя разрешение на воспроизведение фонового звука приложения из настроек сборки проекта.

Однако, после поиска много в Интернете не могу найти подходящее решение для моей проблемы. Вот мои два класса, которые я реализовал:

EGPlayRadio.m

#import "EGPlayRadio.h" 
#import <MediaPlayer/MediaPlayer.h> 
#import <AVFoundation/AVFoundation.h> 

@interface EGPlayRadio() <AVAudioPlayerDelegate> 

@property (nonatomic, strong) AVAudioSession *audioSession; 
@property (nonatomic, strong) AVPlayer *player; 

@end 

@implementation EGPlayRadio 

- (id)initDefault 
{ 
    self = [super init]; 
    if (self) 
    { 
     _audioSession = [AVAudioSession sharedInstance]; 
     [_audioSession setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil]; 
     [[AVAudioSession sharedInstance] setActive: YES error: nil]; 
     [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil]; 
     NSURL *url = [[NSURL alloc] initWithString:@"http://LINK-OF-THE-PLS-FILE"]; 
     _player = [[AVPlayer alloc] initWithURL:url]; 
    } 
    return self; 
} 

- (void)playRadio 
{ 
    [self.player play]; 
} 

- (void)pauseRadio 
{ 
    [self.player pause]; 
} 

EGMainMenuViewController.m

@interface EGRMainMenuViewController() 

@property (nonatomic, strong) IBOutlet UIButton *playButton; 
@property (nonatomic, strong) IBOutlet UIButton *pauseButton; 
@property (nonatomic, strong) EGPlayRadio *radioControl; 

@end 

@implementation EGRMainMenuViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.radioControl = [[EGPlayRadio alloc] initDefault]; 
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; 
    [self becomeFirstResponder]; 
    self.pauseButton.enabled = NO; 
    self.pauseButton.alpha = 0.3f; 
} 

- (BOOL)canBecomeFirstResponder 
{ 
    return YES; 
} 

- (IBAction)musicInteracted:(id)sender 
{ 
    if (sender == self.playButton) 
    { 
     self.pauseButton.enabled = YES; 
     self.pauseButton.alpha = 1.0f; 
     self.playButton.enabled = NO; 
     self.playButton.alpha = 0.3f; 
     [self.radioControl playRadio]; 
    } 
    else 
    { 
     self.pauseButton.enabled = NO; 
     self.pauseButton.alpha = 0.3f; 
     self.playButton.enabled = YES; 
     self.playButton.alpha = 1.0f; 
     [self.radioControl pauseRadio]; 
    } 

} 

-(void)remoteControlReceivedWithEvent:(UIEvent *)event 
{ 
    switch (event.subtype) { 
     case UIEventSubtypeRemoteControlTogglePlayPause: 
      //[streamer pause]; 
      break; 
     case UIEventSubtypeRemoteControlPlay: 
      //[streamer start]; 
      break; 
     case UIEventSubtypeRemoteControlPause: 
      //[streamer pause]; 
      break; 
     case UIEventSubtypeRemoteControlStop: 
      //[streamer stop]; 
      break; 
     default: 
      break; 
    } 

} 

@end 

ответ

2

Для других, имеющих один и тот же вопрос, я решил свою проблему следующим образом:

В EGPlayRadio.м класс, я выделил AVAudioSession с помощью

[_audioSession setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil]; 

InstEd этого мы должны использовать:

[_audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; 

Это проблема для меня, после изменения этого, я могу успешно получить удаленные уведомления.

1

Вы должны использовать MPNowPlayingInfoCenter. Это хорошо документировано в документации Apple.

2

Благодаря @Onur Şahindur, у меня есть эта работа, наконец, после нескольких лет борьбы с этим. Не могу поверить, что это нигде не документировано. Как сказал Онур, многих из нас много в stackoverflow, которые боролись с этим, но это первое решение, которое действительно работает.

Я также получил эту работу с классом «MPRemoteCommandCenter». Я внедрил все в appDelegate с вызовами метода на мой синглтон, который управляет моим AVPlayer. Вот мое решение:

_audioSession = [AVAudioSession sharedInstance]; 

// Previously, I used [_audioSession setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&setCategoryError]; 
// As noted by @Onur, it has to be the following (without options) 
[_audioSession setCategory:AVAudioSessionCategoryPlayback error:nil]; 

// Apple documentation says you don't need the following if you are using 
// the MPRemoteCommandCenter, but that is not true. It is needed. 
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; 
[self becomeFirstResponder]; 


MPRemoteCommandCenter *commandCenter = [MPRemoteCommandCenter sharedCommandCenter]; 
[commandCenter.togglePlayPauseCommand setEnabled:YES]; 
[commandCenter.playCommand setEnabled:YES]; 
[commandCenter.pauseCommand setEnabled:YES]; 
[commandCenter.nextTrackCommand setEnabled:YES]; 
[commandCenter.previousTrackCommand setEnabled:YES]; 
[commandCenter.togglePlayPauseCommand addTargetWithHandler: ^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) { 
    [[MediaController sharedInstance] playOrPauseMusic]; // Begin playing the current track. 
    return MPRemoteCommandHandlerStatusSuccess; 
}]; 

[commandCenter.playCommand addTargetWithHandler: ^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) { 
    [[MediaController sharedInstance] playOrPauseMusic]; // Begin playing the current track. 
    return MPRemoteCommandHandlerStatusSuccess; 
}]; 

[commandCenter.pauseCommand addTargetWithHandler: ^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) { 
    [[MediaController sharedInstance] playOrPauseMusic]; // Begin playing the current track. 
    return MPRemoteCommandHandlerStatusSuccess; 
}]; 

[commandCenter.nextTrackCommand addTargetWithHandler: ^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) { 
    [[MediaController sharedInstance] fastForward]; // forward to next track. 
    return MPRemoteCommandHandlerStatusSuccess; 
}]; 

[commandCenter.previousTrackCommand addTargetWithHandler: ^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) { 
    [[MediaController sharedInstance] rewind]; // back to previous track. 
    return MPRemoteCommandHandlerStatusSuccess; 
}]; 

[commandCenter.stopCommand setEnabled:NO]; 
[commandCenter.skipForwardCommand setEnabled:NO]; 
[commandCenter.skipBackwardCommand setEnabled:NO]; 
[commandCenter.enableLanguageOptionCommand setEnabled:NO]; 
[commandCenter.disableLanguageOptionCommand setEnabled:NO]; 
[commandCenter.changeRepeatModeCommand setEnabled:NO]; 
[commandCenter.changePlaybackRateCommand setEnabled:NO]; 
[commandCenter.changeShuffleModeCommand setEnabled:NO]; 
// Seek Commands 
[commandCenter.seekForwardCommand setEnabled:NO]; 
[commandCenter.seekBackwardCommand setEnabled:NO]; 
[commandCenter.changePlaybackPositionCommand setEnabled:NO]; 
// Rating Command 
[commandCenter.ratingCommand setEnabled:NO]; 

// Feedback Commands 
// These are generalized to three distinct actions. Your application can provide 
// additional context about these actions with the localizedTitle property in 
// MPFeedbackCommand. 
[commandCenter.likeCommand setEnabled:NO]; 
[commandCenter.dislikeCommand setEnabled:NO]; 
[commandCenter.bookmarkCommand setEnabled:NO]; 

В дополнение к вышесказанному (который я поставил в AppDelegate - применение: didFinishLaunchingWithOptions), добавьте к вашему AppDelegate также:

- (BOOL) canBecomeFirstResponder 
{ 
    return YES; 
} 

Затем, каждый раз, когда вы изменяете элемент медиа вы собираетесь играть, я выполнить следующий код из моей медиа-контроллера одноточечного:

ipodControlArtwork = [[MPMediaItemArtwork alloc]initWithImage:artworkImage]; 
if (artworkImage != nil && nowPlayingArtist != nil && nowPlayingTitle != nil && ipodControlArtwork != nil) { 

    [MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys: 
                  nowPlayingTitle, MPMediaItemPropertyTitle, 
                  nowPlayingArtist, MPMediaItemPropertyArtist, 
                  ipodControlArtwork, MPMediaItemPropertyArtwork, 
                  [NSNumber numberWithDouble:0.0], MPNowPlayingInfoPropertyPlaybackRate, nil]; 
} 
+0

Использование необъявленной идентификатора «MediaController» дать мне эту ошибку @ JeffB6688 –