# auto-motion: an SRT file in, a portrait video out, and no approval step

> auto-motion is a workflow template rather than a program you install: you drop a subtitle file at the repository root, let Codex read PROMPT.md, and it drives Claude Code one scene at a time until FFmpeg joins the shots into final.mp4.

**vibe-motion/auto-motion** — Automated SRT-to-motion workflow with Codex cli + Claude Code with any LLM

- Repository: https://github.com/vibe-motion/auto-motion
- Stars: 353 · Forks: 48
- Language: HTML
- License: not declared
- Published: 2026-09-18 · Updated: 2026-09-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/vibe-motion-auto-motion

## Two agents run in series with approvals switched off

The entire pipeline is one command run at the repository root, and Codex does the scheduling while Claude Code does the drawing:

```bash
codex exec \
  --cd . \
  --sandbox danger-full-access \
  --ask-for-approval never \
  - < PROMPT.md
```

`--sandbox danger-full-access` removes the filesystem sandbox and `--ask-for-approval never` removes the pause before each command, so nothing in the run waits for a human. PROMPT.md then hands Codex a fixed job list: read `transcription.srt` from the current directory, split the subtitles by meaning into consecutive scenes that fully cover the total duration, create one directory per scene (`scenes/scene-001`, `scenes/scene-002`, and so on), copy the run template and the HyperFrames skills out of `exampleFolder`, call Claude Code once per scene, then check durations and stitch the result. Each scene call goes through `exampleFolder/run-claude-ai.sh`, which fills in five values (SCENE_ID, SCENE_DURATION_SECONDS, SCENE_TEXT, OUTPUT_FILE, FULL_TRANSCRIPT_PATH) and drives Claude Code with `claude -p`.

## One scene at a time, and the run takes over an hour

Scenes are rendered strictly one after another. The notes are explicit that only one Claude Code call should run at a time and that multiple scenes must not be rendered in parallel, which makes the wall clock cost add up: the run evidence in the README is a screenshot of a multi-scene job that had been going for 1 hour and 36 minutes, with Codex waiting on Claude Code to finish writing and rendering the remaining scenes. Two invariants have to hold for the concatenation to work. Every scene must completely cover its slice of the subtitle timeline, and the sum of the scene durations should equal the total subtitle duration. If specs drift between scenes, the guidance is to transcode to a common format before joining rather than after.

## validate.sh treats 1080x1440, 30fps and silence as the contract

The fourth layer is an acceptance check that refuses anything else. `auto-test/run.sh` creates a temporary workspace, copies the test subtitles and the template in, calls Codex to execute the whole flow, and then hands the output to `auto-test/validate.sh`. That script verifies that the Claude Code stage messages are complete, that the per-scene MP4 and the final MP4 both exist, that the video is 1080x1440, that the frame rate is about 30fps, that the duration is close to the total subtitle duration, and that there is no audio track. The same specification is what the animation layer targets: every scene renders as a 1080x1440, 30fps, silent MP4 with no audio. Deliverable layout is a directory per scene plus the joined file:

```text
scenes/
  scene-001/
    scene-001.mp4
    claude-scene-001.stream.jsonl
    claude-scene-001.stderr.log
    claude-scene-001.user.log
  scene-002/
    scene-002.mp4
final.mp4
```

## Progress is a fixed stage message and three log files

Because the run is unattended, the only signal that a scene is moving is what Claude Code prints. `claude -p` is invoked in non-interactive mode and is required to emit fixed stage messages, and validate.sh fails when those messages are incomplete. Everything else lands in three files inside the scene directory: `claude-<scene>.stream.jsonl` for the raw log, `claude-<scene>.stderr.log` for errors, and `claude-<scene>.user.log` for the human-readable progress line. Those same three are the documented first stop when a scene fails, and the order matters because the stream log is where the stage messages live. `jq` is a prerequisite for working through that output.

## The repository ships its own transcription.srt at the root

The input step is a copy into a path the pipeline already occupies:

```bash
cp /path/to/transcription.srt ./transcription.srt
```

A `transcription.srt` is committed at the repository root, and a separate one lives at `auto-test/transcription.srt` for the end-to-end test. That means a run started without doing the copy does not fail; it reads the committed file and produces a perfectly valid portrait video of somebody else's subtitles. The demo embedded in the README is a 10 second excerpt from `00:00:03,000` to `00:00:13,000` of a finished render, with the input SRT fragment on one side and the generated animation with subtitles added back on the other, and the subtitle text in that sample credits one model with the script, another with writing the React code, and remotion with the render.

## Six version checks stand between you and the first scene

The prerequisites are Codex CLI, Claude Code, Node.js 22 or newer, FFmpeg and FFprobe, and `jq`, all installed and signed in, plus a network connection. The network is not optional: Claude Code searches for footage, installs dependencies, and downloads brand visual assets during a run, so a scene can stall on the network rather than on the code. The sanity check the README offers is six version commands:

```bash
codex --version
claude --version
node --version
ffmpeg -version
ffprobe --version
jq --version
```

FFprobe earns its place separately from FFmpeg because the validation layer inspects the rendered files, and Node 22 is required even though the deliverable is a video, since the animation projects are rendered from code. The finished file opens with `open final.mp4` on a Mac, and the built-in end-to-end test is `bash auto-test/run.sh`, whose artifacts land in `auto-test/.tmp/`, a path the project ignores in git.

## The directory listing never explains auto-hyper/

Compare the tree the README draws with what the repository actually holds at the top level. The listing covers PROMPT.md, `transcription.srt`, `exampleFolder/`, `auto-test/`, and `final.mp4`, and the repository also carries `auto-hyper/`, `readme-assets/`, `AGENTS.md`, `README.en.md`, and `.gitignore`. The `auto-hyper/` directory in particular appears in no section of the instructions, which is a poor sign for a folder whose name suggests it holds a second copy of the HyperFrames material also referenced under `exampleFolder/.claude/skills/`. Two other things stand out at that level. There is no license file in the tree and no license metadata on the repository, so nothing states what you may do with the output or the template. And there are no tagged releases, so the only version marker is a commit on main.

## HTML from skills, while the demo credits React and remotion

The animation layer is described as HTML work. `exampleFolder/.claude/skills/` holds the HyperFrames skills, and Claude Code is expected to write an HTML animation project based on those skills and render it to the fixed 1080x1440 spec. The demo subtitle track tells a different story about how that HTML gets drawn: it credits a qwen model with writing React code and remotion with rendering the motion graphics. Both can be true at once, since React components can compile to HTML and remotion can render from either, but nothing in the instructions resolves it, and the render command for either path is not written down. If you need to reproduce the demo exactly, that gap is where you will stop and read the skills directory yourself.

## Conclusion

auto-motion fits someone who already has both agent CLIs signed in, a subtitle file ready, and FFmpeg installed, and who accepts a pipeline that runs unattended with sandboxing disabled and no approval step. It is a template, not a package: nothing to build, no versioned releases, and a last push to main on 23 July 2026. Check three things before trusting the output. The tree carries no license file, so the terms for reuse are unstated. The repository ships its own transcription.srt at the root, so skipping the copy step animates the demo track instead of your own. And validate.sh is the only thing holding the 1080x1440, 30fps, silent contract, so run the end-to-end test before a long batch.

## FAQ

### What does auto-motion need installed before it can run?

Codex CLI and Claude Code, both installed and signed in, plus Node.js 22 or newer, FFmpeg and FFprobe, and `jq`. A network connection is required as well, because Claude Code searches for assets, installs dependencies, and downloads brand visual assets while a scene is being built.

### How does auto-motion turn an SRT file into a video?

The subtitle file is copied to the repository root as transcription.srt, then Codex reads PROMPT.md, splits the subtitles into scenes by meaning, creates one directory per scene under scenes/, calls Claude Code once per scene to produce an MP4, and joins the shots with FFmpeg into final.mp4.

### What video format does auto-motion output?

Every scene is rendered as a 1080x1440, 30fps, silent MP4 with no audio track, in portrait orientation. `auto-test/validate.sh` checks the resolution, the frame rate, the absence of an audio track, the presence of both the per-scene and final files, and that the duration is close to the total subtitle duration.

### Can auto-motion render several scenes at the same time?

No. The instructions say to run only one Claude Code call at a time and not to render multiple scenes in parallel. Each scene has to cover its slice of the subtitle timeline completely, and the scene durations together should equal the total subtitle duration.

### How do I run the auto-motion end-to-end test?

Run `bash auto-test/run.sh`. It builds a temporary workspace, copies the test subtitles and the template into it, calls Codex to execute the full flow, and then runs auto-test/validate.sh against the result. The artifacts are written to auto-test/.tmp/, which the project ignores in git.

## Sources

- [Issues](https://github.com/vibe-motion/auto-motion/issues)
- [README](https://github.com/vibe-motion/auto-motion/blob/main/README.md)
- [vibe-motion/auto-motion on GitHub](https://github.com/vibe-motion/auto-motion)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/vibe-motion-auto-motion
