0

I'm loading an mp4 video into an AVPlayerLayer, and placing it in a superlayer whose speed is set to 0 (see why below). Video playback stutters badly. Once per second the player outputs a 3-4 frames.

The video roughly follows wall time, so its master clock is good, I think.

I profiled it, and the main thread is idle except for once per second. Also, once per second, some bytes are read from disk even though I preloaded the tracks (weird).

On a whim, I tried advancing the movie manually on a 10ms timer by calling seekToTime on the AVPlayer. I verified that the timer is called every 10ms, but the AVPlayerLayer still updated only once per second.

Is there any way to get AVPlayer to output frames in a more timely manner? Should I abandon AVPlayer in favor of Core Video and manually output frames?


The reason the backing layer's speed is set to 0 is that I've set up several other views in addition to the AVPlayerLayer, and applied path CoreAnimations to them. A UIPanGestureRecognizer drives the backing layer's time, resulting in user-driven animation.

Note that playback stutters even when not panning.

Kevin Packard
  • 374
  • 4
  • 13
  • I appreciate the response. Sorry if I was not clear, but No, my goal is not to synchronize animations to the video. The AVPlayerLayer is animated on a path animation along with other items, so it must be on the backing layer. That, or abandon AVPlayerLayer. – Kevin Packard Feb 25 '16 at 03:07
  • Further experiments show that AVPlayerLayer stutters when sharing the screen with a UIScrollView that's being scrolled - no modifications to layer.speed in this test. This is a 15 second m4v with a single track of 18 fps 640x480 video. Disappointing. – Kevin Packard Feb 25 '16 at 05:22
  • @KevinPackard When UIScrollView scrolls it can block animations that are running on the screen. It has something to do with run loop and run loop modes. See, for example, this SO question http://stackoverflow.com/questions/16557846/uiscrollview-scroll-event-blocks-uiview-animation I think your problem is related to that. – euvs Feb 25 '16 at 10:35
  • @euvs - thanks for the reply. My path animations are silky smooth in response to the user's drag, but I did try manually advancing the AVPlayer on a runloop as you describe. Like my previous experiment, the AVPlayer advances, but the screen still only updates once per second. – Kevin Packard Feb 25 '16 at 15:02
  • In a new experiment, I'm able to rapidly update the UIImageView.layer.content property with different CGImages. My new strategy is to replace the AVPlayerLayer with a UIImageView, and set the UIImageView.layer.content property with CGImages derived from a AVAssetImageGenerator. Will post if successful. – Kevin Packard Feb 25 '16 at 15:07
  • The above solution worked out well. Instead of an AVPlayerLayer, I use a standard CALayer. I create an AVAssetImageGenerator, and call generateCGImagesAsynchronouslyForTimes(...) which returns a series if CGImage's from the video track. For each CGImage I use dispatch_after(...) to schedule some time on the main thread at the appropriate frame time, where I set the CALayer's content property with the CGImage. Because this is a workaround, not an answer to the original post, I'm not going to mark solution as as the answer. – Kevin Packard Feb 29 '16 at 04:32

0 Answers0