---
name: video_render_qa
description: Run a QA pass on a finished video render before it ships: export specs against the order, measured loudness and true peak against the delivery target, on-screen text against safe zones and phone player overlays, captions checked against the final audio, and pacing defects (black or frozen frames, dead pauses, flash cuts, filler), ending in a fix list ranked by viewer impact and a ship, re-export, or re-edit verdict. Runs on any platform with ffmpeg and ffprobe. Use when a render is done and needs checking before upload, delivery, or handoff, or when a shipped video came back with a quality complaint.
---

# Video Render QA

## Purpose

Catch the defects a finished render hides until a viewer or a delivery system finds them: a black opening, captions written for a cut that changed, text sitting under a phone app button, audio mastered for the wrong target. The pass mixes machine measurements (ffmpeg and ffprobe do the counting) with a human watch (only a person can tell an intentional black frame from a broken one), and it ends in one ranked fix list, not a pile of notes.

This skill checks a render of any length and any origin: edited, generated, recorded, or animated. For checking raw generated clips for visual artifacts before editing, use generated-media-qa instead. For basic deliverable verification only (container, codec, duration, resolution, audio presence), the older video-qc skill covers that narrower job.

## Workflow

1. **Pin the order before touching the file.** Write down the delivery target and its specs: platform or buyer, width, height, frame rate, codec pair, loudness target, caption file and format, ordered duration. No order, no verdict: a render can only fail against something. `references/targets.md` holds the common loudness targets and the spec list to compare.
2. **Run the machine pass.** Run `python3 scripts/render_qa.py <render>` from this skill folder. It prints the ffprobe specs, integrated loudness and true peak from loudnorm, and timestamped black, freeze and silence intervals plus a hard cut list. Save the output, the report quotes it.
3. **Judge specs and loudness.** Compare every spec line to the order. Judge loudness as a gap: measured integrated loudness against the target in `references/targets.md`, true peak against its ceiling. Remember the direction of platform normalization: loud uploads get turned down, quiet ones stay quiet.
4. **Watch the render once at full speed, sound on.** Mark what a viewer hits: a slow or broken opening, a pause that reads as a stall, a cut so fast the shot never lands, a caption covering a face. Cross-check your marks against the machine timestamps. A black interval at a chapter break or an ad bumper can be intentional. A black first frame almost never is.
5. **Check text against safe zones.** Work `references/check-sheet.md`: pull a still at every title card, lower third, price and end card, and test it against the action safe and title safe boxes for widescreen, or the phone player overlay guide for vertical. Text under a platform button or outside title safe is a fix, with the timestamp named.
6. **Check captions against the final audio.** Run `python3 scripts/caption_check.py <captions.srt>` for line length, reading speed, duration and gaps. Then compare wording against the shipped audio, not the script: transcribe the render audio or spot check the opening, every name, number and price by ear. Late edits change words after caption files are written, and a caption for a deleted scene is a common find. Check sync on five spread-out cues and placement against on-screen text.
7. **Run the pacing pass.** From the silence list, the cut list and the transcript: dead pauses over about a second in speech content, filler words and restarted sentences that survived the edit, and flash cuts (shots under half a second that are not a deliberate montage beat). Each is a judgment call. Name the timestamp and say why it hurts, or leave it out.
8. **Rank the fix list by viewer impact and give the verdict.** Order: things that make a viewer leave or misunderstand first (broken opening, missing or wrong audio, unreadable captions), delivery blockers next (spec mismatches a receiving system rejects), polish last. Verdict is one of ship, re-export (right edit, wrong file), or re-edit (the edit itself needs work). State the clean checks too, a report that only lists faults cannot be trusted.
9. **Re-run after fixes.** A fix claim is checked, not believed: run both scripts on the new render and confirm every flagged timestamp cleared before the verdict changes.

## Output Contract

Every QA pass returns:

- The order it was judged against (target, specs, loudness target, caption source)
- The machine report lines: specs, loudness and true peak with the gap to target, black, freeze, silence and cut timestamps
- Caption results: form faults per cue, wording faults against the final audio with timestamps, sync result
- Safe zone results per text moment checked, with timestamps
- A fix list ranked by viewer impact, each item carrying a timestamp and the concrete fix
- One verdict: ship, re-export, or re-edit, with the reason in one line

## Operating Rules

- Measurements are evidence, verdicts are judgment. A detector flag is a prompt to look at that timestamp, never a fault on its own. Intentional black frames, dramatic pauses and montage cuts exist. The report says what was seen at the timestamp and lets the intent call be explicit.
- Captions are always checked against the final rendered audio. Checking them against the script certifies a version of the video that may no longer exist.
- Loudness numbers come from the loudnorm measurement in the report, targets from `references/targets.md` or the buyer spec sheet. Never quote a target from memory when the sheet is in the skill.
- No platform publishes an exact pixel map for its phone player overlays. The vertical guide in the check sheet is a conservative working rule. The in-app preview of the exact file is the final word for vertical work.
- The FCC caption standards are accuracy, synchronicity, completeness and placement. The numeric caption limits in the check sheet are industry working defaults. Present them as defaults, never as law.
- QA does not silently fix. The pass reports and ranks. Fixes happen in the edit or the mix, then the new render gets its own pass.
- One flawed render is worked end to end in `references/worked-example.md`, with real tool output: a black frozen opening, two seconds of dead air, loudness 8.9 LU under target, two broken caption cues, and the ranked fix list they produced.
- Bulky detail lives in `references/`: `targets.md` (loudness targets and export spec list), `check-sheet.md` (safe zone boxes with worked pixel sizes, phone player overlay guide, caption form and wording checks), `worked-example.md` (a full pass on a flawed render). Working tools live in `scripts/`: `render_qa.py` (specs, loudness, black, freeze, silence, cuts) and `caption_check.py` (SRT form checks). Both were run against a real test render before this skill shipped.
