Nodes/arkennemasis - ChatGPT / Codex / fal AI nodes/arkennemasis fal · MiniMax H3 Max Camera Controls · $0.05-0.16/s
ComfyUI Node

arkennemasis fal · MiniMax H3 Max Camera Controls · $0.05-0.16/s

Orbit a still with a JSON keyframe list

By Hishamahmer·Created 3 months ago·Updated 9 days ago· 11
arkennemasis fal · MiniMax H3 Max Camera Controls · $0.05-0.16/s
  • image
  • video
  • video_path
  • timings
  • expanded_prompt
  • info
◄promptThe same elements in the reference are rigid. Preserve every element exactly. The entire scene is frozen. Only the camera moves. no scene motion only camera motion►
◄duration5►
◄resolution480P►
◄seed-1►
◄enable_safety_checkertrue►
◄prompt_expansion_modebalanced►
◄camera_trajectory[{"time": 0, "elevation": 0, "azimuth": 0, "distance": 1}, {"time": 0.3, "elevation": 15, "azimuth": 45, "distance": 0.2}, {"time": 0.8, "elevation": -90, "azimuth": 90, "distance": 1}]►
◄max_cost_usd20.0►
◄reuse_identical_runtrue►
◄extra_json►
◄max_concurrent1►

One picture in, a camera move out

Most image-to-video nodes will happily pan and zoom if you ask nicely in the prompt, and then do something else anyway. This one takes a list of camera poses and follows it. Give it a still and three keyframes and you get a controlled orbit, arc or pull-back - the camera moving, the scene staying put.

That distinction is the point. The node's default prompt says it out loud, and it's worth reading twice:

"The same elements in the reference are rigid. Preserve every element exactly. The entire scene is frozen. Only the camera moves. no scene motion only camera motion"

You're getting a camera move, not an animation. Great for product shots, architectural reveals, turntable-style loops for a still, or establishing a 3D-feeling shot from a single image. Wrong tool if you want the subject to do anything.

Pricing is the H3 Max video ladder - $0.05/s at 480p, $0.08/s at 768p, $0.16/s at 1080p - with the note that fal was running 50% promotional rates on some H3 Max endpoints through the end of September 2026, so check what your node's badge says today rather than trusting a blog post.

The input that does the work

camera_trajectory - JSON, ordered keyframes, and the only genuinely fiddly thing here. Each entry has four fields:

[{"time": 0, "elevation": 0, "azimuth": 0, "distance": 1},
 {"time": 0.3, "elevation": 15, "azimuth": 45, "distance": 0.2},
 {"time": 0.8, "elevation": -90, "azimuth": 90, "distance": 1}]

time is the normalised position in the clip (0 to 1), azimuth is the horizontal angle, elevation is up/down, and distance is how far the camera sits from the subject. The first pose holds before its time, the last holds for the rest of the video, and signed full turns are respected with a cap of 32 turns of total azimuth travel - so you can loop the camera right around if you want.

The shipped default is a usable demo, not a recommendation: it swoops in close at 45°, then drops underneath and swings round. Replace it with two or three poses you actually want, and keep the intervals even unless you're deliberately accelerating.

The rest:

  • image - the required first frame. Canvas follows it.
  • prompt - present with that frozen-scene default. Blank leaves it out; that's usually correct.
  • duration - seconds, default 5. Your trajectory's time values are fractions of this.
  • resolution - 480P (default), 768P, 1080P. The 1080P tier is latent refinement from a native 768P source.
  • seed (-1 = model picks), enable_safety_checker (on), and prompt_expansion_mode (disabled, fast, balanced default, quality - the last one can spend ~30s enriching your prompt, which is exactly what you don't want for a "nothing moves" instruction).

Guards: max_cost_usd ($20 default, 0 off), reuse_identical_run, extra_json, max_concurrent (1 by default).

Outputs

video (to SaveVideo, PreviewVideo, or the pack's Video Assemble), video_path, timings (how long fal spent on each stage - the honest place to look when a run felt slow), expanded_prompt, and info with the request id, estimate and fal's raw answer.

Install

cd ComfyUI/custom_nodes
git clone https://github.com/Hishamahmer/comfyui-arkennemasis
pip install -r comfyui-arkennemasis/requirements.txt

Restart, then arkennemasis/fal/Video/MiniMax. .env next to the launcher:

FAL_KEY=your-key-from-fal.ai/dashboard/keys

Where people get burned

JSON is JSON. A trailing comma, a missing bracket, or counts wrapped in quotes and the run fails before it costs you anything - the node validates extra_json and its own JSON boxes before upload. If you edit it in a text editor and paste it back, check the shape first.

time is not seconds. It's the fraction of the clip. A pose at time: 5 on a 5-second video is meaningless; a pose at time: 1.0 is the last frame, which is where the hold begins.

Distance is the motion. A trajectory that changes only azimuth gives you a flat orbit. The pull-in/pull-out that makes these clips look expensive usually comes from moving distance as well.

Over-ambitious poses read as a glitch. Full turns in 5 seconds, or an elevation that flips the camera upside down mid-shot, produce something that looks like a render error. Signed full turns are supported - that doesn't mean they're tasteful.

The prompt fights you if you let it. With prompt expansion on quality, the model may rewrite "only the camera moves" into something livelier and give you scene motion you spent money trying to avoid. disabled is the safe setting here.

Categoryarkennemasis/fal/Video/MiniMax

Inputs (12)

NameTypeDefaultDescription
promptSTRINGThe same elements in the reference are rigid. Preserve every element exactly. The entire scene is frozen. Only the camera moves. no scene motion only camera motionText prompt for video generation. When omitted or blank, defaults to preserving the frozen reference scene while only the camera moves. Empty leaves it out.
durationINT53–15The duration of the video in seconds.
resolutionCOMBO480PThe native generation resolution, or 1080P latent refinement from a native 768P source.
seedINT-1-1–2147483647Random seed. A random seed is selected when omitted. -1 leaves it to the model.
enable_safety_checkerBOOLEANtrueIf set to true, the safety checker will be enabled.
prompt_expansion_modeSTRINGbalancedHow much effort to spend rewriting the prompt before generation. 'disabled' skips prompt expansion. 'balanced' returns in about a second. 'quality' spends up to ~30s on a richer prompt.
imageIMAGEURL of the image to use as the first frame.
camera_trajectorySTRING[{"time": 0, "elevation": 0, "azimuth": 0, "distance": 1}, {"time": 0.3, "elevation": 15, "azimuth": 45, "distance": 0.2}, {"time": 0.8, "elevation": -90, "azimuth": 90, "distance": 1}]Ordered camera keyframes. The first pose is held before its time and 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. JSON. Empty leaves it out.
max_cost_usdoptFLOAT20.00–100000Safety cap. If the estimated cost of this run is above this many US dollars the node stops BEFORE sending anything to fal. 0 = no cap.
reuse_identical_runoptBOOLEANtrueIf these exact inputs (the settings AND the same pictures/clips/audio) were already paid for and the files are still in output/fal, return them instead of paying again - also after a ComfyUI restart. Turn off for a fresh take with the same settings.
extra_jsonoptSTRINGAdvanced: a JSON object merged into the request last, for any fal field this node has no box for. Example: {"seed": 7}. Leave empty normally.
max_concurrentoptINT11–32How many paid fal calls may run at the same time in one run, across every fal node. 1 (default) = one after another. This node starts its paid part only while fewer than this many fal calls are running. Once any fal node fails, the ones still waiting are not started, so nothing more is billed.

Outputs (5)

NameTypeDescription
videoVIDEO—
video_pathSTRING—
timingsSTRING—
expanded_promptSTRING—
infoSTRINGJSON: request id, cost estimate, saved files and fal's full answer.