Looping AVPlayer seamlessly

avfoundation, ios, opengl-es, tvos, video

Solution

I had the same problem when streaming a video. After playing for the first time, there was a black screen when loading the video for second time. I got rid of the black screen by seeking video to 5ms ahead. It made nearly a seamless video loop. (Swift 2.1)

// Create player here..
let player = AVPlayer(URL: videoURL)

// Add notification block
NSNotificationCenter.defaultCenter().addObserverForName(AVPlayerItemDidPlayToEndTimeNotification, object: player.currentItem, queue: nil)
{ notification in
   let t1 = CMTimeMake(5, 100);
   player.seekToTime(t1)
   player.play()
}

Problem

There has been some discussion before about how to loop an `AVPlayer`'s video item, but no 'solution' is seamless enough to provide lag-less looping of a video. I am developing a tvOS app that has a high-quality 10 second clip of 'scenery' in the background of one of its views, and simply restarting its AVPlayer the 'standard' way (subscribing to `NSNotification` to catch it) is too jumpy not to notice and detract from user experience. It seems as though the only way to achieve a truly seamless loop is to manually manage frames, at a lower-level (in OpenGL)... Despite best efforts to read up on this, and as a novice in manipulating video pipelines, I have not come close enough to a comprehensible solution. I am aware that external libraries exist to be able to perform this behaviour more easily; most notably GPUImage. However, the app I am developing is for tvOS and therefore has difficulty using quite a lot of the 3rd party iOS libraries in existence, GPUImage included. Another library I have come across is AVAnimator, which provides great functionality for light-weight animation videos, but not for dense, high-quality video clips of source footage encoded in .H264. The closest I have come so far is Apple's own AVCustomEdit source code, however this primarily deals with static production of a 'transition' that, while seamless, is too complex for me to be able to discern how to make it perform simple looping functionality. If anybody can chip in with experience of manipulating `AVPlayer` at a lower level, i.e. with image processing/buffers (or iOS development that doesn't rest on external libraries), I would be incredibly interested to know how I could make a start.

Original source

Related problems