Fixing some filter paralleism
This commit is contained in:
+51
-14
@@ -1256,6 +1256,16 @@ def cmd_validate(project_path: Path, verbose: bool) -> int:
|
||||
# =============================================================================
|
||||
|
||||
|
||||
def _resolve_process_cache(project_path: Path, config) -> Optional[Path]:
|
||||
"""Return per-project cache dir on external disk, or None if not configured."""
|
||||
if not (config and config.process_cache):
|
||||
return None
|
||||
p = Path(config.process_cache)
|
||||
if not p.is_absolute():
|
||||
p = (project_path / p).resolve()
|
||||
return p / project_path.name
|
||||
|
||||
|
||||
def cmd_preprocess(
|
||||
project_path: Path,
|
||||
verbose: bool,
|
||||
@@ -1280,13 +1290,24 @@ def cmd_preprocess(
|
||||
|
||||
config = parse_project_config(project_path)
|
||||
|
||||
# Narration directory — always media/narration/
|
||||
# Narration directory — source files always in project media/narration/
|
||||
narration_dir = project_path / "media" / "narration"
|
||||
narration_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
raw_dir = narration_dir / "raw_mov"
|
||||
compressed_dir = narration_dir / "raw_mp4"
|
||||
processed_dir = narration_dir / "processed"
|
||||
|
||||
# process_cache: write processed outputs to external disk to save laptop space
|
||||
cache_root = _resolve_process_cache(project_path, config)
|
||||
if cache_root:
|
||||
cache_narration_dir = cache_root / "narration"
|
||||
cache_narration_dir.mkdir(parents=True, exist_ok=True)
|
||||
(cache_narration_dir / "processed").mkdir(parents=True, exist_ok=True)
|
||||
print(f" Using process cache: {cache_root}")
|
||||
else:
|
||||
cache_narration_dir = None
|
||||
|
||||
processed_dir = (cache_narration_dir or narration_dir) / "processed"
|
||||
processed_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Resolve intermediate directory
|
||||
@@ -1362,7 +1383,10 @@ def cmd_preprocess(
|
||||
output_file = f"{_subdir}/processed/{segment_id}_processed.mov"
|
||||
else:
|
||||
output_file = f"processed/{segment_id}_processed.mov"
|
||||
output_path = narration_dir / output_file
|
||||
# When process_cache is set, output goes to the cache dir; narration.json
|
||||
# still records the relative path so stitch (also using cache) can find it.
|
||||
output_base = cache_narration_dir or narration_dir
|
||||
output_path = output_base / output_file
|
||||
|
||||
if output_path.exists() and not force:
|
||||
print(f" {segment_id}: output exists, skipping (use --force to reprocess)")
|
||||
@@ -1420,7 +1444,7 @@ def cmd_preprocess(
|
||||
def process_segment_task(task):
|
||||
seg_id, seg_source = task
|
||||
preprocess_video(
|
||||
narration_dir,
|
||||
cache_narration_dir or narration_dir,
|
||||
seg_id,
|
||||
seg_source,
|
||||
verbose=False,
|
||||
@@ -1439,7 +1463,7 @@ def cmd_preprocess(
|
||||
seg_id, seg_source = future.result()
|
||||
completed += 1
|
||||
print(f" Completed: {seg_id} ({completed}/{len(segments_to_process)})")
|
||||
output_path = narration_dir / seg_source.output_file
|
||||
output_path = (cache_narration_dir or narration_dir) / seg_source.output_file
|
||||
if output_path.exists():
|
||||
successfully_processed.append((seg_id, seg_source))
|
||||
else:
|
||||
@@ -1449,7 +1473,7 @@ def cmd_preprocess(
|
||||
print(f" Output: {segment_source.output_file}")
|
||||
print(f" Filters: {len(segment_source.filter)} step(s)")
|
||||
preprocess_video(
|
||||
narration_dir,
|
||||
cache_narration_dir or narration_dir,
|
||||
segment_id,
|
||||
segment_source,
|
||||
verbose,
|
||||
@@ -1457,7 +1481,7 @@ def cmd_preprocess(
|
||||
gnommo_scratch,
|
||||
res=res,
|
||||
)
|
||||
output_path = narration_dir / segment_source.output_file
|
||||
output_path = (cache_narration_dir or narration_dir) / segment_source.output_file
|
||||
if output_path.exists():
|
||||
successfully_processed.append((segment_id, segment_source))
|
||||
|
||||
@@ -2039,15 +2063,26 @@ def cmd_stitch(
|
||||
else:
|
||||
videos_dir = project_path / "media" / "videos"
|
||||
|
||||
# When process_cache is set, redirect processed segment reads and combined output
|
||||
cache_root = _resolve_process_cache(project_path, config)
|
||||
if cache_root:
|
||||
narration_dir = cache_root / "narration"
|
||||
narration_dir.mkdir(parents=True, exist_ok=True)
|
||||
videos_dir_out = cache_root / "videos"
|
||||
videos_dir_out.mkdir(parents=True, exist_ok=True)
|
||||
print(f" Using process cache: {cache_root}")
|
||||
else:
|
||||
videos_dir_out = videos_dir
|
||||
|
||||
# Use downscaled dirs for non-full res
|
||||
if res != "full":
|
||||
cfg = RES_CONFIGS[res]
|
||||
narration_dir = ensure_downscaled_files_exist(
|
||||
narration_dir, res, force=False, verbose=verbose
|
||||
)
|
||||
videos_dir = videos_dir / cfg[2]
|
||||
videos_dir.mkdir(parents=True, exist_ok=True)
|
||||
print(f" Using {res} dirs: {narration_dir}, {videos_dir}")
|
||||
videos_dir_out = videos_dir_out / cfg[2]
|
||||
videos_dir_out.mkdir(parents=True, exist_ok=True)
|
||||
print(f" Using {res} dirs: {narration_dir}, {videos_dir_out}")
|
||||
|
||||
# Get segment IDs in sorted order
|
||||
segment_ids = sorted(narration.keys())
|
||||
@@ -2062,7 +2097,7 @@ def cmd_stitch(
|
||||
trim_str = f" ({trim_info})" if trim_info else ""
|
||||
print(f" - {segment_id}{trim_str}")
|
||||
|
||||
stitch_output = videos_dir / "narration_combined.mov"
|
||||
stitch_output = videos_dir_out / "narration_combined.mov"
|
||||
|
||||
if stitch_output.exists() and not force:
|
||||
print(f"\n Combined narration exists: {stitch_output.name}")
|
||||
@@ -2085,12 +2120,14 @@ def cmd_stitch(
|
||||
default_end_trim=config.default_end_trim if config else 0.0,
|
||||
loudnorm_config=_loudnorm_cfg,
|
||||
)
|
||||
# Run import videos again, because at this point narration_combined might have been created.
|
||||
_import_videos(videos_dir, config, verbose)
|
||||
# Run import videos again to update duration metadata (skip when using cache
|
||||
# since narration_combined.mov lives on the external disk, not in videos_dir).
|
||||
if not cache_root:
|
||||
_import_videos(videos_dir_out, config, verbose)
|
||||
|
||||
# Always update the MAIN videos.json (parent of subdir when using low/tiny res)
|
||||
# Downscaled dirs only affect file paths, not JSON metadata updates
|
||||
main_videos_dir = videos_dir.parent if res != "full" else videos_dir
|
||||
main_videos_dir = videos_dir_out.parent if (res != "full" and not cache_root) else videos_dir
|
||||
videos_json_path = main_videos_dir / "videos.json"
|
||||
if True: # Always update JSON regardless of proxy mode
|
||||
existing_videos: dict = {}
|
||||
|
||||
Reference in New Issue
Block a user