30

最初にアプリケーションについて少し説明します...
- ビデオ プレーヤーを含む多くの重い UI 操作があります (主にスクロール)
- ビデオは動的であり、現在のページに基づいて変化します。
- そのため、ビデオは動的で変化し続ける必要があり、UI もレスポンシブである必要があります

最初は を使用してMPMoviePlayerControllerいましたが、特定の要件により、AVPlayer
にフォールバックする必要があり、 の独自のラッパーを作成しましたAVPlayer
videoPlayer のコンテンツを変更するには、AVPlayer-wrapper クラスのメソッドは次のようになります。

/**We need to change the whole playerItem each time we wish to change a video url */
-(void)initializePlayerWithUrl:(NSURL *)url
{
    AVPlayerItem *tempItem = [AVPlayerItem playerItemWithURL:url];

    [tempItem addObserver:self forKeyPath:@"status"
                  options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
                  context:nil];
    [tempItem addObserver:self forKeyPath:@"playbackBufferEmpty"
                  options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
                  context:nil];

    //Not sure if this should be stopped or paused under the ideal circumstances
    //These will be changed to custom enums later
    [self setPlaybackState:MPMoviePlaybackStateStopped];
    [self setLoadState:MPMovieLoadStateUnknown];
    [self.videoPlayer replaceCurrentItemWithPlayerItem:tempItem];

    //This is required only if we wish to pause the video immediately as we change the url
    //[self.videoPlayer pause];
}

もちろん、すべてが正常に機能していました...例外..

[self.videoPlayer replaceCurrentItemWithPlayerItem:tempItem];

ほんの一瞬UIをブロックしているようで、スクロール中にUIが本当に反応しなくなり、見苦しくなります。また、この操作はバックグラウンドで実行できません

これに対する修正または回避策はありますか?

4

2 に答える 2

23

私が見つけた解決策はAVAssetAVPlayer. これには便利なAVAssetメソッドがあります:loadValuesAsynchronouslyForKeys:

AVAsset *asset = [AVAsset assetWithURL:self.mediaURL];
[asset loadValuesAsynchronouslyForKeys:@[@"duration"] completionHandler:^{
    AVPlayerItem *newItem = [[AVPlayerItem alloc] initWithAsset:asset];
    [self.avPlayer replaceCurrentItemWithPlayerItem:newItem];
}];

私の場合、URL はネットワーク リソースであり、replaceCurrentItemWithPlayerItem:実際にはこの情報がダウンロードされるまで数秒間ブロックされます。

于 2015-09-22T23:25:58.457 に答える