I finished a five minute music video this week. Sixty eight shots, one song, about eight days.
It is not perfect. There are shots in it I would redo if I had another week, and I will point at a few of them further down.
Almost none of that week went into generating video. It went into judging it.
The song came first
I started with Suno and generated the track. That mattered more than I expected, because once the song existed everything else had to serve it. The cut is locked to the vocal. Every shot carries its lyric in the manifest, and when a shot ran long or landed on the wrong word it was the song that told me, not my taste.
Song first, then pictures.
The images came from Astra. The video never left my machine.
Two different things, and people keep collapsing them, so to be exact about it:
The still images were generated with GPT-6 Astra. Reference frames, the look development sheets, the key image that every shot starts from. That is where the money went. It burned through roughly two accounts worth of credits, because a five minute video is sixty eight shots and each one wants a key image you actually believe.
The video was generated locally, from the beginning. A quantized LTX build on my own Mac, 768 by 448 at 24 frames per second, frame counts landing on 8n+1. There was never a cloud video step and never a migration away from one.
Here is a real prompt from day one, the look development sheet that set the visual language before a single shot existed:
Use case: stylized-concept, photorealistic cinematic production design. Create a highly realistic film art department look-development contact sheet for an original FICTIONAL dystopian music video. Four large cinematic frames in a precise 2x2 grid, each frame widescreen 16:9 […] Real photography look, convincing anatomy and architecture, lens depth, restrained 35mm grain, cold desaturated blue-grey industrial palette, dirty off-white, small deep red control lights. Physically plausible lighting and materials, concrete pores, wet glass, rain, grey coarse cotton fabric. Dark but readable, not crushed black. Oppressive near-future AI governance, humanity vulnerable, no fantasy robot spectacle, no illustration or diagram.
That is the shape that works for me. Not a vibe. A list of physical facts about materials and light, and an equally long list of what must not appear.
The actual work was judging
Local generation makes takes nearly free. That sounds like it makes the job easier. It does the opposite, because now you have 336 takes for 68 shots and something has to decide which ones are good.
For most of this project that something was me, watching. It does not scale and it is not reliable. You get tired, you stop seeing, and you start approving things because you want to be finished.
So the thread that runs through the whole project is trying to find deterministic ways to judge it. Ways that give the same answer whether I am fresh or exhausted. That took a while to get right, and it is the part I would tell somebody else to start on sooner.
Three times a number was smarter than me, and three times it lied
The honest version of “deterministic judging” is that the measurements were wrong about as often as they were right, and the failures taught me more.
It caught a flash I never saw. One shot blew to pure white for five frames in the middle, luma jumping from 23 to 253. I had watched that shot. Every check I had was sampling three frames per shot, and a five frame event at 24 frames per second simply falls between samples. I wrote a pass that decodes every frame at thumbnail size and compares each one against its own scene’s median. It found it instantly, and it found exactly one across all 8,988 frames.
It caught a screen that would not hold still. Screens inside shots are the hardest thing here, because the model regenerates their contents every frame. I froze them. They still looked wrong. Measured, the frozen middle of the panel was changing 0.006 per frame and the strip just outside it was changing 6.37. The freeze was working perfectly and the rectangle was too small. I would never have found that by looking, because what you see is “it flickers” and what you fix is the middle.
And it told me a shot was fine when it was a photograph. A shot measured 60 percent of pixels changed across its slot, which reads as plenty of movement. The two people in it never moved at all. The number was measuring drifting fog and a small camera drift. That one is now written down in big letters: a motion number is a screening tool, never a verdict. Measure the region that holds the thing that should move, measure the background separately, and then go open the frames.
The numbers
| Span | 13 to 21 September, eight days |
| Shots in the finished film | 68 |
| Generated takes still on disk | 336 |
| Sources superseded and archived | 129 |
| Review receipts written | 345 |
| Full film renders | 13, plus 79 scoped checks, 8,988 frames each |
| Purpose built scripts | 36 |
| GPU busy time | at least 26 hours |
Thirty six scripts for one music video sounds absurd until you notice what they are. Almost none of them generate anything. They check things. Did the footage follow the key image when I swapped it, or did only the manifest change. Does this graphic still land on the surface it was tracked against. Does the delivered file have a black scene or a slot holding a single frame.
The GPU figure needs a caveat, because my own guess was much higher. I thought the card had been working for over a week. Measured, by clustering the completion times of every take still on disk, it is about 26 hours. The real total is higher, because overwritten takes and all 92 renders are not counted. But it is nowhere near a week, and I would rather print the number I can defend than the one I felt.
Where this sits against last year
I run a channel called VerseVector for this kind of work. If you want the before picture, the early videos on it are right there.
Last year I spent thousands of dollars on credits generating video, and it was not very good. Then Sora arrived and that was okay, and that is roughly the second half of what is on that channel. Everything I post now is generated locally.
Thousands of dollars for something I was not happy with, then a cloud tool that was fine, then my own machine doing work I would put my name on. In about a year.
What is still wrong with it
There is a shot of two people walking toward a door that I built by reversing a take. Reversing it turned their walk backwards, which anybody could see in a second. I had to put it back.
A couple of the wide shots hold a beat longer than they earn.
And the judging is still not where I want it. I have deterministic checks for flashes, for frozen screens, for graphics drifting off the thing they were tracked to. I do not have one for “is this shot any good”, and I am not sure that one exists.
I could keep going on this. I want to start the next project more, so it ships like this.
The short version
Generating the video was the cheap part and it always ran on my own machine. The expensive part was deciding which takes were good, and the only progress I made there came from building things that measure instead of things that generate.
Related
-
I Tried Three Clever Ways to Find Stale Notes. All Three Were Wrong.
My agent's memory goes stale and I wanted the machine to notice on its own. The best idea found nothing across fifty real cases, and that null result turned out to be the whole answer.
-
I Ran the Memory Prompt on This Site's Repo. Here's What It Wrote.
One paste, five small files, about sixty-five lines. What the setup prompt actually does to a real repo, including the parts it got wrong.
I send a short letter when there's something worth saying: what I built, what broke, one thing I learned. No gates, no popups.