# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## What This Project Does Amazon PVD Mezzanine Encoder — a Windows tool that creates Amazon-compatible mezzanine files from video sources (ProRes, Blu-ray, DVD, etc.). Produces three output files: 1. `*_PVD.mp4` — H.264 with German stereo AAC audio 2. `*_DEU_AUDIO_PCM.mov` — All German audio tracks as uncompressed PCM 3. `*_OV_AUDIO_PCM.mov` — All non-German audio tracks as uncompressed PCM (if present) ## Running ```powershell # Drag-and-drop or batch launcher (recommended for end users) .\create_mezzanine.bat "D:\path\to\video.mov" # Direct Python python .\pvd_mezzanine.py "D:\path\to\video.mov" # CLI-only mode (no GUI) python .\pvd_mezzanine.py --cli "D:\path\to\video.mov" ``` No build step. Pure Python 3.10+ with no third-party dependencies. Requires FFmpeg/FFprobe (auto-detected from PATH, `C:\Tools\FFMPEG`, `C:\Software`, or configured in `config.ini`). ## Architecture All logic lives in `pvd_mezzanine.py`. The data flows in one direction: ``` User Input → config.ini → FFprobe (probe_metadata) → Analysis (analyze_video / build_audio_roles) → JobPlan (build_plan) → FFmpeg commands → run_plan → Output files ``` ### Key Dataclasses **`AudioRole`** — One audio track: stream index, language, channels, codec. `is_german` checks `{DEU, GER}`. `effective_channels` prefers filename-token over FFprobe-detected channels. **`VideoProfile`** — Video analysis result: resolution, FPS, SD/HD, NTSC/PAL, interlacing, colorspace metadata, conversion flags. **`JobPlan`** — Complete encoding spec: input/output paths, selected audio roles for MP4 and MOVs, video profile, generated FFmpeg command strings. ### Module Sections (by line range) | Lines | Responsibility | |-------|----------------| | 27–180 | Config loading (`config.ini`), FFmpeg path detection, output directory resolution | | 301–431 | `probe_metadata()`, `analyze_video()`, `build_audio_roles()`, `parse_audio_tokens()` | | 449–625 | `build_plan()` orchestration, `build_pvd_mp4_command()`, `build_audio_mov_command()`, `build_video_filters()` | | 628–691 | `run_command()` (subprocess streaming), `run_plan()`, `run_cli()` | | 693–871 | `MezzanineApp` — Tkinter GUI with threaded encoding | | 873–935 | `main()`, `run_ui()`, `run_no_tk_fallback()`, `choose_input_with_powershell()` | ### Audio Detection Logic Filename tokens take priority over FFprobe stream metadata. Format: 3-letter language code + channel spec — e.g., `Film_DEU51_ENG20.mov` → Stream 0 = German 5.1, Stream 1 = English 2.0. Token order maps to stream order. MP4 audio selection: prefer German stereo → any German track (FFmpeg downmixes) → error if none found. ### Video Processing Rules - SD (height ≤ 576): 8M bitrate, H.264 level 3.1 - HD (height > 576): 30M bitrate, H.264 level 4.1 - NTSC: height ≤ 480 and FPS ≥ 29 - Colorspace filter only applied when source has complete metadata (primaries + transfer + space); otherwise skipped to prevent FFmpeg abort - Deinterlace (`bwdif`) applied if interlaced source detected - Forced subtitles burned if `_forced.srt` exists next to the input file ### UI Fallback Chain 1. Tkinter GUI (full interface with progress log) 2. PowerShell native file dialog + console output (if Tkinter unavailable) 3. CLI mode with `--cli` flag or file argument ### Output Naming Title is derived from: Blu-ray folder name (4 levels above `BDMV`) → filename stem with audio tokens stripped → `UNKNOWN_TITLE`. ``` Titel_DEU20_PVD.mp4 Titel_DEU_AUDIO_PCM.mov Titel_OV_AUDIO_PCM.mov ``` ## Configuration `config.ini` is auto-created on first run. Key settings: ```ini [ffmpeg] search_dirs = C:\Tools\FFMPEG, C:\Software [output] preferred_dirs = F:\VOD, H:\VOD # first existing dir is used [video] hd_bitrate = 30M sd_bitrate = 8M preset = slow tune = film [audio] mp4_bitrate = 256k pcm_codec = pcm_s24le sample_rate = 48000 ``` ## Language Code comments, UI strings, and log messages are in German — maintain this convention when adding new messages or comments.