2014-03-24 174 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 
}