viralvideogen (storylab)
the_problem
Producing emotional storytelling video for TikTok with character consistency and retention is repetitive, manual and expensive: every prompt mistake is a paid call wasted, and a character whose face changes between scenes destroys the whole video.
what_it_does
- Video intelligence: scene detection, keyframe extraction, audio transcription and visual analysis, selecting representative frames instead of sending every frame to a model.
- Story intelligence: narrative structure, character archetypes, an original story rather than a renamed character with translated dialogue, and a retention strategy built on open loops and emotional escalation.
- A character bible and a visual bible fixing immutable traits per recurring character and the environment’s visual language.
- A deliberate split between the image prompt, which defines visual state, and the animation prompt, which defines what changes over time. That separation is what makes character consistency controllable.
- A publishing gate that measures the final video, reads the attested environment, and refuses when something blocks. It never publishes on its own.
- Thirteen versioned JSON Schema files, one per persisted shape, as machine-readable contracts.
stack
other
Python 3.11+ · Typer · Pydantic 2 · OpenCV · faster-whisper · Anthropic SDK · pytest · GitHub Spec Kit
measured
- Specifications in two days
- 14specs/, 38 commits 2026-08-16 to 2026-08-18
- Machine-readable contracts
- 13schemas/, one JSON Schema per persisted shape
- Lint gate
- 9.9 / 10pylint fail-under threshold
how_it_was_built
Spec-driven, fourteen specifications in two days. The architecture has one clear rule: the pipeline layer orchestrates, one module per CLI command following read-check-write; the domain packages beside it make no I/O decisions; models is the only place a persisted shape is declared; and every persisted shape has a contract in schemas.
There is no `generate` command that runs the whole chain. Three stages make paid model calls, and the operational decision is that stories are written by hand in chat and enter through a promote step, the unpaid path.
`record` does not accept a declared result as truth. A video job reported as completed against a local file is decoded before being believed: a file that is not a readable video demotes the job to missing, and a file that is has its measured duration recorded, replacing the declared one. The reason is on the record: the repository’s own first render plan logged a job as completed against a PNG, and an exists-check believed it. Anything with nothing local to measure is stored as reported, because inventing a measurement would be the same failure in the opposite direction.
`assemble` sums measured duration, not requested duration. A gap over one second becomes a warning, because a provider returning five-second clips for eight-second requests passes every check in the pipeline and produces a video under the minimum length.
Deterministic, LLM-free commands never modify their source file. They write a new file alongside it. Storage is split by nature: code, config, schemas, tests and light manifests in git; video, image, frames, audio and renders synced outside it.
known_limitations
- No end-to-end command exists, and that is deliberate rather than missing: three stages cost money per call, so the chain is driven stage by stage.
- Publishing is never automatic. The final post is manual, on a phone. The gate reports ready or blocked, and a human acts on it.
- A remote result with no local artifact is stored as reported, not as measured. The distinction is kept in the data rather than smoothed over.
- Not deployed anywhere: it is a local CLI, run by its author.
tracked coding time
104 hrs 37 mins Source: WakaTime · tracked 2026-03-17 to current