6

i am having an issue with playing back a video in my intro scene. i have added my video to the scene and it plays fine. i just want it to repeat again and again. is there any way to set this video to playback automatically after it ends?

this is how i add the video:

SKVideoNode *videoNode = [SKVideoNode videoNodeWithVideoFileNamed:@"game1.m4v"];
videoNode.position = CGPointMake(150, 180);
videoNode.size = CGSizeMake(150, 150);
[self addChild:videoNode];
[videoNode play];

any help is appreciated.

Adrian P
  • 6,479
  • 4
  • 38
  • 55
  • If you initialize with initWithAVPlayer you can use this code to loop your video: http://stackoverflow.com/questions/5361145/looping-a-video-with-avfoundation-avplayer – sangony Mar 02 '15 at 17:05
  • @sangony can it be done with sk video node? – Adrian P Mar 02 '15 at 17:13
  • Yes, if you use the above referenced init which uses an AVPlayer. You can then use the linked code to create a message which in turn loops. Alternately you could probably also use a block to time and re-run your video. – sangony Mar 02 '15 at 17:25
  • @sangony, thank you for the link. it did the job. can you please post it as an answer so i can mark it for you, and thank you again. – Adrian P Mar 02 '15 at 17:54

2 Answers2

7

Initialize your SKVideoNode with:

- (instancetype)initWithAVPlayer:(AVPlayer *)player

When setting up the AVPlayer use:

avPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone; 

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(playerItemDidReachEnd:)
                                             name:AVPlayerItemDidPlayToEndTimeNotification
                                           object:[avPlayer currentItem]];

this will prevent the player to pause at the end.

In the notification:

-(void)playerItemDidReachEnd:(NSNotification *)notification {
    AVPlayerItem *p = [notification object];
    [p seekToTime:kCMTimeZero];
}

this will rewind the movie.

(Credit to Bastian for his answer to this question)

Community
  • 1
  • 1
sangony
  • 11,636
  • 4
  • 39
  • 55
  • It's bizarre, if you don't set the actionAtItemEnd or manually play the AVPlayer prior to initializing the video node, you'll get 2 notifications rather one when playback has completed. I guess one for rewinding and one for the playback completion due to it pausing on default, but then again why would that change if you play the player manually. – TheCodingArt Dec 30 '15 at 16:06
  • I'm getting a memory leak with this exact same implementation. Is anyone else seeing a memory leak? It appears to be when looping a video with AVPlayer and SKVideoNode. – Solsma Dev Nov 16 '16 at 19:23
0

iOS 10 introduced sweet AVPlayerLooper. This class basically does what we did manually before, using notifications. Now you need less code to make an SKVideoNode repeat. In the context of the question, the solution will look like this:

// Hold strong ref to the looper somewhere
var videoLooper: AVPlayerLooper?
// ...


func addVideoNode() {
    guard let url = Bundle.main.url(forResource: "game1", withExtension: "m4v") else {

        print("Video is missing!")
        return
    }

    // Configure looper magic
    let item = AVPlayerItem(url: url)
    let player = AVQueuePlayer()
    videoLooper = AVPlayerLooper(player: player, templateItem: item)

    // Setup node
    let videoNode = SKVideoNode(avPlayer: player)
    videoNode.position = CGPoint(x: 150, y: 180)
    videoNode.size = CGSize(width: 150, height: 150)
    addChild(videoNode)
    videoNode.play()
}
kelin
  • 11,323
  • 6
  • 67
  • 104