Come home from a trip and you have hundreds of video clips. Ours arrive a dozen a day, ten or twenty seconds each, and not one person in this household has ever sat down to turn them into something worth watching. “I’ll edit it later” is a promise nobody keeps. Footage from trips we took months ago is still sitting there, raw, exactly where it landed.
So I stopped editing altogether and handed the whole job to a machine.
These days my wife uploads clips to one folder in Google Drive and that is the end of her involvement. Something picks the good moments, cuts them into short highlights, checks them for quality, and publishes them to our YouTube album.
A month in, the count stands at 112 highlights from fourteen days of shooting. One day produced twenty-seven. My total editing time over that month was zero minutes.
This post is about how to build it. I am not a developer and cannot write the code myself. What I can do is describe what I want precisely, which turns out to be enough — I gave the specification to Claude Code and it built the thing. The prompt I actually used is reproduced in full below. Copy it, paste it, and you will have the same system.
What You Need
| Item | Notes |
|---|---|
| Claude Code | The Code tab in the Claude app. Point it at a folder and it writes files and runs commands inside that folder |
| ffmpeg | Free video tool that does the actual heavy lifting. On Windows: winget install Gyan.FFmpeg |
| Python | Needed for the YouTube upload and the scheduled runs |
| A Google account | To authorize uploads to your own channel |
After installing ffmpeg, open a new terminal before running ffmpeg -version. A terminal that was already open is still holding the old environment and will insist the program does not exist. I lost an embarrassing amount of time to this.
The Shape of It: Five Stages, Each Handing Off a File
The skeleton is simple. Rather than asking for everything at once, the work is split into five stages, and each stage writes its result to a file that the next stage reads.
- Collect — find new clips, record date, length, resolution
- Choose — pull stills from each clip, look at them, mark the segments worth keeping
- Edit — cut those segments and assemble highlights by date and theme
- Check — measure brightness, resolution, frozen frames; pass or reject
- Publish — upload to YouTube and file into a playlist
The handoff files matter more than they look. When something goes wrong, you can see exactly which stage broke. If you end up with zero highlights but the stage-two file is full of chosen segments, your problem is in editing, not selection. Build it as one monolithic script and you lose that entirely — you get a shrug and no output.
The Hard Part Is Choosing, Not Cutting
Cutting and stitching is what machines have always been good at. The genuinely hard problem is finding the twenty seconds worth keeping out of fifty clips.
Counting is easy. Is there a face in frame, how many people, is anything moving — all solved problems. But “will we want to watch this again in five years” is not a counting question. Whether a child looks genuinely delighted, whether a family is actually interacting rather than merely standing near each other, whether a shot is pleasant to look at — you do not measure that. You look at it.
So the system imitates the way a person flips through a photo album. It pulls a still every two seconds, tiles them into a single contact sheet, and shows that sheet to Claude, which reads images as readily as text. It looks the way you would look, and points at the good ones.
The important part is keeping the instruction broad. Not “find shots containing my child’s face” but “find moments where the child looks delighted.” Narrow rules feel precise and then shatter the first time reality does something they did not anticipate.
The Prompt, in Full
That is the design. Now for the building, which consists of copying the block below and pasting it into Claude Code. Make an empty folder, open it in Claude Code, paste.
The prompt already contains the traps I fell into. Leave them out and you will find them yourself, in the same order I did.
Build me a "family travel video album" system to the specification below. I can't write code myself, so create all the files you need, and when you're done tell me what I should check.
[GOAL]
When I drop videos into a folder (inbox), the system picks the good moments, cuts them into short highlights, checks their quality, and uploads them to YouTube. It has to be safe to run over and over with nobody watching.
[ENVIRONMENT]
- Windows
- ffmpeg / ffprobe installed
- Python runs via the py launcher
[CONFIG FILE: config.json]
Every path and preference lives in this one file. Do not hard-code paths in the scripts.
- inbox folder, working folder, output folder
- still-frame interval (default 2 seconds)
- theme list (e.g. child's name, family, food, scenery, swimming)
- clip length range (8-30 seconds), target highlight length (60 seconds)
- quality thresholds: minimum height 720, minimum brightness 40, max frozen-frame ratio 0.5
- YouTube privacy setting (unlisted / public), playlist name
The privacy setting in this file is the single source of truth. Do not restate it in code or documentation, or the two will drift apart and one day disagree.
[FIVE-STAGE PIPELINE]
Each stage writes its result to a file and the next stage reads that file. Do not merge or skip stages.
1. Collect - scan the inbox for new videos, extract shooting date, duration, resolution and rotation, save as 01_ingest_manifest.json
2. Choose - use ffmpeg to pull stills at a fixed interval and tile them into a contact sheet, then look at that image directly and choose which segments to keep. For each segment record start time, end time, theme, a score from 0 to 1, and a one-line reason, in 02_scenes.json. Keep only candidates scoring 0.6 or above
3. Edit - cut the chosen segments and group them into highlights by date and theme. Burn in a date caption. Never mix landscape and portrait footage in the same highlight - the portrait clips get stretched to fill a landscape frame and the proportions break. Landscape becomes a normal video, portrait becomes a short
4. Check - measure resolution, brightness, silence and frozen-frame ratio, and also look at a representative frame before passing or rejecting. On rejection send it back to stage 3, but no more than twice per highlight; after that, drop it from publishing and record why
5. Publish - upload to YouTube, add to the playlist, write the outcome to 05_publish_report.json
[USE THE AUDIO TOO]
A clip where a child holds the camera and narrates looks, in still frames alone, like a series of repetitive close-ups, and gets thrown away. So transcribe the speech and use it alongside the images when deciding. Any clip where someone is narrating should be published whole, not cut.
[NEVER UPLOAD ANYTHING TWICE - IMPORTANT]
This runs unattended on a schedule, so it must never process the same video twice or upload the same highlight twice.
- Identify processed videos by a hash of the file contents, not the filename. Renaming or moving a file must not make it look new
- Keep a separate record of what has been uploaded
- Anything that fails, or hits the YouTube quota, gets set aside and retried automatically on the next run
- Use a lock file so two runs can't overlap
[WINDOWS RULES - I HIT EVERY ONE OF THESE]
1. Pass encoding="utf-8" to every subprocess.run call. My Windows is set to a non-English locale, and without this the ffprobe output can't be decoded, so every piece of metadata comes back empty with no error to explain it
2. Don't use wildcards like frame_*.jpg for ffmpeg inputs. Windows builds don't support them. Use a numbered sequence such as frame_%04d.jpg
3. Use -fps_mode, not -vsync. Recent ffmpeg builds don't recognize -vsync, and the error gets swallowed, so the run finishes "successfully" having produced no clips at all
4. At the top of each script, locate ffmpeg and ffprobe and add them to PATH explicitly. A freshly spawned process can be holding an environment from before the install, which produces intermittent file-not-found failures
5. Keep console output to plain ASCII. Non-ASCII characters in a print statement can kill the whole process on a non-UTF-8 console
6. Never report a failed run as a success. Mine once had an expired credential, failed every time, kept reading the last successful report, and cheerfully announced the same fake result every seventy seconds for an hour and a half
[WHEN YOU'RE DONE]
- Tell me what I need to fill into the config file
- Run the whole pipeline once on a video or two and confirm it actually works
- Show me how to schedule it to run automatically each day
Three Things to Do After Pasting
1. Fill in the config file. Your inbox folder, a trip name, your theme list. I would start with the YouTube privacy setting on unlisted. It is family footage, and you can always widen it later; the reverse is less comfortable.
2. Authorize YouTube once. In the Google Cloud Console: create a project, enable the YouTube Data API v3, create an OAuth client ID of type “Desktop app,” and drop the file it gives you into your folder. You consent once in a browser and every upload after that happens without you. If the console makes your eyes glaze over, ask Claude to walk you through it screen by screen — it will.
3. Schedule it. Windows Task Scheduler handles this. I run two jobs: one at a fixed hour each night, and one that watches the folder every sixty seconds and fires when a new upload has finished landing. The second is the one that matters — clips uploaded in the afternoon are an album by dinner.
A Word for Whoever Holds the Camera
The single biggest influence on the output is not a setting. It is how the footage gets shot. Reducing what the system has to discard beats any amount of tuning downstream.
- Shoot in bursts of ten to thirty seconds. Several short moments are far more useful than one long take
- Shoot landscape, in good light. Portrait and dim footage get filtered out at the quality check
- Start recording, wait a beat, then move. It spares you the opening lurch
- The audio is part of the decision. Laughter or conversation is itself a reason to keep a clip
Two Things Worth Knowing in Advance
Beyond the traps already baked into the prompt, two lessons from actually running this.
Re-editing the same day and theme fails silently. The duplicate protection keys on “date plus theme,” so if you rework a day’s footage the new version matches an existing key and is quietly skipped. You have to rename the old record first. Nothing warns you; the video simply never appears.
Things get made and then stall before publishing. I once had three highlights pass every quality check and sit there, finished and unpublished, for days. So I built a small status page that shows one thing: what has been made but not yet uploaded. Automation fails quietly by nature, which makes the thing that tells you it stopped roughly as important as the automation itself.
The Point
What this bought me was not more footage. It was the elimination of editing as an activity. The job I used to postpone for months now finishes while the trip is still happening.
The pattern generalizes past video. If you have a chore where the same kind of judgment gets made over and over and a human is making it by hand, the move is to hand off only the judgment and leave the heavy work to tools that already exist. I cannot write the code. I could describe what I wanted. These days that turns out to be the part that matters.