First a little context about the application...
- There\'s a lot of heavy UI operation\'s involving video players (mostly scrolling)
- The videos are dynamic and c
We had the same problem when building Ultravisual. I can't exactly remember how we solved it, but IIRC it involved doing as much of the item setup as possible on a background thread, and waiting until the new item reports that it is 'ready to play' before calling replaceCurrentItemWithPlayerItem
.
Sadly this involves a voodoo dance with somewhat inconsistent asynchronous KVO, which is no fun.
The solution I found was to ensure that the underlying AVAsset
is ready to return basic info, such as its duration, before feeding it to the AVPlayer
. AVAsset
has a method loadValuesAsynchronouslyForKeys:
which is handy for this:
AVAsset *asset = [AVAsset assetWithURL:self.mediaURL];
[asset loadValuesAsynchronouslyForKeys:@[@"duration"] completionHandler:^{
AVPlayerItem *newItem = [[AVPlayerItem alloc] initWithAsset:asset];
[self.avPlayer replaceCurrentItemWithPlayerItem:newItem];
}];
In my case the URL is a network resource, and replaceCurrentItemWithPlayerItem:
will actually block for several seconds waiting for this information to download otherwise.