Центр управления, не приостанавливает / не воспроизводит мой аудиопоток
Надеюсь, что проблема идет в правильный поток.
Я играю HLS, то есть я использую AVPlayer для воспроизведения смешанного контента (аудио и чистого видео) с сервера.
Я продолжаю воспроизводить звук после перемещения приложения в фоновый режим: я включил такую функцию в plist, плюс я сохраняю Prev Player, отключаю визуальные треки и устанавливаю nil AVPlayerLayer. Вот методы:
- (void)changePlayerState:(BOOL)restored
{
if (restored && !self.storedPlayer)
return;
if (!restored){
self.storedPlayer = self.playerView.player;
[self.playerView setPlayer:nil];
} else if (self.storedPlayer) {
[self.playerView setPlayer:self.storedPlayer];
self.storedPlayer = nil;
}
AVPlayerItem *playerItem = self.playerView.playerItem;
NSArray *tracks = [playerItem tracks];
for (AVPlayerItemTrack *playerItemTrack in tracks)
{
//
if ([playerItemTrack.assetTrack hasMediaCharacteristic:AVMediaCharacteristicVisual])
playerItemTrack.enabled = restored; //
}
}
И следующий:
- (void)setPlayer:(AVPlayer *)player
{
if (_player != player) {
[self removePlayerObservers];
_player = player;
[self configurePlayerLayer];
if (_player)
[self addPlayerObservers];
}
}
- (void)removePlayerObservers
{
if ([_player observationInfo] != nil) {
[_player removeObserver:self
forKeyPath:@"rate"
context:NPUIPlayerViewPlayerRateObservationContext];
[_player removeObserver:self
forKeyPath:@"isExternalPlaybackActive"
context:NPUIPlayerViewAirPlayVideoActiveObservationContext];
}
[self removePeriodicTimeObserver];
}
- (void)addPlayerObservers {
[_player addObserver:self
forKeyPath:@"rate"
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
context:NPUIPlayerViewPlayerRateObservationContext];
[_player addObserver:self
forKeyPath:@"isExternalPlaybackActive"
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
context:NPUIPlayerViewAirPlayVideoActiveObservationContext];
[self addPeriodicTimeObserver];
}
- (void)removePeriodicTimeObserver
{
if (_registeredTimeObserver) {
[_player removeTimeObserver:_registeredTimeObserver];
_registeredTimeObserver = nil;
}
}
- (void)addPeriodicTimeObserver
{
__weak NPUIPlayerView *weakSelf = self;
_registeredTimeObserver = [_player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(0.5f, 10) queue:dispatch_get_main_queue()
Поэтому после перемещения приложения на задний план, нажатия кнопки HOme и активации Центра управления (сдвигая вверх от кнопки, где находится калькулятор, камера, световые кнопки), я могу установить название воспроизводимого элемента, но управление плеером Apple в этом не отображается. не работает: нажатие паузы, воспроизведение не работает, а слайдер не работает. Я получаю события, когда нажимаю кнопки, но в то же время, несмотря на тот факт, что я звоню [пауза игрока] или меняю скорость, это не меняет кнопку. Но когда возникает проблема с доступом к аудио через Интернет, или звуковой буфер пуст, кнопка изменяется, пользовательский интерфейс был приостановлен. Ниже приведен код для настройки теперь воспроизводимого медиацентра и добавления команд
- (void)adjustNowPlayingScreen
{
MPNowPlayingInfoCenter *infoCenter = [MPNowPlayingInfoCenter defaultCenter];
NSMutableDictionary *mDic =[NSMutableDictionary dictionary];
NSString *newTitle = self.playerTitle.text ?: self.itemToPlay.shortName ?: self.itemToPlay.name ?: @"";
if (newTitle.length)
mDic[MPMediaItemPropertyTitle] = newTitle;
AVPlayerItem * item = [self.playerView.player currentItem];
CMTime itemDuration = [self.playerView.player.currentItem duration];
if (CMTIME_IS_VALID(itemDuration) ) {
NSTimeInterval duration = CMTimeGetSeconds(itemDuration);
if (duration)
mDic[MPMediaItemPropertyPlaybackDuration] = @(duration);
}
else
{
NSTimeInterval duration = CMTimeGetSeconds([item.asset duration]);
if (!isnan(duration) && duration > 0)
mDic[MPMediaItemPropertyPlaybackDuration] = @(duration);
else {
duration = CMTimeGetSeconds([[[[self playerView] playerItem] asset] duration]);
if (!isnan(duration) && duration > 0)
mDic[MPMediaItemPropertyPlaybackDuration] = @(duration);
}
}
NSString *urlStr = self.itemToPlay.autoQualityURL ?: self.itemToPlay.lowAutoQualityURL;
if (urlStr.length)
mDic[MPMediaItemPropertyAssetURL] = urlStr;
CMTime curTime = self.playerView.playerItem.currentTime;
if (CMTIME_IS_VALID(curTime)) {
NSTimeInterval duration = CMTimeGetSeconds(curTime);
mDic[MPNowPlayingInfoPropertyElapsedPlaybackTime]= @(duration);
}
if (mDic.count) {
#warning @"HACK: Necessary to change number of played items & index"
mDic[ MPMediaItemPropertyAlbumTrackNumber] = @(1);
mDic[ MPMediaItemPropertyAlbumTrackCount] = @(1);
mDic[ MPNowPlayingInfoPropertyPlaybackRate] = @(self.playerView.isPlaying ? 1.0 : 0.0);
UIImage *img = [UIImage imageNamed:@"team_4f6ae0b99d4b856118000124"];
mDic[MPMediaItemPropertyArtwork] = [[MPMediaItemArtwork alloc]initWithImage:img];
infoCenter.nowPlayingInfo = mDic;
}
}
- (void)addRemoteCommands
{
MPRemoteCommandCenter *commandCenter = [MPRemoteCommandCenter sharedCommandCenter];
MPRemoteCommand *command = [commandCenter pauseCommand];
command.enabled = true;
[command addTarget:self action:@selector(pauseCommand:)];
command = [commandCenter playCommand];
command.enabled = true;
[command addTarget:self action:@selector(playCommand:)];
command = [commandCenter togglePlayPauseCommand];
command.enabled = true;
[command addTarget:self action:@selector(toggleCommand:)];
command = [commandCenter seekForwardCommand];
command.enabled = true;
[command addTarget:self action:@selector(seekForwardCommand:)];
command = [commandCenter seekBackwardCommand];
command.enabled = true;
[command addTarget:self action:@selector(seekBackwardCommand:)];
}
- (void)updateElapsedTime
{
MPRemoteCommandCenter *commandCenter = [MPRemoteCommandCenter sharedCommandCenter];
MPRemoteCommand *command = [commandCenter togglePlayPauseCommand];
if (!command.enabled)
return;
[self adjustNowPlayingScreen];
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 2);
dispatch_after(popTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void){
[self updateElapsedTime];
});
}
- (void)removeRemoteCommands
{
MPRemoteCommandCenter *commandCenter = [MPRemoteCommandCenter sharedCommandCenter];
MPRemoteCommand *command = [commandCenter pauseCommand];
command.enabled = false;
[command removeTarget:self action:@selector(pauseCommand:)];
command = [commandCenter playCommand];
command.enabled = false;
[command removeTarget:self action:@selector(playCommand:)];
command = [commandCenter togglePlayPauseCommand];
command.enabled = false;
[command removeTarget:self action:@selector(toggleCommand:)];
command = [commandCenter seekForwardCommand];
command.enabled = false;
[command removeTarget:self action:@selector(seekForwardCommand:)];
command = [commandCenter seekBackwardCommand];
command.enabled = false;
[command removeTarget:self action:@selector(seekBackwardCommand:)];
}
- (void)seekBackwardCommand:(MPRemoteCommandEvent *)event
{
NSLog(@"%@",NSStringFromClass([event class]));
}
- (void)seekForwardCommand:(MPRemoteCommandEvent *)event
{
NSLog(@"%@",NSStringFromClass([event class]));
}
- (void)pauseCommand:(MPRemoteCommandEvent *)event
{
[self pause]; //_player pause];
AVPlayerItem *playerItem = self.playerView.playerItem;
NSArray *tracks = [playerItem tracks];
for (AVPlayerItemTrack *playerItemTrack in tracks)
{
/
if ([playerItemTrack.assetTrack hasMediaCharacteristic:AVMediaCharacteristicAudible])
playerItemTrack.enabled = false; /
}
MPNowPlayingInfoCenter *infoCenter = [MPNowPlayingInfoCenter defaultCenter];
NSMutableDictionary *mDic =[NSMutableDictionary dictionaryWithDictionary:infoCenter.nowPlayingInfo];
mDic[ MPNowPlayingInfoPropertyPlaybackRate] = @(0.0);
infoCenter.nowPlayingInfo = mDic;
}
Итак, моя команда pause вызвана, я вызываю метод pause AVPlayer. Но это не останавливает аудиопоток.
И Slider не работает, поэтому мои seekBackwardCommand/seekForwardCommand не вызываются.
Но, как я уже сказал, когда поток заканчивается (также аудио), проигрыватель в Центре управления переключает кнопку с воспроизведения в режим паузы, то есть каким-то образом прослушивает изменения аудиосеанса.
Я настраиваю категорию звука установкой AVAudioSessionCategoryPlayback
и режим настройки: AVAudioSessionModeMoviePlayback
Помогите пожалуйста, как правильно обрабатывать кнопки паузы / воспроизведения на экране управления, как включить слайдер?
Я запускаю свой код на iOS9, iPhone 6.