Adding some bugfixes to the 'all' command

This commit is contained in:
2026-05-09 12:06:15 +02:00
parent f0387f24bb
commit 831c0c4e60
3 changed files with 39 additions and 38 deletions
+13 -36
View File
@@ -50,7 +50,7 @@ Examples:
gnommo -p video1 transcode --processed --alpha-quality 0.5 More aggressive alpha compression
gnommo -p video1 transcode --processed --dry-run Preview what would be compressed
gnommo -p video1 transcode --force Re-transcode even if output already exists
gnommo -p video1 all Full pipeline: transcribe → align → render
gnommo -p video1 all Full pipeline: import → preprocess → trim → stitch → render → handoff
gnommo -p video1 render --dry-run Show FFmpeg command without running
gnommo -p video1 description Generate YouTube description file
gnommo -p video1 transcribe Narration file for timing of slides
@@ -833,7 +833,6 @@ def _import_narration_segments(narration_dir: Path, config, verbose: bool) -> No
Folder structure:
media/narration/raw_mov/ ← raw recordings from iPhone/QuickTime
media/narration/compressed/ ← H.265 copies (transcode 1st pass)
media/narration/processed/ ← chroma-keyed output (preprocess)
media/narration/narration.json
@@ -2757,7 +2756,7 @@ def cmd_all(
res: str = "full",
force: bool = False,
) -> int:
"""Run full pipeline: import → transcode → preprocess → transcode --processed → trim → stitch → render → handoff.
"""Run full pipeline: import → preprocess → trim → stitch → render → handoff.
Cascade rule: if any stage produces output, all subsequent stages are forced
to re-run (cascade_force=True), regardless of whether --force was passed.
@@ -2771,22 +2770,17 @@ def cmd_all(
# True so all downstream stages re-run unconditionally.
cascade_force = force
print(">>> Step 1/8: Import\n")
print(">>> Step 1/6: Import\n")
t0 = time.time()
result = cmd_import(project_path, cascade_force, verbose)
if result != 0:
return result
if _files_modified_since(project_path, t0, "slides.json") or _files_modified_since(
project_path, t0, "narration.json"
):
cascade_force = True
print("\n>>> Step 2/8: Transcode narration (H.265)\n")
t0 = time.time()
result = cmd_transcode(
project_path, verbose, dry_run, replace=False, crf=23, force=cascade_force
)
if result != 0:
return result
# Step 2 does not cascade: preprocess already checks its own output existence.
# A broad *_compressed.mp4 pattern would falsely match pre-existing raw_mp4/ sources.
print("\n>>> Step 3/8: Preprocess\n")
print("\n>>> Step 2/6: Preprocess\n")
t0 = time.time()
result = cmd_preprocess(project_path, verbose, dry_run, cascade_force, workers=1, res=res)
if result != 0:
@@ -2797,24 +2791,7 @@ def cmd_all(
):
cascade_force = True
print("\n>>> Step 4/8: Transcode processed (HEVC+alpha)\n")
t0 = time.time()
result = cmd_transcode(
project_path,
verbose,
dry_run,
replace=False,
crf=23,
force=cascade_force,
processed=True,
alpha_quality=1.0,
)
if result != 0:
return result
if _files_modified_since(project_path, t0, "*_processed.mov"):
cascade_force = True
print("\n>>> Step 5/8: Trim\n")
print("\n>>> Step 3/6: Trim\n")
t0 = time.time()
result = cmd_trim(project_path, verbose, force=cascade_force, threshold_db=-40.0)
if result != 0:
@@ -2823,7 +2800,7 @@ def cmd_all(
if _files_modified_since(project_path, t0, "narration.json"):
cascade_force = True
print("\n>>> Step 6/8: Stitch\n")
print("\n>>> Step 4/6: Stitch\n")
t0 = time.time()
result = cmd_stitch(project_path, verbose, cascade_force, res=res)
if result != 0:
@@ -2831,12 +2808,12 @@ def cmd_all(
if _files_modified_since(project_path, t0, "narration_combined.mov"):
cascade_force = True
print("\n>>> Step 7/8: Render\n")
print("\n>>> Step 5/6: Render\n")
result = cmd_render(project_path, verbose, dry_run, res=res, force=cascade_force)
if result != 0:
return result
print("\n>>> Step 8/8: Handoff\n")
print("\n>>> Step 6/6: Handoff\n")
return cmd_handoff(project_path, verbose, file_override=None, prod=False, res=res)
+16 -2
View File
@@ -1349,8 +1349,6 @@ def _process_chunk_to_prores4444(
"yuva444p10le", # must carry alpha
"-vendor",
"apl0", # optional; helps some NLEs tag as Apple ProRes
"-movflags",
"+faststart", # optional; makes MOV streamable
]
)
@@ -1378,6 +1376,22 @@ def _process_chunk_to_prores4444(
stderr=result.stderr,
)
# Validate the output file is a readable MOV (moov atom present).
# FFmpeg can return 0 but write a corrupt/incomplete file (e.g. moov atom
# missing) when faststart rewrite fails or disk is under pressure.
probe = subprocess.run(
["ffprobe", "-v", "error", "-show_entries", "format=duration",
"-of", "csv=p=0", str(output_path)],
capture_output=True, text=True,
)
if probe.returncode != 0 or not probe.stdout.strip():
raise PreprocessError(
f"Chunk output file is unreadable or missing moov atom: {output_path.name}",
filter_type="chunk",
command=" ".join(cmd),
stderr=probe.stderr,
)
def _process_chunk_to_webm(
input_path: Path,
Executable
+10
View File
@@ -0,0 +1,10 @@
#!/bin/sh
./gnommo.sh -p video1 all
./gnommo.sh -p video2 all
./gnommo.sh -p video3 all
./gnommo.sh -p video4 all
./gnommo.sh -p video5 all
./gnommo.sh -p video6 all