2016-06-01 8 views
0

が実行されます。AVAssetの「isPlayable」/「再生可能」チェック・ブロックや遅延UIアップデート

self.loadingView.frame = _frameWhereItShouldBeLocated; 
[self.loadSpinner startAnimating]; // self.loadSpinner is an UIActivityIndicatorView 
self.loadingView.hidden = FALSE; 

AVPlayer *player = [AVPlayer playerWithURL:fileUrl]; // fileUrl is where is the video file is hosted, which is not a local path 

if ([player.currentItem.asset isPlayable]) 
{ 

    if (!self.playerController) { 
     self.playerController = [[AVPlayerViewController alloc] init]; 
     self.playerController.transitioningDelegate = self; 
     self.playerController.modalPresentationStyle = UIModalPresentationCustom; 
    } 

    self.playerController.player = player; 
    self.playerController.showsPlaybackControls = TRUE; 

    [self.navigationController presentViewController:self.playerController animated:YES completion:nil]; 
    [self.playerController.player play]; 

} 

ユーザーのタップ直後に読み込みビューが表示され、しばらくしてからプレーヤーコントローラーが表示され、ビデオが再生されると思います。ただし、読み込みビューが表示されるまでにはかなりの遅延があります。

これは私が期待したものである:

User tap -> loading view shown -> (some time for loading the video, etc) -> play video 

代わりに、これは私が持っているものである:すなわち

User tap -> (significant time delay) -> loading view shown -> play video 

いくつかのデバッグ後、私は、遅延が[player.currentItem.asset isPlayable]呼び出しによって引き起こされることがわかりました読み込みビューは、呼び出しが返された後にのみ表示されます。私はdispatch_asyncコールでローディングビューの表示の下にセグメントを置こうとしましたが、それは変わりません。

これを処理して期待通りに動作させるにはどうしますか?

ありがとうございます!

+0

答えはAVAsynchronousKeyValueLoadingの導入である。https://developer.apple.com/library/mac/documentation/AVFoundation/Reference/AVAsynchronousKeyValueLoading_Protocol/index.html –

答えて

0

if ([player.currentItem.asset isPlayable])

チェックこの

if ((player.rate != 0) && (player.error == nil)) { 
    // player is playing 
} 

それとも あなたが観察された速度の新しい値がゼロであるかどうかを確認後のような

[player addObserver:self 
       forKeyPath:@"rate" 
       options:NSKeyValueObservingOptionNew 
       context:NULL]; 

の下rateプロパティの通知を追加することができますのInsted、これは、何らかの理由で再生が停止したことを意味します。つまり、空のバッファが原因で終了または停止しています。料金については

- (void)observeValueForKeyPath:(NSString *)keyPath 
         ofObject:(id)object 
         change:(NSDictionary<NSString *,id> *)change 
         context:(void *)context { 
    if ([keyPath isEqualToString:@"rate"]) { 
     float rate = [change[NSKeyValueChangeNewKey] floatValue]; 
     if (rate == 0.0) { 
      // Playback stopped 
     } else if (rate == 1.0) { 
      // Normal playback 
     } else if (rate == -1.0) { 
      // Reverse playback 
     } 
    } 
} 

== 0.0の場合、正確に再生を停止させたかを知るためには、次のチェックを行うことができます。上記の条件に基づいて

if (self.player.error != nil) { 
    // Playback failed 
} 
if (CMTimeGetSeconds(self.player.currentTime) >= 
    CMTimeGetSeconds(self.player.currentItem.duration)) { 
    // Playback reached end 
} else if (!self.player.currentItem.playbackLikelyToKeepUp) { 
    // Not ready to play, wait until enough data is loaded 
} 

をお使いのインジケータ表示を非表示にします。 メインスレッドにインジケータビューをロードします。

dispatch_async(dispatch_get_main_queue(), ^{ 
//load spinner 
}); 
関連する問題