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

依然范特西╮ 提交于 2019-12-21 04:38:09

问题


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?

回答1:


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




回答2:


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.



回答3:


It turns out that this may have been related to the way I was testing. Using the Network Link conditioner didn't trigger the block, but when I actually blocked the host using Charles Proxy, everything worked as intended. I'm trying to go with my original code for now, and will add in some of Dan's ideas if it proves to be problematic still during real world testing



来源:https://stackoverflow.com/questions/23701057/how-does-avplayer-avplayeritem-inform-my-application-about-unreachable-network

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!