如果屏幕被锁定,当点击暂停按钮时,avplayer不会暂停

如果应用正在播放音频和手机屏幕被锁定,则控制屏幕如下所示。 我无法对avplayer采取任何行动

在此处输入图像描述

在我的appdelegate中,我实现了:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { MPRemoteCommandCenter *rcc = [MPRemoteCommandCenter sharedCommandCenter]; [[rcc skipForwardCommand] setEnabled:NO]; [[rcc skipBackwardCommand] setEnabled:NO]; [[rcc nextTrackCommand] setEnabled:NO]; [[rcc previousTrackCommand] setEnabled:NO]; [[rcc skipForwardCommand] setEnabled:NO]; [[rcc skipBackwardCommand] setEnabled:NO]; rcc.playCommand.enabled = YES; rcc.pauseCommand.enabled = YES; [[MPRemoteCommandCenter sharedCommandCenter].playCommand addTarget:self action:@selector(play)]; [[MPRemoteCommandCenter sharedCommandCenter].pauseCommand addTarget:self action:@selector(pause)]; } - (void) play { [[MyVideoController instance] play]; } - (void) pause { [[MyVideoController instance] pause]; } 

class MyVideoController包括:

 - (void) pause { [self.avPlayer pause]; } - (void) play { [self.avPlayer play]; } 

即使触发了这些方法(添加要检查的断点),也不会对avplayer采取任何操作。 无论如何,avplayer都不会停顿。

有没有办法暂停avplayer?

编辑1:添加完整的代码

在我的AppDelegate中:

 - (void) remoteControlReceivedWithEvent: (UIEvent *) event { [[ZVideoPlayerController instance] eventReceived:event]; if (event.type == UIEventTypeRemoteControl) { switch (event.subtype) { case UIEventSubtypeRemoteControlTogglePlayPause: { break; } case UIEventSubtypeRemoteControlPlay: { [[ZVideoPlayerController instance] play]; break; } case UIEventSubtypeRemoteControlPause: { [[ZVideoPlayerController instance] pause]; break; } default: break; } } 

}

 - (void)applicationDidEnterBackground:(UIApplication *)application { [[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; [self becomeFirstResponder]; } - (void)applicationDidBecomeActive:(UIApplication *)application { [[UIApplication sharedApplication] endReceivingRemoteControlEvents]; } 

我收到的事件,但音频不会在播放器上调用暂停方法。

编辑2:PlayerController类中的实例声明

 + (instancetype)instance { static id instance = nil; if (instance == nil) { static dispatch_once_t onceToken = 0; dispatch_once(&onceToken, ^(void) { NSAssert(instance == nil, @"Singleton instance is already allocated."); instance = [[super allocWithZone:NULL] init]; }); } return instance; } 

初始化AVPlayer

  AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil]; AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:avAsset]; AVAudioSession *session = [AVAudioSession sharedInstance]; [session setCategory:AVAudioSessionCategoryPlayback error:nil]; NSError *activationError = nil; BOOL success = [[AVAudioSession sharedInstance] setActive: YES error: &activationError]; NSMutableDictionary *songInfo = [[NSMutableDictionary alloc] init]; MPMediaItemArtwork *albumArt = [[MPMediaItemArtwork alloc] initWithImage: [UIImage imageNamed:@"Audio_Thumbnail_Play"]]; [songInfo setObject:title forKey:MPMediaItemPropertyTitle]; [songInfo setObject:@"100" forKey:MPMediaItemPropertyPlaybackDuration]; [songInfo setObject:albumArt forKey:MPMediaItemPropertyArtwork]; [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:songInfo]; self.avPlayer = [AVPlayer playerWithPlayerItem:playerItem]; self.avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:self.avPlayer]; 

我找到了问题的解决方案。 当我获得avPlayer的nil值时,我使用了我的PageViewController类来获取PlayerController的实例。 然后我使用这个playerController的实例来播放和暂停我的avplayer,因为这个实例保存了对avPlayer的引用。

 - (PlayerController *)getVideoController { NSArray *controllers = [UtiliyClass getNavigationController].viewControllers; PageViewController *pageController = nil; for (UIViewController *cont in controllers) { if ([cont isKindOfClass:[PageViewController class]]) { pageController = (PageViewController *)cont; break; } } if (pageController == nil) { return nil; } NSArray *objectsController =pageController.pageController.viewControllers; PlayerController *videoPlayerController = nil; for (UIViewController *item in objectsController) { if ([item isKindOfClass:[PlayerController class]]) { videoPlayerController = (PlayerController *)item; break; } } return videoPlayerController; } - (void) pause { PlayerController *controller = [self getVideoController]; [controller.avPlayer pause]; } - (void) play { PlayerController *controller = [self getVideoController]; [controller.avPlayer play]; } 

当应用程序被锁定时,您需要注册远程通知以更新播放器状态。对于以下内容:

在AppDelegate中添加它,理想情况下在applicationDidEnterBackground中:

 [[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; [self becomeFirstResponder]; 

这在applicationDidBecomeActive中:

 [[UIApplication sharedApplication] endReceivingRemoteControlEvents]; 

通过在AppDelagate中添加远程通知来接收远程通知。 这将在手机锁定时收听所有操作。

 - (void)remoteControlReceivedWithEvent:(UIEvent *)event { if (event.type == UIEventTypeRemoteControl){ // Call method of your player where you want to make change (Pause , Paly), // I am calling a shared view for example, Its up to your logic how you want to deal it [[AudioPlayerView sharedPlayerView] remoteControlReceivedWithEvent:event]; } } 

并在那里得到你想要的事件并相应地更新状态

  - (void)remoteControlReceivedWithEvent:(UIEvent *)event { if (event.type == UIEventTypeRemoteControl){ switch (event.subtype){ case UIEventSubtypeRemoteControlPlay: [[MyVideoController instance] play]; break; case UIEventSubtypeRemoteControlPause: [[MyVideoController instance] pause]; break; case UIEventSubtypeRemoteControlTogglePlayPause: // Check if state is playing , call pause else call play break; } default: break; } } } 

在iOS 7.1及更高版本中,使用共享MPRemoteCommandCenter对象注册远程控制事件。 使用共享命令中心对象时,无需调用此方法。 此方法使用响应程序链开始传递远程控制事件。 远程控制事件源自耳机和外部附件发出的命令,用于控制应用程序呈现的多媒体。 要停止接收远程控制事件,必须调用endReceivingRemoteControlEvents()。

在init音频季节的didfinishlunching中添加以下代码并获取远程控制事件:

  // Initialize the AVAudioSession here. if (![[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&myErr]) { // Handle the error here. NSLog(@"Audio Session error %@, %@", myErr, [myErr userInfo]); } else{ // Since there were no errors initializing the session, we'll allow begin receiving remote control events [[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; } 

用于复制commadn使用此代码:

 - (void)remoteControlReceivedWithEvent:(UIEvent *)receivedEvent { if (receivedEvent.type == UIEventTypeRemoteControl) { switch (receivedEvent.subtype) { case UIEventSubtypeRemoteControlPreviousTrack: break; case UIEventSubtypeRemoteControlNextTrack: break; case UIEventSubtypeRemoteControlPlay: [[MyVideoController instance] play]; break; case UIEventSubtypeRemoteControlPause: [[MyVideoController instance] pause]; break; default: break; } } }