Commti prior to change to video tag below / above layering
This commit is contained in:
+31
-23
@@ -5,6 +5,8 @@ import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from .errors import RenderError
|
||||
from .parser import _read_json
|
||||
from .preprocessor import _resolve_auto_channel
|
||||
from .models import (
|
||||
AudioEvent,
|
||||
CameraEvent,
|
||||
@@ -179,22 +181,23 @@ def _resolve_video_path(
|
||||
base_dir = videos_dir
|
||||
|
||||
if video_source.output_file:
|
||||
video_path = base_dir / video_source.output_file
|
||||
# Check with cache fallback
|
||||
if project_path:
|
||||
resolved, _ = resolve_with_cache(video_path, project_path)
|
||||
if resolved.exists():
|
||||
return resolved
|
||||
elif video_path.exists():
|
||||
return video_path
|
||||
# Check for WebM variant (preprocessing outputs compressed WebM instead of ProRes)
|
||||
webm_path = video_path.with_suffix(".mov")
|
||||
if project_path:
|
||||
resolved, _ = resolve_with_cache(webm_path, project_path)
|
||||
if resolved.exists():
|
||||
return resolved
|
||||
elif webm_path.exists():
|
||||
return webm_path
|
||||
for candidate_dir in [base_dir, base_dir.parent]:
|
||||
video_path = candidate_dir / video_source.output_file
|
||||
# Check with cache fallback
|
||||
if project_path:
|
||||
resolved, _ = resolve_with_cache(video_path, project_path)
|
||||
if resolved.exists():
|
||||
return resolved
|
||||
elif video_path.exists():
|
||||
return video_path
|
||||
# Check for WebM variant (preprocessing outputs compressed WebM instead of ProRes)
|
||||
webm_path = video_path.with_suffix(".mov")
|
||||
if project_path:
|
||||
resolved, _ = resolve_with_cache(webm_path, project_path)
|
||||
if resolved.exists():
|
||||
return resolved
|
||||
elif webm_path.exists():
|
||||
return webm_path
|
||||
|
||||
# Fall back to source_file with cache fallback
|
||||
source_path = base_dir / video_source.source_file
|
||||
@@ -272,7 +275,6 @@ def build_ffmpeg_command(plan: RenderPlan, output_path: Path) -> list[str]:
|
||||
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
|
||||
has_background = bool(bg_handle)
|
||||
bg_idx = None
|
||||
@@ -282,7 +284,7 @@ def build_ffmpeg_command(plan: RenderPlan, output_path: Path) -> list[str]:
|
||||
videos_json_bg = shared_assets_dir / "videos.json"
|
||||
if not videos_json_bg.exists():
|
||||
raise RenderError(f"shared_assets/videos.json not found (needed for background handle '{bg_handle}')")
|
||||
bg_videos = _json.loads(videos_json_bg.read_text())
|
||||
bg_videos = _read_json(videos_json_bg)
|
||||
if bg_handle not in bg_videos:
|
||||
raise RenderError(f"Background handle '{bg_handle}' not found in shared_assets/videos.json")
|
||||
bg_path = shared_assets_dir / bg_videos[bg_handle]["source_file"]
|
||||
@@ -719,7 +721,8 @@ def build_filter_complex(
|
||||
)
|
||||
else:
|
||||
filters.append(
|
||||
f"[{bg_idx}:v]scale={width}:{height}:force_original_aspect_ratio=increase,"
|
||||
f"[{bg_idx}:v]fps={plan.config.fps},"
|
||||
f"scale={width}:{height}:force_original_aspect_ratio=increase,"
|
||||
f"crop={width}:{height}[bg]"
|
||||
)
|
||||
else:
|
||||
@@ -742,9 +745,12 @@ def build_filter_complex(
|
||||
|
||||
if not plan.narration_pauses:
|
||||
# Simple case: no pauses, continuous overlay
|
||||
# fps+setpts normalise the source to a constant frame rate and reset
|
||||
# the timeline to 0 so the video stays locked to the audio track.
|
||||
video_label = f"av{i}"
|
||||
filters.append(
|
||||
f"[{input_idx}:v]format=yuva444p10le,"
|
||||
f"[{input_idx}:v]fps={plan.config.fps},setpts=PTS-STARTPTS,"
|
||||
f"format=yuva444p10le,"
|
||||
f"scale={zoomed_width}:{zoomed_height}:force_original_aspect_ratio=increase,"
|
||||
f"crop={cut_width}:{cut_height}:(iw-{cut_width})/2:(ih-{cut_height})/2,"
|
||||
f"format=rgba[{video_label}]"
|
||||
@@ -942,9 +948,11 @@ def build_filter_complex(
|
||||
narration_volume = 1.0
|
||||
if plan.narration_videos:
|
||||
_, first_video_source, _ = plan.narration_videos[0]
|
||||
channel_filter = _build_audio_channel_filter(
|
||||
first_video_source.use_audio_channels
|
||||
)
|
||||
use_channels = first_video_source.use_audio_channels
|
||||
if use_channels == "auto":
|
||||
narration_path = _resolve_video_path(videos_dir, first_video_source, shared_assets_dir, project_path)
|
||||
use_channels = _resolve_auto_channel(narration_path)
|
||||
channel_filter = _build_audio_channel_filter(use_channels)
|
||||
narration_volume = first_video_source.volume
|
||||
|
||||
# Build volume filter if not 1.0
|
||||
|
||||
Reference in New Issue
Block a user