iOS seamless video loop using AVPlayer

I’ve been lately hacking a new app, Fireplace Deluxe for the new Apple TV thingy, and had to deal with looping videos.

The usual way to implement this is getting a notification for AVPlayerItemDidPlayToEndTimeNotification and rewind the video. But this introduces some milliseconds of lag and give us some undesired hiccups.

There is not much info about this but a nice way to solve the issue is by using the AVQueuePlayer and inserting videos in the queue indefinitely as long as they are being played.

This will render a nice seamless video loop without annoying hiccups.

#import <UIKit/UIKit.h>
@import AVKit;

@interface VideoViewController : AVPlayerViewController

@end
#import "VideoViewController.h"

@implementation VideoViewController
{
    NSURL* videoURL;
    AVQueuePlayer* queue;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSString *resourceName = @"video.mov";
    NSString* movieFilePath = [[NSBundle mainBundle]
                               pathForResource:resourceName ofType:nil];
    videoURL = [NSURL fileURLWithPath:movieFilePath];
    
    AVPlayerItem *video = [[AVPlayerItem alloc] initWithURL:videoURL];
    queue = [[AVQueuePlayer alloc] initWithItems:@
];
    video = [[AVPlayerItem alloc] initWithURL:videoURL];
    [queue insertItem:video afterItem:nil];
    
    self.player = queue;
    
    self.showsPlaybackControls = FALSE;

    [self.player play];
    
    NSNotificationCenter *noteCenter = [NSNotificationCenter defaultCenter];
    [noteCenter addObserverForName:AVPlayerItemDidPlayToEndTimeNotification
                object:nil
                queue:nil
                usingBlock:^(NSNotification *note) {
                    AVPlayerItem *video = [[AVPlayerItem alloc] initWithURL:videoURL];
                    [queue insertItem:video afterItem:nil];
                }];
}

@end