The short version
Some things in a video have to be exactly right: a product name, a number on a chart, the label on a button, the boxes in a diagram, the caption under a speaker. Some things only have to look right: a face, a room, steam coming off a mug, a street at night. Generative video is great at the second list and unreliable at the first: in this run it spelled one short title perfectly and garbled everything denser. Animated HTML (we use Remotion, which renders React components to MP4) is exact at the first list and can't do the second at all.
So we stopped trusting the video model to write. The house pattern is: generate the plate (the background shot), type the words on top in Remotion. This post is the evidence for that rule, with the four briefs that tempt people to generate anyway.
The decision table
Every number here comes from a file in the run folder; the file is named in the last column. "Words right" is a count of the words the brief names, read off the last frame and checked against all 12 frames of the contact sheet. "s/s" is seconds of compute per second of finished video; "t2v" is text-to-video, "i2v" is image-to-video.
| Job | Use | Remotion (CPU) | LTX 2.5 (GPU) | Where the numbers come from |
|---|---|---|---|---|
| Title card with a product name (P11) | Remotion | 6/6 words right; 14.2 s wall for 5 s (first render of the session) | 6/6 words right; 81.1 s wall, 16.1 s/s | render-remotion.log; tests/195 timing.json, verdict.md |
| Chart that draws itself (P12) | Remotion | 10/10 labels and values right; 7.3 s wall | 3/10 right; 99.1 s wall, 19.7 s/s | render-remotion.log; tests/196 |
| UI with a cursor and a click (P13) | Remotion, or a capture of the real app | 5/5 words right; 7.1 s wall | 2/5 right; 72.1 s wall, 14.3 s/s | render-remotion.log; tests/197 |
| Diagram that builds (P14) | Remotion | 4/4 boxes right; 7.7 s wall | 0/4 right; 72.1 s wall, 14.3 s/s | render-remotion.log; tests/198 |
| A sign or a label that lives inside a photographic scene (P06, "VIDEO LAB" neon) | A still with the text checked, then image-to-video | n/a | Text-to-video wrote VIDDEO LAB: 1/2 words right in 12/12 frames, 72.1 s wall, 14.3 s/s. A Z-Image Turbo still spelled it right (9.0 s), and LTX image-to-video from that still kept VIDEO LAB in 12/12 frames: 2/2, 84.1 s wall, 16.7 s/s, scored 4/5 overall | tests/016, 006, 026 (timing.json, verdict.md) |
| Lower thirds and captions | Remotion (house LowerThird and Captions templates, word timing from the ElevenLabs alignment) | the 10 s composite below, with a title and a lower third over two generated plates: 13.9 s wall | not tested separately | render-remotion.log |
| Product and object shots (P02 mug) | LTX 2.5, text-to-video or image-to-video | n/a | 4/5 overall both ways; 75.1 s wall (14.9 s/s) t2v, 78.1 s (15.5 s/s) i2v | tests/012, 022 verdict.md |
| Places, camera moves, mood (P03 lighthouse, P09 night street) | LTX 2.5 (image-to-video when it matters) | n/a | P03 4/5 t2v and i2v; P09 3/5 t2v, 4/5 i2v; 14.3 to 16.1 s/s | tests/013, 023, 019, 029 |
| Stylized characters (P07 cartoon fox) | LTX 2.5 image-to-video from a still | n/a | 5/5 overall, 84.2 s wall, 16.7 s/s | tests/027 |
| Faces and talking hosts | LTX 2.5 image+audio (InfiniteTalk not tested here), then Remotion for the name plate and captions | n/a | not scored in this post; the instructional's hosts are LTX 2.5 image+audio | qa/hosts-gate.md |
Two numbers to hold onto. A finished 5-second Remotion composition took 7.1 to 7.7 seconds of wall time on the CPU (1.4 to 1.5 s per second of video, including the browser launch and the encode, outside the GPU lock); the first render of the session took 14.2 s. LTX 2.5 at 1280x704 took 14.3 to 19.7 seconds of GPU per second of video on the same four briefs, and got 11 of the 25 named words right where Remotion got 25 of 25. Six of those eleven were the title card.
The four briefs
We wrote four prompts in the style of P06 (text on screen) and P02 (a product shot), the kind of thing people reach for a video model to do: a title card for a product called ORBIT LAMP, a bar chart of weekly signups (MON 120, TUE 180, WED 260, THU 340), a settings page where a cursor clicks a Dark mode toggle, and a flowchart that builds Script, Voice, Video, Publish. They are P11 to P14 in the run's prompt file, added on Nov 2 as new ids.
Then we made each one twice. Once as a small Remotion composition (49 to 82 lines of TypeScript each, data in the props, so the product name or the chart values are a JSON edit). Once with LTX 2.5 22B distilled, text-to-video, seed 42, at the suite's fixed settings.
What came back:
- Title card. Remotion: ORBIT LAMP slides in letter by letter, the pink line draws, "Desk light, model 2" fades in, and every word is spelled exactly as written once it has appeared. LTX: all six words right: ORBIT LAMP, the pink underline and "Desk light, model 2", spelled exactly from the frame each appears to the end. The words fade in whole rather than letter by letter, but on this seed the text is correct. Scored 4/5 overall (tests/195 verdict.md).
- Chart. Remotion: four bars grow in order and each number counts up to its exact value. LTX: the title reads "Weelky sigups", there are no day labels at all, and it drew seven bars instead of four, tagged 120, 120, 180, 180, 360, 360, 340: 260 never appears and 360 was invented. 3 of 10 named words and numbers, and the bar heights don't match their own tags. 1/5 overall.
- Settings UI. Remotion: the cursor travels to the toggle, the click lands on frame 78, the page eases to dark over 12 frames. LTX: a light list of pseudo-text ("Genarst Billing.", "Arrcout,", "Dar1 Bimode"), no sidebar, no toggle labelled Dark mode and no click; the whole frame just dims after 2.5 s. Only "Billing" and "Dark" appear spelled right, and only inside nonsense labels. 1/5 overall.
- Flowchart. Remotion: each box lands, then its arrow draws itself before the next box. LTX: the boxes do pop in left to right, but they read Spipt, Vicre, Vidce, Bubil and Pulish, five boxes for a four-box brief. 0 of 4. 1/5 overall.
The title card surprised us. Two short lines of large type, about the friendliest text a video model can be asked for, and LTX spelled every word right, drew the pink line and faded the subtitle in. If the only brief had been that one, this post would have a different headline. The other three are what most motion graphics actually look like (a chart with ten labels, a UI with five, a diagram with four short words), and there it produced "Weelky sigups", pseudo-text and Spipt. One seed each, so we can't say how often the title comes out right; we can say we wouldn't ship a product name without checking every frame, and at that point the Remotion version is already rendered.
The P06 neon sign is the cleanest single example from the suite. Asked for a sign that reads VIDEO LAB, text-to-video wrote VIDDEO LAB in every one of the 12 sampled frames, sharp and confident and wrong. Our reviewer scored it 1/5 overall: "A misspelled title sign cannot ship in any cut" (tests/016, verdict.md). Handed the words, the same model kept them: image-to-video from a Z-Image still that already said VIDEO LAB kept both words in all 12 frames (tests/026). So when text has to live inside a photographic scene (a sign on a wall, a label on a bottle), make the still, check the spelling with your own eyes, then animate it.
The model also writes when nobody asked. On the suite's robot mascot prompt it put a well-known fruit logo on the laptop lid (tests/018), and on the skateboard prompt a sportswear swoosh on the hoodie (tests/024). Remotion draws exactly what's in the props and nothing else.
Where generation wins
None of this makes the video model the loser. The same suite at the same settings gave us a clean product push-in with curling steam (tests/012 and 022, 4/5 both), an establishing shot of a lighthouse (tests/013 and 023, 4/5), a cartoon fox that held its style for five seconds (tests/027, 5/5), and a night street with a crowd (tests/029, 4/5 from a still). Remotion can't make any of those. It draws rectangles, text, SVG and whatever images and video you give it. Products, places, motion and mood come from the model.
The house pattern: both
The composite at the end of the film is two generated plates (the P02 mug, t2v and i2v, untouched) with a Remotion title and a lower third on top. The plates cost 75.1 and 78.1 seconds of GPU. The type cost 13.9 seconds of CPU for the 10-second shot, and changing it is a props edit and another CPU render. We tried that: changing "model 2" to "model 3" in the title card and re-rendering took 9.1 seconds. Getting a different spelling out of the video model means another full generation and another look at every frame.
Every Video Lab instructional already works this way: the cast host is generated (LTX 2.5 image+audio) and the name plate, captions, diagrams and score sheets are Remotion.
How we tested
- Remotion side. Four new compositions (LabTitle, LabChart, LabSettings, LabFlow), plus LabComposite for the plate-and-type shot and HtmlVsGen for the split-screen film. 1920x1080, 30 fps, 150 frames (5 s, the length of an LTX clip). Rendered one at a time with the run's
bin/render-remotion(Remotion 4.0.539, chrome-headless-shell 154 for aarch64 with--gl=angle, H.264, concurrency 10). The wall time it prints covers the browser launch and the encode; the first render of the session took 14.2 s against 7.1 to 7.7 s for the next three (most likely the cold bundle cache; not measured separately). MemAvailable was 19 to 25 GiB at each render's start (an LTX job was running on the GPU at the same time, under its own lock). - Generative side. LTX 2.5 22B distilled int8, text-to-video, 1280x704, 121 frames at 24 fps, two stages (8 steps at half size, 2x latent upscale, 3 steps), CFG 1.0, seed 42, one job each through the run's queue and
bin/run-test(tests 195 to 198). Same graph, same settings as the suite's P01 to P10. - Scoring. The methodology's 1 to 5 rubric on a 12-frame contact sheet per clip, written up in each test's verdict.md. Words were counted on the last frame and checked across all 12 sheet frames; a word counts only if it is spelled exactly as the brief has it.
- One seed. Each generated brief ran once (seed 42). The P06 result (one seed, one misspelling) and the three dense briefs agree, the title card is the exception, and the Oct 31 LTX review found pseudo-text on every label that appeared in its ten clips. More seeds would put a number on how often it gets lucky; we didn't spend the GPU on it.
Setup and gotchas
- Remotion can only load files from its public folder or a URL. The run's
bin/render-remotionhard-links local clips intoremotion/public/_assets/and rewrites the props for you. In the embedded player on this page the clips load from the media bucket by https URL. - A cross-fade between two video plates fades over black if the first plate's
<Sequence>has already ended. Our first composite render had a black frame at the cut; the fix was a hard cut (or overlap the two sequences by the fade length). - Freeze is how you hold a frame. The split-screen film plays both sides for 150 frames, then holds the last frame under the verdict.
<Freeze frame={n}>around the HTML panel and the<OffthreadVideo>holds both. - Scale a 1920x1080 composition into a smaller cell with a CSS transform, not by re-laying it out: the HTML panel in the film is the same component at
scale(0.448). - Autoplay is not guaranteed in an embedded player. Headless Chrome (and some browsers) won't autoplay without a click, and our chart starts empty at frame 0. The player opens on frame 120, so a paused player still shows the finished chart.
- The negative prompt can't save you. LTX 2.5 distilled runs at CFG 1.0, where the negative prompt has no effect (Oct 31 review), so "no text" and "correct spelling" are wishes (CFG is how strongly the model follows the prompt over the negative; the distilled model runs at 1.0).
- License. Remotion is free for individuals and companies of up to three people; a bigger company needs a Remotion Company License (LICENSE.md). LTX 2.5 is under the LTX-2 Community License, free under $10M revenue.
Settings
- Remotion compositions:
remotion/src/lab/(LabTitle, LabChart, LabSettings, LabFlow, LabComposite, HtmlVsGen), registered insrc/Root.tsx. Props for every render are in the post folder'sprops/. - Render:
bin/render-remotion <Composition> <props.json> <out.mp4>; concurrency 10,--gl=angle, JPEG frames, H.264, then a-c copy -movflags +faststartremux. - LTX:
ltx_i2vjob kind in t2v mode,w 1280, h 704, frames 121, seed 42, prompts P11 to P14 verbatim (in each sample's "Prompt and settings"). - The player on this page:
src/lab/player-lab.tsx, bundled to one HTML file with esbuild (src/lab/build-lab-player.mjs), 624 KB.
Speed and memory
| Render | Output | Wall time | Wall s per s of video | Source |
|---|---|---|---|---|
| Remotion LabTitle (first of the session) | 5.0 s, 150 f, 1080p | 14.2 s | 2.8 | render-remotion.log |
| Remotion LabChart | 5.0 s | 7.3 s | 1.5 | render-remotion.log |
| Remotion LabSettings | 5.0 s | 7.1 s | 1.4 | render-remotion.log |
| Remotion LabFlow | 5.0 s | 7.7 s | 1.5 | render-remotion.log |
| Remotion LabTitle after a text edit | 5.0 s | 9.1 s | 1.8 | render-remotion.log |
| Remotion LabComposite (two plates + type) | 10.0 s | 13.9 s | 1.4 | render-remotion.log |
| Remotion HtmlVsGen film, layout preview | 49.0 s, 1470 f | 48.7 s | 1.0 | render-remotion.log |
| LTX 2.5 t2v, P11 title | 5.04 s, 121 f, 704p | 81.1 s | 16.1 | tests/195 timing.json |
| LTX 2.5 t2v, P12 chart | 5.04 s | 99.1 s | 19.7 | tests/196 |
| LTX 2.5 t2v, P13 UI | 5.04 s | 72.1 s | 14.3 | tests/197 |
| LTX 2.5 t2v, P14 diagram | 5.04 s | 72.1 s | 14.3 | tests/198 |
| LTX 2.5 t2v, P06 sign | 5.04 s | 72.1 s | 14.3 | tests/016 |
The Remotion numbers are CPU wall time on the Spark's 20 cores while an LTX job held the GPU; Remotion's memory use was not measured. The LTX numbers are GPU wall time per test. Tests 195 and 196 each ran right after image-model jobs on the same server (logs/gpu-queue.log), so their 81.1 s and 99.1 s may include reloading LTX; 196 started with 68 GiB available against 33 to 43 GiB for the other three, which fits a reload. 197 and 198 ran back to back at 72.1 s each. How much of the extra time was loading was not measured. The lowest MemAvailable during the four briefs was 32 GiB (timing.json of tests 195 to 198: 32, 39, 39, 37). The two columns are the same kind of number (wall seconds per second of finished video on one box) measured on different hardware: the Remotion renders ran on the CPU beside the GPU queue without waiting for it.