From 757d966803dae3b6c607498734cf886a44a293a4 Mon Sep 17 00:00:00 2001 From: jenstandstad Date: Sun, 15 Mar 2026 11:13:09 +0100 Subject: [PATCH] Bugfixes --- gnommo/cli.py | 7 ++++--- gnommo/models.py | 2 ++ gnommo/parser.py | 8 ++++++-- gnommo/preprocessor.py | 6 ++++++ gnommo/renderer.py | 2 ++ 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/gnommo/cli.py b/gnommo/cli.py index 334067f..06e99dc 100644 --- a/gnommo/cli.py +++ b/gnommo/cli.py @@ -911,14 +911,15 @@ def cmd_stitch( narration, stitch_output, verbose=verbose, + default_end_trim=config.default_end_trim if config else 0.0, ) # Run import videos again, because at this point narration_combined might have been created. _import_videos(videos_dir, config, verbose) - # Always update the MAIN videos.json (parent directory when in proxy mode) - # Proxy mode only affects file paths, not JSON metadata updates - main_videos_dir = videos_dir.parent if proxy else videos_dir + # 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 videos_json_path = main_videos_dir / "videos.json" if True: # Always update JSON regardless of proxy mode existing_videos: dict = {} diff --git a/gnommo/models.py b/gnommo/models.py index a5f9375..e6d24fe 100644 --- a/gnommo/models.py +++ b/gnommo/models.py @@ -56,6 +56,8 @@ class ProjectConfig: gnommo_scratch: Optional[ str ] = None # directory for intermediate files (e.g., external SSD) + default_begin: float = 0.0 # Trim this many seconds from the start of each segment (if no explicit begin/skip) + default_end_trim: float = 0.0 # Trim this many seconds from the end of each segment (if no explicit end/take) # Outro sequence - plays after narration ends (not marker-triggered) outro: list[str] = field( default_factory=list diff --git a/gnommo/parser.py b/gnommo/parser.py index 63abcc5..0343443 100644 --- a/gnommo/parser.py +++ b/gnommo/parser.py @@ -199,6 +199,8 @@ def parse_project_config(project_path: Path) -> ProjectConfig: audio_source=data.get("audio_source"), main_video=data.get("main_video"), gnommo_scratch=data.get("gnommo_scratch"), + default_begin=float(data.get("default_begin", 0.0)), + default_end_trim=float(data.get("default_end_trim", 0.0)), outro=data.get("outro", []), description=data.get("description", ""), footer=data.get("footer", ""), @@ -518,10 +520,12 @@ def parse_narration( filter_list = filter_value # Handle skip/take - can use begin/end as user-friendly alternatives - skip = segment_data.get("skip", 0.0) + # Fall back to project-level defaults if no explicit value is set + default_begin = config.default_begin if config else 0.0 + skip = segment_data.get("skip", default_begin) take = segment_data.get("take") - # Convert begin/end to skip/take if provided + # Explicit begin/end always override defaults if "begin" in segment_data and segment_data["begin"]: skip = parse_timestamp(segment_data["begin"]) if "end" in segment_data and segment_data["end"]: diff --git a/gnommo/preprocessor.py b/gnommo/preprocessor.py index 96abd0f..54b6c6c 100644 --- a/gnommo/preprocessor.py +++ b/gnommo/preprocessor.py @@ -1951,6 +1951,7 @@ def stitch_narration_segments( videos: dict[str, VideoSource], output_path: Path, verbose: bool = False, + default_end_trim: float = 0.0, ) -> Path: """ Stitch multiple narration video segments into a single file. @@ -1965,6 +1966,7 @@ def stitch_narration_segments( videos: Dict of video ID -> VideoSource from videos.json output_path: Path for the concatenated output file verbose: Enable verbose output + default_end_trim: Seconds to trim from the end when no explicit end/take is set Returns: Path to the stitched video file. @@ -2003,6 +2005,10 @@ def stitch_narration_segments( skip = video_source.skip or 0.0 take = video_source.take + # Apply default end trim if no explicit take/end was set + if take is None and default_end_trim > 0: + take = max(0.0, full_duration - skip - default_end_trim) + # Calculate effective duration if take is not None: effective_duration = min(take, full_duration - skip) diff --git a/gnommo/renderer.py b/gnommo/renderer.py index 31e25b6..52c14d4 100644 --- a/gnommo/renderer.py +++ b/gnommo/renderer.py @@ -269,6 +269,8 @@ def build_ffmpeg_command(plan: RenderPlan, output_path: Path) -> list[str]: always_visible_inputs.append(input_idx) input_idx += 1 + from .cache import resolve_with_cache + # Input: background — resolved via handle in shared_assets/videos.json import json as _json bg_handle = plan.config.background