Skip to content
tezvyn:

Generating Video Thumbnails with AVAssetImageGenerator

MediumHow cards are made

Summary

AVFoundation usage plus async UI hygiene.

Key points

load AVAsset, configure AVAssetImageGenerator, request the time off the main thread, hop back to update UI.

Watch out for

doing the decode synchronously on the main thread.

WHAT THIS TESTS This checks AVFoundation familiarity and, just as importantly, whether you keep heavy decoding work off the main thread so the UI stays responsive.

A GOOD ANSWER COVERS Create an AVAsset, or AVURLAsset, from the video URL. Instantiate an AVAssetImageGenerator with that asset. Set appliesPreferredTrackTransform to true so the thumbnail respects the video's recorded orientation rather than appearing rotated. Build a CMTime for the target moment, then request the frame asynchronously, on modern OS versions using the async image(at:) method or generateCGImagesAsynchronously, which delivers results on a background queue. Wrap the resulting CGImage in a UIImage and dispatch UI updates to the main queue.

COMMON WRONG ANSWERS Calling the synchronous copyCGImage on the main thread, which decodes a frame and stalls scrolling. Forgetting appliesPreferredTrackTransform, yielding sideways thumbnails. Decoding a full-resolution frame for a tiny image view, wasting memory and CPU.

LIKELY FOLLOW-UPS How do requestedTimeToleranceBefore and after trade accuracy for speed by snapping to keyframes? How do you set maximumSize to downscale during decode? How would you cancel pending requests when a cell is reused in a collection view? How do you cache generated thumbnails to avoid redundant work?

ONE CONCRETE EXAMPLE For a video feed, each cell asks a thumbnail service for a frame. The service creates an AVAssetImageGenerator, sets maximumSize to roughly the cell's pixel size and tolerances of a fraction of a second so it lands on a nearby keyframe quickly, then requests the image asynchronously. When the cell is reused before the result arrives, the service cancels the outstanding generation. On completion it hops to the main queue, sets the cell's image, and stores it in an in-memory cache keyed by URL and time so the next scroll back is instant.

Interview question

Scrolling a video list stutters whenever thumbnails appear. The generator is configured correctly but called via copyCGImage. What is the root cause?

  • a.appliesPreferredTrackTransform is rotating frames, which is expensive
  • b.maximumSize is too small, forcing repeated re-decodes
  • c.CMTime tolerances are zero, so it always lands on an exact keyframe
  • d.The synchronous copyCGImage decodes frames on the main thread, blocking itCorrect
Why?

Synchronous copyCGImage decodes on the calling thread; on the main thread it blocks scrolling. Use the async API on a background queue and update UI on the main queue.

Just read this? Test yourself on what you have been reading.

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on ios — each one lists the topics its interview covers.

See open roles