Skip to main content

AI Video Camera Controls Are Now Numbers: What 12 Keyframes Change for Product Ads

A camera move used to be an adjective inside a prompt. On fal's H3 Max camera endpoint it is a typed array of up to 12 keyframes, each carrying an angle, a height and a distance. Here is what a replayable camera path buys a product ad, and where a written move still wins.

Mauricio Valdivia

Mauricio Valdivia

·11 min

A motorized turntable rotating a skincare bottle in front of a camera on a small studio set

The camera move stopped being an adjective

The fifth re-roll is where people give up. There is a skincare bottle on a marble counter, the shot needs the camera to travel once around it and land back on the front label, and the instruction has now been written four different ways. Two renders drifted sideways. One pushed in instead of orbiting. One did something close enough to argue about. The bottle was never the problem. The sentence was.

On fal's H3 Max camera-controls endpoint that sentence is no longer where the move lives. The move is an input of its own, called camera_trajectory: an ordered array of between 2 and 12 camera poses, each carrying an angle around the subject, a vertical angle, a distance, and the moment in the clip it belongs to. You stop describing the orbit. You write it down.

That is a smaller story than "AI video gets camera control" and a more useful one. Keyframed camera control is not new, and the change here is not a capability so much as a shape. A move specified in prose is a request. A move specified as four numbers per pose is a coordinate, and coordinates can be saved, diffed and replayed across a catalogue. Two disclosures before the mechanics: this endpoint is not running on Novoads, so treat what follows as a market report rather than a release note, and the model is not quite the MiniMax release its name implies.

What the camera endpoint actually accepts

A trajectory is an array, not a sentence

The endpoint describes itself in one line on its model page: it "turns a single image into a video with precise, keyframe-based control over the camera's orbit, elevation, and distance in 3D space". Marketing copy usually evaporates when you open the schema. This one does not.

The published OpenAPI document lists image_url as a required input, documented as the image to use as the first frame, which makes this an image-to-video endpoint in the strict sense: one still frame in, one moving clip out. Alongside it sits camera_trajectory, an array with minItems of 2 and maxItems of 12. Its description carries the behaviour that makes it usable rather than decorative:

  • The first pose is held before its time.
  • The final pose is held for the remainder of the video.
  • Signed full turns are preserved, with at most 32 turns of total azimuth travel.

That third bullet is the one worth reading twice. Preserving signed full turns means 360 and 0 are different instructions, not the same position reached by different arithmetic. A path that ends at 360 goes all the way round. A path that ends at 0 stays put. In a prompt those two are the same English word.

The four numbers in every keyframe

Each entry in the array is an H3MaxCameraKeyframe, and all four of its fields are required. There is no partial pose.

FieldWhat it setsRange
timePosition in the clip0 at start, 1 at end
azimuthHorizontal angle around subjectDegrees, signed
elevationVertical angle around subject-90 to 90
distanceCamera distance from subjectNormalized scene units

Two of those deserve a note. time is normalized, running from 0 at the start to 1 at the end, so a path is defined as a proportion of the clip rather than in seconds. Change the duration and the move stretches to fit instead of breaking. distance is in normalized scene units rather than millimetres, which means it is a relative framing control, not a lens. You are saying "closer than the opening frame", not "85mm at 1.2 metres".

Clip length on this endpoint runs from 5 to 15 seconds, and resolution is one of 480P, 768P or 1080P.

Who built the rig, and why the name misleads

The endpoint sits under a minimax/ namespace, which invites a wrong conclusion. fal's own hub page for the model describes the stack this way: "H3 Max is post-trained by fal on top of the open-weight base MiniMax H3 model". That sentence is worth reading slowly, because three parties are doing three different things in it:

  • The base model is MiniMax's. H3 is their release. How it is licensed is their statement to make, and the wording above is fal's description of the model it builds on, not MiniMax's own terms.
  • The post-train is fal's. H3 Max is not a MiniMax product with a longer name.
  • The camera layer is fal's too, one step further out. The input schema describes itself as a "MiniMax H3 Multi-angle input with a fixed internal camera LoRA".

A LoRA is an adapter bolted onto a base model, so the keyframe rig is something fal carries on top of a post-train, not a feature MiniMax shipped.

This matters for a practical reason rather than a pedantic one. If you go looking for azimuth and elevation parameters on the base model, in the MiniMax H3 specs we covered at launch or in the broader MiniMax and Hailuo picture, you will not find them. The control surface belongs to the host, and hosts change their surfaces more often than labs change their weights.

A UGC creator filming a product review at home
Novoads · UGC video ads with AI, ready in minutes.
Try now

Why a typed control surface behaves differently from a phrase

A sentence is a request, a coordinate is an instruction

We have written before about how a camera move gets specified when the only control is the prompt: you pick a direction word, you keep one move per shot, and the model interprets. Interpretation is the whole job there. The same sentence, run twice, produces two readings of the same intent, and neither is wrong in a way you can point at.

A coordinate removes the interpretation step from one specific question. "Where is the camera at 30% through the clip" has exactly one answer when the answer is azimuth: 90, elevation: 10, distance: 0.7. It has a distribution of answers when the answer is "swinging round to the side by now".

That distinction is narrower than it sounds. It removes interpretation from the path, not from the picture. Everything else in the frame, lighting, texture, how the product's label holds up under motion, stays exactly as negotiable as it was.

The replay is the product

Here is the part that actually changes an ad workflow. A prompt is a description you rewrite. A trajectory is a file you keep.

Once an orbit has been tuned on one product shot, that array is a small piece of JSON. Posting it again with a different image_url is not "trying to get the same move again". It is the same move, by construction, because it is the same numbers. Three things follow from that:

  • The move stops being a variable under test and becomes a constant.
  • The question shifts from "did the camera behave" to "does this product survive this move".
  • A shot that worked six weeks ago can be reproduced exactly, not approximately.

For a catalogue this compounds. Thirty SKUs shot on the same sweep, one trajectory, thirty clips that cut together because the camera did the same thing in each. That kind of consistency is normally something you buy with a locked-down actor and reference discipline. Here it falls out of the input format.

What the numbers still do not promise

The model page uses the word "precise". That is the vendor's word for its own product, and it should not be repeated as a tested fact. Three reasons to keep it at arm's length:

  • A language layer is still in the path. The endpoint returns an expanded_prompt, documented as the prompt after expansion as sent to the model. The trajectory informs the generation. It does not bypass it.
  • The prompt field is still doing work. Its default is a paragraph of instructions about keeping the scene frozen while only the camera moves. A rig that needed no persuasion would not ship with that default.
  • Nobody outside has published a number. We could not find an independent measurement of trajectory adherence on this endpoint.

When we last looked at how reliably a written camera move actually lands, the picture was of adherence that is real and partial. Absent an equivalent figure here, the safe assumption is that typed keyframes tighten the distribution rather than collapse it.

Three ways a camera move gets specified today

Camera control is not one feature with one implementation. Three different answers are shipping right now, and they fail in different places.

Written as a phrase

You put the move in the prompt. Cheap, instant, expressive, and it can ask for anything language can name, including moves no coordinate system models. It is how camera direction works whenever a model exposes no camera parameter at all, which is the situation our Seedance prompt guidance is written for. The cost is variance: the same words produce a family of moves, not one move.

Set as numbers on a path

You post a trajectory. Repeatable, diffable, replayable across a catalogue. The cost is expressiveness: the parameterization describes poses on a sphere around a subject, so it can only say things that are points on that sphere.

Handed over as footage

You supply a driving video and the model transfers the motion in it. fal describes the Kling endpoint as transferring movements from a reference video to any character image. The specification is not numbers and not words, it is a performance, and the thing being specified is the subject rather than the camera. That is the mechanism behind motion control and what it costs to run.

ApproachSpecification isBest atWeak at
Prompt phraseA sentenceAny move you can nameRepeating it exactly
Keyframe arrayNumbers on a sphereOrbits you replayMoves off the sphere
Driving videoFootageSubject performanceCamera path
Novoads UGC ad templates gallery
Novoads · UGC video ads with AI, ready in minutes.
Try now

Where a written camera move still wins

A typed control surface is not a strict upgrade over a phrase, and anyone selling it as one has not read the schema. Three places prose still wins outright.

Moves that are not orbits

The parameterization is spherical. Every field is defined relative to the subject: an angle around it, an angle above it, a distance from it. So every pose the array defines is a point on a sphere centred on that subject. A dolly down a corridor is not a point on that sphere. Neither is a handheld drift, nor a whip pan that leaves one product and arrives at another, because the centre would have to move mid-shot. Those still belong in the prompt.

When the move is still a question

Numbers demand a decision you may not have made yet. Early in a concept, the useful loop is three renders of "slow push in", "slow pull back" and "orbit" so you can see which one the product likes. Writing three trajectories to answer a question a sentence answers faster is a process tax, not precision. Coordinates are for after the choice, not instead of it.

When there is no single subject

"Around the subject" assumes a subject. A sentence can be vague about a centre because it never needed one. A trajectory cannot, and these are the cases where that bites:

  • A flat lay with four items and no hero.
  • A scene where the product enters late.
  • An ad whose point is the room rather than the thing in it.

Put together, the split is less about which control is better and more about which question you are currently answering:

Reach for a trajectory when:

  • The move is an orbit, a rise or a push around one clear subject.
  • You already know the move and need it again, identically.
  • The same shot has to run across many products.

Reach for a sentence when:

  • The move is still a question you are testing.
  • The camera travels through space rather than around a thing.
  • The shot has no single centre to orbit.

A worked example: one bottle, four poses, thirty SKUs

The path, as four poses

A full orbit that starts and ends on the front label, written as four keyframes on a normalized timeline:

  • time 0.0, azimuth 0, elevation 0, distance 1.0. The opening frame, straight on.
  • time 0.35, azimuth 90, elevation 10, distance 0.7. A quarter turn, slightly above, closer in.
  • time 0.7, azimuth 180, elevation 0, distance 0.7. Round the back, still close.
  • time 1.0, azimuth 360, elevation 0, distance 1.0. All the way round, back to the opening framing.

Four poses, sixteen numbers, one file. Note that the last pose reads 360 and not 0: because the schema preserves signed full turns, that is what makes it a complete revolution instead of a camera that never left.

What changes per SKU and what does not

Swap image_url for the next product photo and everything about the move is held. What is not held is everything else:

  • How a taller bottle crops at distance: 0.7.
  • Whether a glossy label survives the back half of the turn.
  • Whether a dark product reads at all at elevation: 10.

That is the useful reframing. The camera stops being a variable under test and becomes a constant, which is precisely what lets you see the variable you actually care about.

The hold rule is doing quiet work

The first pose being held before its time and the last held for the remainder is not a footnote. It means you can buy a beat of stillness at either end without spending a keyframe on it. Put the first pose at time 0.1 and the shot opens on a static hero frame for the first tenth of the clip, then moves. For an ad, where the opening frame is the thing a viewer decides on, that is a real control and it costs nothing.

How Novoads solves the repeatable-move problem today

To be plain about it:

  • H3 Max is not one of the engines Novoads runs.
  • There is no camera-trajectory input anywhere in the product.
  • This post is us tracking a control surface we find interesting, not announcing one.

What does run is a different answer to the same problem. Kling Motion Control costs 3 credits for a five-second Pro clip, and it specifies motion by transfer: you hand it a driving video and a character image, and the performance in the video becomes the performance in the render. It solves repeatability from the subject's side rather than the camera's, and for a talking product ad that is usually the side that matters. On the Inicial plan's 50 credits a month, that is sixteen five-second clips with two credits left over, which is enough to test a move properly rather than once.

The engines underneath all of this are rented and they reprice monthly. The workflow on top, a script, a cast actor, a voice, captions, a 9:16 master and a dozen testable variants, is the part that stays yours, and it is what you are actually buying when you pick a tool rather than an API key.

The Novoads app: pick an AI actor, write a script, generate a UGC ad
Novoads · UGC video ads with AI, ready in minutes.
Try now

A move you can write down is a move you can reuse

The interesting thing about camera_trajectory is not that it produces a better orbit. It probably produces a comparable orbit to a well-written prompt on a good day. The interesting thing is that it produces the same orbit tomorrow.

Creative work has been slowly moving from things you ask for to things you specify, and every step of that migration turns a re-roll into an asset. A prompt you rewrite is labour. A trajectory you replay is inventory. When the camera move becomes a file, the question stops being whether the model understood you and starts being whether the move was worth making, which is the only question that was ever worth your time.

Frequently Asked Questions

What are AI video camera controls?

Camera controls are the part of a video model's interface that decides where the virtual camera sits and how it moves. On most ad video models there is no such interface, so the move is read out of your text prompt. On fal's H3 Max camera-controls endpoint there is one: an input called camera_trajectory that takes an ordered list of camera poses, each with an angle around the subject, a vertical angle, a distance and the moment in the clip it applies to.

How many camera keyframes does the H3 Max camera endpoint accept?

Between 2 and 12. The published schema sets minItems to 2 and maxItems to 12 on the camera_trajectory array, and documents the hold behaviour around them: the first pose is held before its time and the final pose is held for the remainder of the video. It also caps the path at 32 turns of total azimuth travel.

What do azimuth, elevation and distance mean in an AI video camera path?

They are spherical coordinates around whatever the camera is pointed at. fal's schema defines azimuth as the horizontal camera angle around the subject in degrees, elevation as the vertical camera angle around the subject in degrees (clamped between -90 and 90), and distance as the camera distance from the subject in normalized scene units. Together they describe a point on a sphere, which is why the shape suits an orbit around one product and suits a dolly down a corridor much less.

Can I use MiniMax H3 Max camera controls inside Novoads?

No. H3 Max is not one of the engines Novoads runs, and nothing in this post describes a Novoads feature. We track model releases like this one because the engines are the rented layer of the product. The control surface that does run in Novoads today is Kling Motion Control, which works on a different principle: it transfers a performance from a driving video onto a character image.

Is a keyframed camera path better than a camera prompt?

It is more repeatable, which is not the same as better. A numeric path is a file you can replay across thirty product shots and get the same move every time, and a sentence is not. But the path can only express poses on a sphere around a subject, so moves that are not orbits still belong in the prompt, and a written move stays the cheaper way to find out what you want before you commit to it.

Does a camera trajectory guarantee the shot you specified?

No, and the endpoint hints at that in its own output. It returns an expanded_prompt, described as the prompt after expansion as sent to the model, which means a language layer still sits between the numbers you posted and the frames that come back. fal calls the control precise on its model page. That is fal's word for its own product, and we could not find an independent measurement of trajectory adherence on this endpoint.

Key Takeaways

  • On fal's H3 Max camera endpoint the camera path is a typed input rather than a phrase. camera_trajectory is an ordered array of between 2 and 12 keyframes, and the schema caps total azimuth travel at 32 turns.
  • Each keyframe requires four numbers: time (0 at the start of the clip, 1 at the end), azimuth in degrees, elevation clamped between -90 and 90, and distance in normalized scene units.
  • The camera rig belongs to fal, not to MiniMax. fal describes H3 Max as its own post-train on top of the MiniMax H3 base model, and the endpoint's input schema describes itself as a multi-angle input with a fixed internal camera LoRA.
  • Numbers buy repetition, not obedience. The endpoint still returns an expanded_prompt, so a language layer sits between your array and the render, and we could not find an independent adherence test for this endpoint.
  • H3 Max is not on Novoads and we are tracking it. What runs today is Kling Motion Control at 3 credits for a five-second Pro clip, which specifies the subject's performance rather than the camera's path.
Mauricio Valdivia

Mauricio Valdivia

Founder of Novoads

Mauricio is the founder of Novoads, where he works to democratize video advertising with AI for brands in Latin America.