safe_output_stem und get_pvd_filename nutzten unterschiedliche Logik, sodass MP4 und MOV-Dateien inkonsistente Titel hatten. Neue gemeinsame Funktion extract_title stellt sicher, dass alle drei Ausgabedateien denselben Titel ohne Unterstriche verwenden. README und CLAUDE.md aktualisiert. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4.1 KiB
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:
*_PVD.mp4— H.264 with German stereo AAC audio*_DEU_AUDIO_PCM.mov— All German audio tracks as uncompressed PCM*_OV_AUDIO_PCM.mov— All non-German audio tracks as uncompressed PCM (if present)
Running
# 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.srtexists next to the input file
UI Fallback Chain
- Tkinter GUI (full interface with progress log)
- PowerShell native file dialog + console output (if Tkinter unavailable)
- CLI mode with
--cliflag 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:
[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.