2014-03-24 170 views
5

我正在使用Sprite Kit和SKVideoNode播放短视频。当视频节点添加到场景中时,在初始设置之前,播放器会短暂闪烁黑色。在播放开始前播放SKVideoNode中的视频会导致黑屏闪烁

我试过用AVPlayer代替视频直接使用AVPlayer,我也用KVO在视频说它准备播放时只加载SKVideoNode。

无论哪种方式,在我的视频开始播放之前,我会得到一个黑色闪光灯。

此外似乎没有办法将AVPlayerLayer添加到SKScene/SKView,但我不知道这是否有帮助。

任何关于下一步尝试的建议都会很棒。

下面是我使用

- (void)didMoveToView:(SKView *)view 
{ 
    if (!self.contentCreated) { 
     [self createSceneContents]; 
    } 
} 

- (void)createSceneContents 
{ 
    NSString *resourcePath = [[NSBundle mainBundle] pathForResource:@"IntroMovie" ofType:@"mov"]; 
    NSURL *introVideoURL = [NSURL fileURLWithPath:resourcePath]; 
    self.playerItem = [AVPlayerItem playerItemWithURL:introVideoURL]; 
    self.player = [[AVPlayer alloc] initWithPlayerItem:self.playerItem]; 

    [self.playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil]; 

    SKSpriteNode *playButton = [SKSpriteNode spriteNodeWithImageNamed:@"PlayButton"]; 
    [playButton setPosition:CGPointMake(CGRectGetMidX(self.view.frame), (CGRectGetMidY(self.view.frame)/5) * 3)]; 
    [self addChild:playButton]; 
} 

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 
    if ([keyPath isEqualToString:@"status"]) { 
     if ([[change objectForKey:NSKeyValueChangeNewKey] integerValue] == AVPlayerItemStatusReadyToPlay) { 
      NSLog(@"Change has the following %@", change); 
       [self.player prerollAtRate:0 completionHandler:^(BOOL done){ 
        SKVideoNode *introVideo = [SKVideoNode videoNodeWithAVPlayer:self.player]; 
        [introVideo setSize:CGSizeMake(self.size.width, self.size.height)]; 
        [introVideo setPosition:self.view.center]; 
        [self addChild:introVideo]; 
        [introVideo play]; 
        [self.playerItem removeObserver:self forKeyPath:@"status"]; 
       }]; 
     } 
    } else { 
     [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; 
    } 
} 

代码下面是替代代码块刚刚播放视频,并给出了视频之间的相同的黑色闪存加载和它玩。

NSString *resourcePath = [[NSBundle mainBundle] pathForResource:@"IntroMovie" ofType:@"m4v"]; 
NSURL *introVideoURL = [NSURL fileURLWithPath:resourcePath]; 
self.playerItem = [AVPlayerItem playerItemWithURL:introVideoURL]; 
self.player = [[AVPlayer alloc] initWithPlayerItem:self.playerItem]; 

SKVideoNode *introVideo = [SKVideoNode videoNodeWithAVPlayer:self.player]; 
[introVideo setSize:CGSizeMake(self.size.width, self.size.height)]; 
[introVideo setPosition:self.view.center]; 
[self addChild:introVideo]; 
[introVideo play]; 
+0

其中skvideonode已初始化?你可以发布skvideonode代码吗? – Ilario

+0

在我使用它的地方添加了代码。我尝试了预览代码,因为你会看到,并没有任何区别的东西。 –

+0

哪里调用[introVideo play]? – Ilario

回答

1

我也有类似的问题,解决它像这样:

我导出视频为PNG的第一帧。然后我在的前面添加了一个SKSpriteNode和那个PNG。当我开始播放视频时,我将SKSpriteNodehidden属性设置为YES


这里是我的代码与相关部件的简化的例子:

-(void)didMoveToView:(SKView *)view {  

    // add first frame on top of the SKVideoNode 
    firstFrame = [SKSpriteNode spriteNodeWithImageNamed:@"firstFrame"]; 
    firstFrame.zPosition = 1; 
    [self addChild:firstFrame]; 

    // here I add the SKVideoNode with AVPlayer 
    ...... 

    // Add KVO 
    [playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil]; 

} 


- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 
    if (object == player.currentItem && [keyPath isEqualToString:@"status"]) { 
     if (player.currentItem.status == AVPlayerItemStatusReadyToPlay) { 

      [introVideo play]; 
      firstFrame.hidden = YES;    
     } 
    } 
} 


这是到目前为止,我已经找到了最好的解决方案。我希望能帮到你!

+0

谢谢。我曾想过按照这些方式做一些事情,但有希望会有些简单的事情。感谢您确认这一点,至少在现在,这是一条路。 –

0

奇怪的问题......你可以尝试不使用AVPlayerItem?像这样:

NSString *resourcePath = [[NSBundle mainBundle] pathForResource:@"IntroMovie" 
                  ofType:@"m4v"]; 
    NSURL *introVideoURL = [NSURL fileURLWithPath:resourcePath]; 

    AVPlayer *player = [AVPlayer playerWithURL: introVideoURL]; 

    SKVideoNode *introVideo = [[SKVideoNode alloc] initWithAVPlayer: player]; 

    [introVideo setSize:CGSizeMake(self.size.width, self.size.height)]; 
    [introVideo setPosition:self.view.center]; 
    [self addChild:introVideo]; 
    [introVideo play]; 
+0

同样的结果。这似乎与使用AVPlayer或AVPlayerItem无关,并且在不使用AVPlayer或AVPlayerItem时仍然会发生,并且直接将SKVideoNode加载到视频中。 –

+0

我过去曾经遇到像MPMoviePlayer一样的问题,但是您可以将背景颜色或图像插入到已经处理好的背景颜色或图像中。由于AVPlayer和SKVideoNode不支持视图,因此无法在此处执行此操作。 –

1

具有相同的问题。 我的解决方法:

videoNode = SKVideoNode(AVPlayer: player) 
videoNode.hidden = true 

player.addBoundaryTimeObserverForTimes([1/30.0], queue: dispatch_get_main_queue()) { [unowned self]() -> Void in 
    self.videoNode.hidden = false 
}