How to Play Avplayeritems Immediately

How to play AVPlayerItems immediately

Swift 5

You just need to use the automaticallyWaitsToMinimizeStalling property.

player.automaticallyWaitsToMinimizeStalling = false
player.playImmediately(atRate: 1.0)

How to make AVPlayer appear instantly instead of after video ends?

The answer was we had an incorrectly composed video in the first place, as described here: AVAssetExportSession export fails non-deterministically with error: "Operation Stopped, NSLocalizedFailureReason=The video could not be composed.".

The other part of the question (audio playing long before images/video appears) was answered here: Long delay before seeing video when AVPlayer created in exportAsynchronouslyWithCompletionHandler

Hope these help someone avoid the suffering we endured! :)

Knowing when AVPlayer object is ready to play

You are playing a remote file. It may take some time for the AVPlayer to buffer enough data and be ready to play the file (see AV Foundation Programming Guide)

But you don't seem to wait for the player to be ready before tapping the play button. What I would to is disable this button and enable it only when the player is ready.

Using KVO, it's possible to be notified for changes of the player status:

playButton.enabled = NO;
player = [AVPlayer playerWithURL:fileURL];
[player addObserver:self forKeyPath:@"status" options:0 context:nil];

This method will be called when the status changes:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context {
if (object == player && [keyPath isEqualToString:@"status"]) {
if (player.status == AVPlayerStatusReadyToPlay) {
playButton.enabled = YES;
} else if (player.status == AVPlayerStatusFailed) {
// something went wrong. player.error should contain some information
}
}
}

How to know when AVPlayerItem is playing

First you need to register your AVPlayerItem as an observer:

[self.yourPlayerItem addObserver:self
forKeyPath:kStatus
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
context:AVPlayerStatus];

Then on your player Key Value Observer method you need to check for AVPlayerStatusReadyToPlay status, like so:

- (void)observeValueForKeyPath:(NSString *)path
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {

if (context == AVPlayerStatus) {

AVPlayerStatus status = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
switch (status) {
case AVPlayerStatusUnknown: {

}
break;

case AVPlayerStatusReadyToPlay: {
// audio will begin to play now.
}
break;
}
}

Replaying AVPlayerItem / AVPlayer without re-downloading

You can call the seekToTime method when your player received AVPlayerItemDidPlayToEndTimeNotification

func itemDidFinishPlaying() {
self.player.seek(to: CMTime.zero)
self.player.play()
}


Related Topics



Leave a reply



Submit