2
votes

I am using an AVPlayer with an SKVideoNode attached to a scene. That is the only node for that SKScene. I am playing out that video intermingled with a set of other scenes loaded with a variety of SKSpriteNode nodes.

I want to pre-roll the AVPlayer so that the video has begun playing just before (or as) it becomes visible during an SKScene transition. And yet I can't seem to do so without getting an intervening black flash.

Just as the scene containing the video disappears, I reset it (I stuff the AVPlayer object into the SKVideoNode's user dictionary). This appears to work:

SKVideoNode *v = ...;
AVPlayer *player = [[v userData] objectForKey:@"AVPlayer"];
if ([player isKindOfClass:[AVPlayer class]]) {
    [player seekToTime:kCMTimeZero];

When the scene is about to appear that contains the video, I do this:

SKTransition *trans = [SKTransition flipHorizontalWithDuration:1.0];
[self.skView presentScene:theScene transition:trans];
[self performSelector:@selector(startVideoInScene:)
           withObject:theScene
           afterDelay:0.2];

then...

- (BOOL)startVideoInScene:(SKScene *)theScene
{
    for (SKNode *n in [theScene children])
        if ([n isKindOfClass:[SKVideoNode class]]) {
            SKVideoNode *v = (SKVideoNode *)n;
            AVPlayer *player = [[v userData] objectForKey:@"AVPlayer"];
            if ([player isKindOfClass:[AVPlayer class]]) {
                [v play];
                return YES;
            }
        }
    return NO;
}

This does not work without starting with short duration of black before the video.

Anyone had success with this?

I have a haunting suspicion that all content on a SKScene is suspended during its transition, and there's no way around it. Well, apart from transitioning out all nodes of the current scene, keeping that current scene, and transitioning a new SKVideoNode onto it.

1

1 Answers

1
votes

The answer from this question suggests making a still image from the first frame of the video, and making that an SKSpriteNode that is to be used as the image that first appears as the scene transitions. Then, when the transition is over, hide that poster image (the SKSpriteNode) and play your video.

Now, what i'm doing in a project i have going right now, is actually using the black to my advantage. The context of the game allows me to do this, but i basically let my scene transition to black, the start of the video (in my case an mp4) has its black start, then fades in from black as the video plays.