Avplayer does not pause when pause button is pressed if screen is locked

If the app is playing, the sound and phone screen are locked, then the control screen is shown below. I cannot take any action in avplayer

enter image description here

In my appdelegate, I have implemented:

- (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];
}

      

the MyVideoController class consists of:

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

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

      

Even if these methods are run (checkpoints are added to check), no action is taken in avplayer. Regardless, avplayer does not stop.

Is there a way to pause avplayer?

EDIT 1: Adding complete code

In my 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];
}

      

I GOT THE EVENTS BUT THE AUDIO DOESN'T PAUSE TO CALL THE PAUSE METHOD ON THE AVPLAYER.

EDIT 2: Declaring an instance in the PlayerController class

+ (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 initialization

    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];

      

+3


source to share


3 answers


I found a solution to the problem. When I was getting a null value for avPlayer, I used my PageViewController class to get a PlayerController instance. Then I used an instance of this playerController to play and pause my avplayer because this instance contains a link to the 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];
}

      

+2


source


You need to register for remote notification to update the player status when the app is locked. To do this, follow these steps:

Add this to your AppDelegate, ideally at applicationDidEnterBackground:

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

      

And this is in applicationDidBecomeActive:

[[UIApplication sharedApplication] endReceivingRemoteControlEvents];

      



Get deleted notifications by adding this to AppDelagate. This will listen to all activities when the phone is locked.

- (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];


    }
 }

      

And in this you will get the desired event and update state

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

      

+1


source


In iOS 7.1 and later, use the generic MPRemoteCommandCenter object to log remote control events. You don't need to call this method when using a shared center center object. This method triggers the delivery of remote control events using the responder chain. Remote control events occur as commands issued by headsets and external accessories designed to control the media presented by the application. To stop receiving remote control events, you must call endReceivingRemoteControlEvents ().

Add the following dofinishlunching code for init audio session and receive remote event:

        // 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];
        }

      

to use commadn use this code:

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

      

0


source







All Articles