iAmd iAmd - 4 months ago 173
iOS Question

AVPlayer stops playing and dont resume again

In my application I have to play audio files stored on a web server. Im using

AVPlayer
for it. I have all the play/pause controls and all delegates and observers there which work perfectly fine. On playing small audio files everything works great.

When a long audio file is played it also starts playing fine but after some seconds the
AVPlayer
pauses the playing (most probably to buffer it). The issue is it don't resume on its own again. It keeps in a pause state and if I manually press the play button again it plays smoothly again.

I want to know why
AVPlayer
dont resume automatically and how can I manage to resume the audio again without user pressing the play button again? Thanks.

Answer

Yes it stops because the buffer is empty so it has to wait to load more video. After that you have to manually ask for start again. To solve the problem I has follow this steps:

1) Detection: To detect when the player has stopped i use the KVO with the rate property of the value:

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"rate"] )
    {

        if (self.player.rate == 0 && CMTimeGetSeconds(self.playerItem.duration) != CMTimeGetSeconds(self.playerItem.currentTime) && self.videoPlaying)
        {
            [self continuePlaying];
        }
      }
    }

This condition: CMTimeGetSeconds(self.playerItem.duration) != CMTimeGetSeconds(self.playerItem.currentTime) is to detect the difference between arriving to the end of the video and stop in the middle

2)Wait the video to load - If you continue playing directly you will not have enough buffer to continue playing without interruption. To know when to start you have to observe the value playbackLikelytoKeepUp from the playerItem (here I use a library to observe with blocks but I think it makes the point):

-(void)continuePlaying
 {

if (!self.playerItem.playbackLikelyToKeepUp)
{
    self.loadingView.hidden = NO;
    __weak typeof(self) wSelf = self;
    self.playbackLikelyToKeepUpKVOToken = [self.playerItem addObserverForKeyPath:@keypath(_playerItem.playbackLikelyToKeepUp) block:^(id obj, NSDictionary *change) {
        __strong typeof(self) sSelf = wSelf;
        if(sSelf)
        {
            if (sSelf.playerItem.playbackLikelyToKeepUp)
            {
                [sSelf.playerItem removeObserverForKeyPath:@keypath(_playerItem.playbackLikelyToKeepUp) token:self.playbackLikelyToKeepUpKVOToken];
                sSelf.playbackLikelyToKeepUpKVOToken = nil;
                [sSelf continuePlaying];
            }
                    }
    }];
}

And that's it! problem solved

Edit: By the way the library used is libextobjc

Comments