Extracting Stills From Footage You Already Rendered
A rendered clip is several hundred frames deep. extract_video_frames pulls one you already paid for; analyze_video helps you find which one first.
Every rendered clip is, among other things, a stack of finished still images nobody asked for separately — hundreds of individual frames sitting inside a file most people only ever treat as one continuous thing to watch. A thumbnail, a carousel slide, an ad static, a clean anchor to chain the next generation from: all four are usually treated as separate generation requests, when at least one of them is very often already sitting inside footage that's already been rendered. The gap isn't a missing capability. It's that pulling a frame back out gets treated as an afterthought instead of a first move.
Two tools, two different jobs
extract_video_frames does exactly what it says and nothing more: point it at a video and it returns one or more still frames as plain image URLs — useful for grabbing a thumbnail, or for chaining a frame straight into generate_image_from_image or generate_video_from_image as a reference or first frame. What it doesn't do is tell you anything about what's actually in each frame it returns. That's the right tool once you already know which moment you want — a specific timestamp you remember, or a range you're confident holds something usable.
analyze_video solves a different problem: not knowing which moment yet. It's built for deeper, on-demand video understanding — sample frames, uploaded as reusable JPEG URLs, alongside a description of the overall style and format, a beat-by-beat account of what happens at each timestamp, any on-screen text, and optionally a full speech transcript. Its own description is direct about when it earns its keep over guessing: "Prefer this over guessing from a video URL alone." Where extract_video_frames hands you images and leaves the judgment call entirely to you, analyze_video hands you images paired with a description of what's happening in each one — which means the choice of which frame actually serves a thumbnail or a carousel slide can be reasoned about, instead of made by scrubbing back and forth and eyeballing it.
Four destinations, four different criteria for "the right frame"
The same rendered clip serves these differently, and treating them as one search — "find the good frame" — misses that each destination is actually asking for something distinct.
A thumbnail wants the single highest-energy beat in the whole clip: the moment a scroll would actually stop on, evaluated in isolation from everything around it. A carousel wants the opposite property — several genuinely distinct beats spread across the runtime, not three near-duplicate frames a second apart that all show functionally the same moment. Sequential frames from one motion peak fill a carousel with redundancy dressed up as variety. An ad static wants something neither of the other two necessarily do: real negative space, a frame with a clean, uncluttered region where a headline or CTA can actually sit without fighting the subject for attention — which sometimes means passing over the single most dramatic frame in favor of a calmer one a beat earlier or later, because the most dramatic frame is usually also the most visually busy one. And a continuity anchor — a frame meant to seed the next generation — wants something the other three don't care about at all: it has to be specifically the last clean frame, not just any good one, because it's about to become the starting point another clip has to convincingly continue from.
The continuity case is the one worth understanding properly
This is the destination where extraction isn't just convenient, it's structurally better than the alternative. First-last frame generation works from two supplied stills, but plain image-to-video only ever gets one — it "knows where it begins and improvises the rest," which is exactly why what you hand it as that starting image matters as much as it does. A fresh text-to-image generation meant to match the previous clip's ending has to reconstruct lighting, character appearance, and setting from a written description and hope it lands close enough. A frame extracted directly from the actual previous clip doesn't have to reconstruct anything — it is the previous clip's own last moment, pixel for pixel, which removes the entire category of drift a fresh generation risks introducing between scenes. Chained generation built this way holds a scene's continuity for a reason that has nothing to do with prompt-writing skill: the anchor frame isn't an approximation of where the last shot ended, it's that exact frame.
Working the two tools together
The two aren't really competing options so much as sequential ones on any clip longer than a few seconds. Run analyze_video first when you're not sure yet which moment across a longer render is worth pulling — its beat-by-beat descriptions and sampled frames give you enough to identify, say, "the frame at the 4-second mark where the product is fully in frame with clean space to its right" without scrubbing the whole timeline by eye first. Once you know which specific timestamp that is, extract_video_frames is the tool for actually pulling it — and pulling several nearby variants at once with frame_count and a tight start_time/end_time range, so you can compare two or three candidates around the moment you identified rather than betting on the first one you grabbed. An fps value narrows that further, sampling more densely inside the window when the motion is fast enough that even half a second can be the difference between a clean frame and a blurred one, and output_format decides what you're actually comparing the candidates as once they're back.
None of this requires touching the source render again. Every candidate comes from the exact file that already exists — no re-generation, no new prompt, no risk of a second attempt drifting from the first in lighting or framing the way a fresh generation always can.
A Versely walkthrough: one render, three assets
Take a single ten-second product clip and treat it as a source for more than the video itself. First, find the candidates: "Analyze this video and tell me the best moments for a thumbnail, plus any frame with open space for text" runs analyze_video, returning sample frames alongside descriptions of what's happening at each timestamp — enough to pick a high-energy moment for a thumbnail and a calmer, clearer one for an ad static without guessing. Next, pull them at full quality: "Extract stills at the 2-second and 7-second marks from this video" calls extract_video_frames with start_time and end_time narrowed to each moment, returning clean image URLs with none of the compression a screen-capture would introduce. From there, turning a video into still photos and generating a video thumbnail are the two framings of the same underlying pull, and if the next step is chaining rather than publishing, extracting frames from a video to grab the clean final frame and feeding its URL straight into the next generate_video_from_image call carries scene continuity forward with nothing reconstructed from a text description in between.
Takeaway
A finished render isn't just a video — it's a still-image library that happens to be temporarily disguised as motion, and every frame in it was already paid for the moment the clip finished generating. extract_video_frames is the precise pull once you know the moment; analyze_video is how you find the moment when you don't, handing back frames paired with a description instead of a blind scrub through the timeline. Between the two, a thumbnail, a set of carousel slides, an ad static, and a continuity anchor for the next scene can all come from footage that's already sitting there, rather than four separate generations queued up out of habit.