AVPlayer不显示video

我想在游戏开始时播放电影。 我正在使用AVPlayer来做到这一点。 我的问题是,当我注册一个KVO来检查我的AVPlayer的状态时,我的游戏照常进行,没有等待video加载和完成。 因此,我只能听到我的.mov文件中的audio,并且看不到任何video(因为我的游戏已经开始)。 我希望video加载和完成之前进行游戏。 代码如下:

@interface RMVideoView : NSView { NSURL* _videoURL; AVPlayer* _player; AVPlayerLayer* _playerLayer; } @property (nonatomic, readonly, strong) AVPlayer* player; @property (nonatomic, readonly, strong) AVPlayerLayer* playerLayer; @property (nonatomic, retain) NSURL* videoURL; - (void) play; @end static void *RMVideoViewPlayerLayerReadyForDisplay = &RMVideoViewPlayerLayerReadyForDisplay; static void *RMVideoViewPlayerItemStatusContext = &RMVideoViewPlayerItemStatusContext; @interface RMVideoView() - (void)onError:(NSError*)error; - (void)onReadyToPlay; - (void)setUpPlaybackOfAsset:(AVAsset *)asset withKeys:(NSArray *)keys; @end @implementation RMVideoView @synthesize player = _player; @synthesize playerLayer = _playerLayer; @synthesize videoURL = _videoURL; - (id)initWithFrame:(NSRect)frame { self = [super initWithFrame:frame]; if (self) { self.wantsLayer = YES; _player = [[AVPlayer alloc] init]; [self addObserver:self forKeyPath:@"player.currentItem.status" options:NSKeyValueObservingOptionNew context:RMVideoViewPlayerItemStatusContext]; } return self; } - (void) setVideoURL:(NSURL *)videoURL { _videoURL = videoURL; [self.player pause]; [self.playerLayer removeFromSuperlayer]; AVURLAsset *asset = [AVAsset assetWithURL:self.videoURL]; [asset retain]; NSArray *assetKeysToLoadAndTest = [NSArray arrayWithObjects:@"playable", @"hasProtectedContent", @"tracks", @"duration", nil]; [asset loadValuesAsynchronouslyForKeys:assetKeysToLoadAndTest completionHandler:^{ dispatch_async(dispatch_get_main_queue(),^{ [self setUpPlaybackOfAsset:asset withKeys:assetKeysToLoadAndTest]; }); }]; } #pragma mark - KVO - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (context == RMVideoViewPlayerItemStatusContext) { AVPlayerStatus status = [[change objectForKey:NSKeyValueChangeNewKey] integerValue]; switch (status) { case AVPlayerItemStatusUnknown: break; case AVPlayerItemStatusReadyToPlay: [self onReadyToPlay]; break; case AVPlayerItemStatusFailed: [self onError:nil]; break; } } else if (context == RMVideoViewPlayerLayerReadyForDisplay) { if ([[change objectForKey:NSKeyValueChangeNewKey] boolValue]) { self.playerLayer.hidden = NO; } } else { [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } } #pragma mark - Private - (void)onError:(NSError*)error { // Notify delegate } - (void)onReadyToPlay { // Notify delegate [self.player play]; } - (void)setUpPlaybackOfAsset:(AVAsset *)asset withKeys:(NSArray *)keys { for (NSString *key in keys) { NSError *error = nil; if ([asset statusOfValueForKey:key error:&error] == AVKeyValueStatusFailed) { [self onError:error]; return; } } if (!asset.isPlayable || asset.hasProtectedContent) { [self onError:nil]; return; } if ([[asset tracksWithMediaType:AVMediaTypeVideo] count] != 0) { // Asset has video tracks _playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player]; self.playerLayer.frame = self.layer.bounds; self.playerLayer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable; self.playerLayer.hidden = NO; [self.layer addSublayer:self.playerLayer]; [self addObserver:self forKeyPath:@"playerLayer.readyForDisplay" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:RMVideoViewPlayerLayerReadyForDisplay]; } // Create a new AVPlayerItem and make it our player's current item. AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:asset]; [self.player replaceCurrentItemWithPlayerItem:playerItem]; } #pragma mark - Public - (void) play { [self.player play]; } @end 

我从我的入口函数的 – (void)drawView方法这样调用上面的代码:

 -(void)drawView { if(playVideo) { RMVideoView *rmVid = [[RMVideoView alloc]init]; NSURL* MovieURL; NSBundle *bundle = [NSBundle mainBundle]; if(bundle != nil) { NSString *moviePath = [bundle pathForResource:@"MyVideoResource" ofType:@"mov"]; if (moviePath) { MovieURL = [NSURL fileURLWithPath:moviePath]; [MovieURL retain]; [rmVid setVideoURL:MovieURL]; } } playVideo = kFalse; } } 

当设置KVO并且游戏向前运行时,对[rmVid setVideoURL:MovieURL]的调用返回。 请帮忙!

当video播放达到如下所示的结尾时,您可以收听通知:

  AVPlayerItem *avPlayerItem =[[AVPlayerItem alloc]initWithAsset:avAsset]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemDidReachedEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:avPlayerItem];