---
name: video_podcast_production
description: Produce a full-length video podcast episode from recorded camera files: compose solo, split-screen, picture-in-picture, and screen-share layouts, mix and loudness-normalize the audio, burn or attach subtitles, build multilingual versions with dubbed audio and translated subtitle tracks, and export platform-ready masters at 1080p and 4K. Use when asked to build, assemble, edit, subtitle, localize, or export a video podcast episode. For audio-only shows use podcast_production, for short vertical clips use podcast_video_clips.
---

# Video Podcast Production

## Purpose

Take the recorded camera and audio files of one episode and ship a finished
video episode: composed picture, clean mixed audio at a steady loudness,
subtitles in the right form for each platform, and exports that pass upload
checks the first time. The craft here is the build. Show format, guest
booking, and promotion belong to other skills.

Scope boundaries:

- Audio-only production, RSS feeds, show format design: `podcast_production`.
- Cutting Shorts, Reels, or TikTok clips from the episode: `podcast_video_clips`.
- Caption accuracy standards and SDH conventions: `caption_accessibility`.
- Translation and dubbing craft itself: `video_localization_dubbing`. This
  skill takes finished translated subtitle files and dubbed audio tracks and
  turns them into correct per-language episode files.

## Workflow

### 1. Inventory and sync check

List what actually arrived before building anything: one video file per
camera, separate audio if it was recorded apart, screen capture if any,
intro and outro assets, the subtitle file, and the episode metadata (title,
guest names and spellings, chapter plan).

Check three things on every camera file with `ffprobe`:

```bash
ffprobe -v error -show_entries stream=codec_type,width,height,r_frame_rate,channels,sample_rate -of default=noprint_wrappers=1 ep12-host.mp4
```

- Resolution and frame rate match across cameras. Mixed frame rates get
  conformed to the episode rate before composition, never during export.
- Each file starts close enough that a clap, a countdown, or a shared
  timestamp can sync them. If sync drift grows over the episode (two clocks
  running at slightly different speeds), fix it with a small `atempo` or
  `setpts` correction on the drifting track and note the correction in the
  build sheet. Drift left alone reads as an echo by minute twenty.
- Audio is the speaker's own mic on each file, or one file carries the full
  mix. This decides `--audio-mode` in step 3. Guessing wrong doubles voices.

Output: a one-page build sheet per episode, from
`templates/build-sheet.md`, with the sync corrections and asset list filled in.

### 2. Pick the composition template

Four layouts cover nearly every episode. Full geometry, margins, and
lower-third placement for each: `references/composition-templates.md`.

- **solo**: one speaker full frame. Default for monologues and narration.
- **split**: host and guest side by side, equal halves. Default for remote
  two-person interviews where both faces matter the whole time.
- **pip**: active speaker full frame, the other speaker in a corner box.
  Use when the edit cuts between speakers, or keep it static for a calmer show.
- **screen**: screen capture full frame, speaker in a corner box. For demos,
  walkthroughs, and slide segments.

Composition rules that hold for every layout:

- Keep faces and lower thirds inside the graphics-safe area: at least 5
  percent margin at every edge (EBU R 095 for 16:9). Corner boxes sit inside
  that margin, not on the frame edge.
- Lower thirds appear when a speaker is first named, hold long enough to
  read twice, and use the guest spelling from the build sheet. Never let a
  lower third and a burned subtitle occupy the same band at the same time.
- Match eye lines in split view: scale or crop so both faces sit at a
  similar height and size. A guest who looks half the host's size reads as
  less important, whatever the conversation says.
- Cut on speaker change in pip layouts, not mid-sentence. Reaction shots
  are fine, jump cuts on every breath are not.

### 3. Build the episode

`bin/build_episode.py` composes the picture, mixes the audio, applies a
two-pass loudness normalization to the final mix, and encodes the master.
It writes an intermediate first, measures it, then applies a linear gain
with the video copied untouched, so the loudness pass costs no picture quality.

```bash
# Split-screen interview, 4K master, English subtitles burned for the
# hard-of-hearing audience copy
python3 bin/build_episode.py \
  --host ep12-host.mp4 --guest ep12-guest.mp4 \
  --layout split --preset 2160p --audio-mode mix \
  --subs ep12.en.srt --subs-lang en \
  --out ep12-master-2160p.mp4

# Solo episode, 1080p, no burned subtitles (sidecar ships separately)
python3 bin/build_episode.py \
  --host ep13-host.mp4 --layout solo --preset 1080p \
  --audio-mode host --out ep13-master-1080p.mp4
```

Build order inside the script, and why: scale and compose first, overlays
second, subtitle burn last in the video chain (any filter after the burn
softens the text), loudness on the finished mix only (normalizing each
voice separately and then mixing lands at an unpredictable level).

Loudness target: minus 14 LUFS integrated, minus 1 dBTP true peak for
video platforms. If the same mix also ships as the audio-only episode,
render that copy at minus 16 LUFS instead and say so on the build sheet.
Full export numbers per platform: `references/export-specs.md`.

### 4. Subtitles: burn, sidecar, or both

Decide per destination, not per habit:

- **Sidecar (default for YouTube and Spotify)**: ship the `.srt` beside the
  video and upload it as a timed subtitle file. Viewers can toggle it, the
  platform can index it, and a corrected file can replace it after publish
  without a re-upload. YouTube accepts basic SubRip `.srt` in plain UTF-8
  and ignores style markup in it.
- **Burned**: only for destinations with no subtitle track support, or an
  open-caption copy the show deliberately publishes. Burned text is part of
  the picture forever: a typo means a new render. The builder burns with
  libass as the final video filter; check one mid-episode frame and one
  frame over bright footage before shipping.
- **Both**: a burned open-caption copy plus the clean master with sidecar.
  Name them so they cannot be confused at upload time
  (`ep12-master-2160p.mp4` and `ep12-open-captions-2160p.mp4`).

Subtitle craft rules for the full episode: two lines maximum per cue, break
cues at phrase boundaries, keep lower-third moments clear by nudging cue
timing rather than stacking text, and spell names as the build sheet spells
them. Accuracy standards live in `caption_accessibility`; this skill owns
placement and delivery form.

### 5. Chapters and metadata

Write chapters from the finished edit's real section boundaries, never
from the plan. Validate and convert them with `bin/chapters.py`:

```bash
python3 bin/chapters.py chapters.txt --duration 2745 \
  --youtube-out chapters-youtube.txt --ffmetadata-out chapters.ffmeta
```

YouTube chapter rules the validator enforces: the first timestamp is
00:00, at least three chapters, timestamps in ascending order, and every
chapter at least 10 seconds long, including the last one measured against
the episode duration. The ffmetadata output embeds the same chapters into
the master file for players that read embedded chapters.

### 6. Multilingual versions

Build language versions from the clean master, after the primary version
is approved. Never re-edit per language.

For each language you need: a translated subtitle file timed to the same
edit, and optionally a dubbed audio track of the same duration. Then mux
with `bin/mux_language.py`:

```bash
python3 bin/mux_language.py ep12-master-2160p.mp4 \
  --dub es:ep12-dub-es.wav --subs es:ep12.es.srt --subs en:ep12.en.srt \
  --default-lang es --out ep12-multilingual.mkv
```

The MKV carries the original audio, each dub, and each subtitle track with
language tags and titles, one default audio flagged. Rules and the
per-platform fallback (separate uploads where multi-track is not
supported) are in `references/multilingual-versions.md`. Quality gate for
every language version: spot-check subtitle sync at the start, middle, and
end, confirm the dub starts at 00:00 against the same edit, and confirm no
track is mislabeled. A Spanish subtitle track tagged as Portuguese is a
real failure mode, not a nitpick.

### 7. Export and verify

Export per destination from the master, using `references/export-specs.md`.
Then run the verification pass. An episode is not done until every box
passes:

- `ffprobe` on each export: resolution, frame rate, codec (H.264 High for
  uploads), audio codec AAC at 48 kHz, duration within a second of the edit.
- Loudness re-measured on the final file: integrated within 0.5 LU of
  target, true peak at or under the ceiling.
- Container has faststart (moov atom at the front) for MP4 uploads.
- Watch the first 60 seconds, one middle minute, and the last 30 seconds
  with subtitles on, and one minute with subtitles off. Most build errors
  (bad sync, a stray lower third, a silent guest track) show up in those
  windows.
- Chapters pasted into the description pass the validator, and the first
  chapter starts at 00:00.

## Output Contract

Per episode, the build delivers:

- One clean master per agreed resolution (MP4, H.264, AAC 48 kHz,
  loudness on target, faststart set).
- Sidecar subtitle files (`.srt`, UTF-8) per language, plus any burned
  open-caption copies, named distinctly.
- A multilingual MKV when language versions were requested.
- A chapters file in YouTube description form, validated.
- The filled build sheet: assets used, sync corrections, loudness
  measurements, exports produced, and the verification results.

## Operating Rules

1. Verify facts against the platform's current help pages before an export
   run if a spec looks unfamiliar. Platform numbers change; the tables in
   `references/export-specs.md` carry their source and check date.
2. Never ship a burned-subtitle copy as the only copy. The clean master
   always exists, so a caption fix never forces a re-edit.
3. Never normalize voices separately and call the mix mastered. Loudness
   is measured and set on the final mix, in the final file.
4. Names, titles, and spellings come from the build sheet, which comes
   from the guest or the show notes. Do not guess a spelling into a lower
   third.
5. If a camera file is missing, corrupt, or out of sync beyond a simple
   correction, stop and report what is missing. A build on bad sources
   wastes more time than the report does.
6. Keep the intermediate files until the episode is published and verified
   live. Deleting them early turns every small fix into a full rebuild.
