diff --git a/gnommo/cli.py b/gnommo/cli.py index cb7d269..4602d8c 100644 --- a/gnommo/cli.py +++ b/gnommo/cli.py @@ -1266,6 +1266,24 @@ def _resolve_process_cache(project_path: Path, config) -> Optional[Path]: return p / project_path.name +def _resolve_narration_combined( + project_path: Path, videos_dir: Path, config +) -> Optional[Path]: + """Find narration_combined.mov: local → GnommoCache → process_cache.""" + local = videos_dir / "narration_combined.mov" + if local.exists(): + return local + resolved, _ = resolve_with_cache(local, project_path) + if resolved.exists(): + return resolved + pc_root = _resolve_process_cache(project_path, config) + if pc_root: + pc_path = pc_root / "media" / "videos" / "narration_combined.mov" + if pc_path.exists(): + return pc_path + return None + + def cmd_preprocess( project_path: Path, verbose: bool, @@ -2501,9 +2519,13 @@ def cmd_render( # Load whisper transcription JSON # Check for narration_combined in videos.json (new workflow) or multi-segment in config (legacy) combined_path = videos_dir / "narration_combined.mov" - # Try cache fallback for combined narration - resolved_combined, _ = resolve_with_cache(combined_path, project_path) - if "narration_combined" in videos and resolved_combined.exists(): + resolved_combined = _resolve_narration_combined(project_path, videos_dir, config) + if resolved_combined and resolved_combined != combined_path: + # File lives on external disk — point the VideoSource at the absolute path so + # the renderer doesn't re-resolve it via the local (missing) videos_dir. + if "narration_combined" in videos: + videos["narration_combined"].source_file = str(resolved_combined) + if "narration_combined" in videos and resolved_combined and resolved_combined.exists(): # New workflow: narration_combined was created by 'gnommo concat' and is in videos.json # This entry has the correct volume setting from videos.json transcript_path = resolved_combined.with_suffix(".transcript.json") @@ -2789,6 +2811,12 @@ def cmd_transcribe( video_id, video_source = result video_path = videos_dir / video_source.source_file + if not video_path.exists() and video_source.source_file == "narration_combined.mov": + found = _resolve_narration_combined(project_path, videos_dir, config) + if found: + video_path = found + if not video_path.exists(): + video_path, _ = resolve_with_cache(video_path, project_path) if not video_path.exists(): print(f"Error: Video not found: {video_path}", file=sys.stderr) return 1 @@ -3551,7 +3579,7 @@ def cmd_extract_audio( # Handle --combined mode: extract from narration_combined.mov if combined: videos, videos_dir = parse_videos(project_path, config) - combined_path = videos_dir / "narration_combined.mov" + combined_path = _resolve_narration_combined(project_path, videos_dir, config) or (videos_dir / "narration_combined.mov") if not combined_path.exists(): print( @@ -3716,7 +3744,7 @@ def cmd_master( videos, videos_dir = parse_videos(project_path, config) # Find narration_combined.mov - combined_path = videos_dir / "narration_combined.mov" + combined_path = _resolve_narration_combined(project_path, videos_dir, config) or (videos_dir / "narration_combined.mov") if not combined_path.exists(): print( f"Error: narration_combined.mov not found at {combined_path}",