Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does AVPlayer / AVPlayerItem inform my application about unreachable network failure?

I’m using AVPlayer to implement a custom video player in an iOS application. To play video from the network I allocate a player:

[[AVPlayer alloc] initWithURL:_URL];

Create an asset:

AVURLAsset *asset = [AVURLAsset URLAssetWithURL:self.URL
options:@{AVURLAssetPreferPreciseDurationAndTimingKey : @(YES)}];

load the playable key asynchronously:

NSArray *keys = @[@"playable"];
[asset loadValuesAsynchronouslyForKeys:keys completionHandler:^{
    dispatch_async(dispatch_get_main_queue(), ^{
        for (NSString *key in keys) {
            NSError *error;
            AVKeyValueStatus status = [asset statusOfValueForKey:key error:&error];

            if (status == AVKeyValueStatusFailed) {
                NSLog(@"Failed to load asset key %@ error %@", key, [error localizedDescription]);
                [self fail];
                return;
            }
        }

        if (asset.isPlayable) {
            [self.player replaceCurrentItemWithPlayerItem:self.playerItem];
        }
        else {
            [self fail];
        }
    });
}];

The problem is that when the device has no internet connection or high packet loss, the completionHandler is never called (even after waiting for minutes) and so I have no idea when to show a message to the user that loading the video failed.

My questions are:

  1. Am I missing something / is there a better way to handle this?
  2. Should I roll my own timeout logic or should I just never loadValuesAsynchronouslyForKeys: when Reachability believes that the network isn't reachable.
  3. What are the best practices regarding AVPlayer and network failures?
like image 447
Matthew Bischoff Avatar asked May 16 '14 17:05

Matthew Bischoff


People also ask

What is Avplayeritem?

An object that models the timing and presentation state of an asset during playback.

How do I disable AVPlayer?

AVPlayer does not have a method named stop . You can pause or set rate to 0.0. Show activity on this post. I usually seekToTime 0.0, then pause.

What is AVPlayer in IOS?

Overview. A player is a controller object that manages the playback and timing of a media asset. Use an instance of AVPlayer to play local and remote file-based media, such as QuickTime movies and MP3 audio files, as well as audiovisual media served using HTTP Live Streaming.


2 Answers

You should be observing (KVO) features of the AVPlayerItem that reveal how the buffer is doing, such as playbackBufferEmpty etc.

like image 150
matt Avatar answered Sep 20 '22 16:09

matt


I've integrated AVAsset before, but haven't run into this specific issue. Nonetheless, here's what I would do:

  1. Set a timer or delayed block dispatch for the length of the timeout you'd like to enforce.
  2. Check the value of the "playable" key with statusOfValueForKey:error:.
  3. If the status is not AVKeyValueStatusLoaded or error is not nil, call [asset cancelLoading] and display an error message to the user or whatever cleanup you might need to do.
like image 31
dwlz Avatar answered Sep 19 '22 16:09

dwlz