Everyframe · composition
One pipeline. Every version.
A table goes in. Finished videos come out, one per row. Every video on this page came from the same pipeline and the same six photos. Only the row changed.
A hundred and eight videos, one run
Five things vary across this batch. None of them is a separate pipeline: each is a column in the table, and the run is every combination of them. Turn sound on in the player: the scored cuts carry a bed, and the narrated ones speak over it.
Add a market and it is 162. Add a fourth format on top and it is 216. Nobody opens an editor for any of them, which is the entire point: the work grows by multiplication, and the effort does not.
Every cell below is a finished file. Pick one and it plays. Nothing is made in your browser: each video was rendered once, on the fleet, and is served exactly as it came back.
/
File
| The row | 16:9 | 9:16 | 1:1 |
|---|
Twelve rows, three formats each, and the soundtrack switch swaps all thirty six for another thirty six. The formats and the soundtracks are lists in the run, not jobs somebody remembered to start.
The row that made it
This is the whole pipeline. It is a TypeScript function: row in, render out. The highlighted values are the only things that differ between the video you are watching and the other hundred and seven.
The row
The pipeline
The call returns a graph, not a file. The engine compiles that graph, the fleet runs it, and the output lands in storage under the name the row was given. Twelve rows, three formats and three soundtracks is a hundred and eight of those, submitted in one pass.
What the types catch
A batch is worth little if a tenth of it comes back wrong. Most of that risk is in the shape of the job, and the shape is checked before anything runs.
Caught before the run
- A slide with no duration.
- A resolution that is not two numbers.
- A transition or crop mode that does not exist.
- An option the recipe does not take.
These are compile errors. The batch cannot be started with them in it.
Caught during the run
- A photo that is missing from storage.
- A source file the decoder rejects.
- A row whose text is empty.
- A worker that runs out of memory.
These come back per row, with a reason, while the other rows finish.
We are stating the split on purpose. Types are not a promise that every render is good. They are a promise that the same mistake is not repeated across a thousand rows before anyone notices.
At real size
A hundred and eight is a demonstration. The pattern has run at size. For the Slovenian Chamber of Commerce and Industry we produced the presentation videos for its national innovation awards.
235
innovations, one video each
13
regional chambers: each video carried its chamber logo, innovation name and description
6
narration voices per innovation, to pick from
1,410
finished videos, rendered overnight
Innovations per regional chamber
Nothing about a video was generic. The title card took the innovation's name, the corner took its regional chamber's logo, the slides took the company's own photographs, and the narration read that innovation's description. The slides were held until the narration finished, so no video cut a sentence in half. The work ran while the office was empty, and the results were reviewed in the morning.
That batch ran on the engine's own composition API, an earlier generation of the TypeScript shown above. The shape of the work is the same one this page demonstrates: a table of rows, one definition, one video per row. The awards were public. The videos belong to the companies competing, so they are not republished here.
What changes when the list gets long
One more video is one more line
A new listing, a new SKU, a new hire. Add the row. Nobody opens a timeline.
One more format is one more entry
The three formats here are a list. A fourth is a line of configuration, and the whole table gets it. So is the soundtrack, and so is the language.
Failures stay local
A row that fails comes back named, with the reason. The other rows finish. Nobody restarts the batch.
Dimensions multiply, work does not
Five columns made a hundred and eight files here. A sixth would make more, from the same pipeline, in the same pass, for the same effort.
Missing data is skipped, never invented
A row without its required fields does not render. It is reported. The engine does not fill the gap with something plausible.
What this is not
- ·
Nothing here was generated by a model. The photographs are ours. The engine crops, times, joins and labels them. It invents no footage.
- ·
The narration is machine speech. Every spoken line was synthesized, the same voice reading both languages, and it says so here because a listener often cannot tell. A recorded voice drops into the same slot; the pipeline does not care which it gets.
- ·
The music is a licensed track from our own library. Ten seconds of it, faded at both ends, ducked under the narration. A brand's own bed replaces it by changing one line.
- ·
The slides hold still. Slow push and pan are supported. This batch left them off, so what you see is the cut and the crop doing the work.
- ·
Stock photography stands in for a client's assets. A real run reads a brand's own library, and the look is fixed by the brand, not by the person filling the row.
- ·
Volume is not the same as judgement. Somebody still decides what deserves a video and approves what goes out. This removes the assembly, not the editorial.
Ways to run this
We run the batch
You send the assets and the list. We build the pipeline, run it, and hand back the finished files, named and sorted.
Talk to us →
Composer
coming soonThe app that puts this batch behind a screen you fill in: rows, dimensions, one run. It is in pre-beta now, with no date yet. The engine and its composition SDK already do the work; Composer is the front for it.
The batch runs on the engine's composition SDK, @jtdigital/renderbox-sdk. Processing runs in Europe, or on your own machines if you would rather it never leaves the building. We do not train models on your material.