From 358b8647f59441f72e1633d5b62d775b8c42b0e6 Mon Sep 17 00:00:00 2001 From: calesthio Date: Wed, 1 Apr 2026 10:00:15 -0700 Subject: [PATCH] Talking-head pipeline: 8 new tools, Remotion TalkingHead composition, and skill rewrites New tools: face_tracker, visual_qa, eye_enhance, auto_reframe, remotion_caption_burn, showcase_card, silence_cutter. Updated audio_mixer with segmented_music operation and subtitle_gen with ASR corrections. Registered TalkingHead composition in Root.tsx. Rewrote compose/edit/scene director skills for full enhancement chain, Remotion captions, multi-clip assembly, and visual QA. Gitignore cleanup: exclude test demo-props, downloaded music, and generated images. --- .gitignore | 7 + generated_image.png | Bin 302181 -> 0 bytes pipeline_defs/talking-head.yaml | 31 +- remotion-composer/src/Root.tsx | 16 + remotion-composer/src/TalkingHead.tsx | 35 ++ .../talking-head/compose-director.md | 204 ++++++- .../pipelines/talking-head/edit-director.md | 38 +- .../pipelines/talking-head/scene-director.md | 52 +- tools/analysis/face_tracker.py | 314 ++++++++++ tools/analysis/visual_qa.py | 343 +++++++++++ tools/audio/audio_mixer.py | 152 ++++- tools/enhancement/eye_enhance.py | 578 ++++++++++++++++++ tools/subtitle/subtitle_gen.py | 51 ++ tools/video/auto_reframe.py | 537 ++++++++++++++++ tools/video/remotion_caption_burn.py | 439 +++++++++++++ tools/video/showcase_card.py | 226 +++++++ tools/video/silence_cutter.py | 481 +++++++++++++++ 17 files changed, 3467 insertions(+), 37 deletions(-) delete mode 100644 generated_image.png create mode 100644 remotion-composer/src/TalkingHead.tsx create mode 100644 tools/analysis/face_tracker.py create mode 100644 tools/analysis/visual_qa.py create mode 100644 tools/enhancement/eye_enhance.py create mode 100644 tools/video/auto_reframe.py create mode 100644 tools/video/remotion_caption_burn.py create mode 100644 tools/video/showcase_card.py create mode 100644 tools/video/silence_cutter.py diff --git a/.gitignore b/.gitignore index d98efa3..4234a0f 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,10 @@ skills-lock.json # Generated images (logo drafts — final logo lives in assets/) logo_*.png +generated_image.png + +# Downloaded music files (Pixabay, Freesound — not source code) +pixabay_music_* # OS .DS_Store @@ -57,3 +61,6 @@ remotion-composer/out/ remotion-composer/public/* # But keep demo props (shipped with the project for zero-key demos) !remotion-composer/public/demo-props/ +# Ignore test/scratch compositions in demo-props (keep only curated demos) +remotion-composer/public/demo-props/test-* +remotion-composer/public/demo-props/talking-head-* diff --git a/generated_image.png b/generated_image.png deleted file mode 100644 index 58012fbcca23550edc0b205c99a13255fe3ac42b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 302181 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%0ANEiN2O@NDV!~_eCIof9 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 diff --git a/pipeline_defs/talking-head.yaml b/pipeline_defs/talking-head.yaml index 6bc53a2..7445340 100644 --- a/pipeline_defs/talking-head.yaml +++ b/pipeline_defs/talking-head.yaml @@ -78,8 +78,12 @@ stages: required_tools: [] optional_tools: - frame_sampler # representative frame extraction + - face_tracker # face position analysis for reframing decisions + - silence_cutter # silence detection for jump cut planning tools_available: - frame_sampler + - face_tracker + - silence_cutter checkpoint_required: true human_approval_default: true review_focus: @@ -126,7 +130,12 @@ stages: - script produces: - edit_decisions - tools_available: [] + optional_tools: + - silence_cutter # auto jump cuts on silent segments + - video_trimmer # speed control (0.5x–2x), cut, concat + tools_available: + - silence_cutter + - video_trimmer checkpoint_required: true human_approval_default: false review_focus: @@ -149,17 +158,35 @@ stages: - render_report required_tools: - video_compose # rendering - - audio_mixer # audio layering + - audio_mixer # audio layering + segmented music optional_tools: - face_enhance # face enhancement + - eye_enhance # eye brightening, dark circle removal - color_grade # color correction - audio_enhance # audio cleanup + - auto_reframe # aspect ratio conversion with face tracking + - face_tracker # face position data for reframing + - silence_cutter # auto jump cuts + - video_trimmer # speed control (0.5x–2x) + - remotion_caption_burn # animated word-by-word captions via Remotion + - showcase_card # letterboxed showcase cards with typography + - video_stitch # multi-clip assembly with transitions + - visual_qa # frame extraction + quality validation tools_available: - video_compose - audio_mixer - face_enhance + - eye_enhance - color_grade - audio_enhance + - auto_reframe + - face_tracker + - silence_cutter + - video_trimmer + - remotion_caption_burn + - showcase_card + - video_stitch + - visual_qa checkpoint_required: true human_approval_default: false review_focus: diff --git a/remotion-composer/src/Root.tsx b/remotion-composer/src/Root.tsx index 531ad6a..9033d52 100644 --- a/remotion-composer/src/Root.tsx +++ b/remotion-composer/src/Root.tsx @@ -5,6 +5,7 @@ import { calculateCinematicMetadata, } from "./CinematicRenderer"; import { signalFromTomorrowWithMusicFixture } from "./cinematic/fixtures"; +import { TalkingHead, TalkingHeadProps } from "./TalkingHead"; const calculateMetadata: CalculateMetadataFunction = async ({ props, @@ -61,6 +62,21 @@ export const Root: React.FC = () => { defaultProps={signalFromTomorrowWithMusicFixture} calculateMetadata={calculateCinematicMetadata} /> + ); }; diff --git a/remotion-composer/src/TalkingHead.tsx b/remotion-composer/src/TalkingHead.tsx new file mode 100644 index 0000000..9128fce --- /dev/null +++ b/remotion-composer/src/TalkingHead.tsx @@ -0,0 +1,35 @@ +import { AbsoluteFill, OffthreadVideo } from "remotion"; +import { CaptionOverlay, WordCaption } from "./components/CaptionOverlay"; + +export interface TalkingHeadProps { + videoSrc: string; + captions: WordCaption[]; + wordsPerPage?: number; + fontSize?: number; + highlightColor?: string; +} + +export const TalkingHead: React.FC = ({ + videoSrc, + captions, + wordsPerPage = 4, + fontSize = 52, + highlightColor = "#22D3EE", +}) => { + return ( + + + + + ); +}; diff --git a/skills/pipelines/talking-head/compose-director.md b/skills/pipelines/talking-head/compose-director.md index 5f699cd..c4ae7a8 100644 --- a/skills/pipelines/talking-head/compose-director.md +++ b/skills/pipelines/talking-head/compose-director.md @@ -18,51 +18,215 @@ You have edit decisions and an asset manifest. Your job is to render the final t ### Step 1: Run Enhancement Chain Apply video enhancements in order: -1. **Face enhancement** (if face_enhance tool available) — sharpen faces -2. **Color grading** (if color_grade tool available) — apply a profile -3. **Audio enhancement** (if audio_enhance tool available) — noise reduction, normalization +1. **Face enhancement** (if `face_enhance` tool available) — apply `talking_head_standard` preset +2. **Eye enhancement** (if `eye_enhance` tool available) — under-eye dark circle removal + eye brightening +3. **Color grading** (if `color_grade` tool available) — apply a profile +4. **Audio enhancement** (if `audio_enhance` tool available) — noise reduction, normalization Each step is optional — check tool availability first. -### Step 2: Burn Subtitles +**Eye enhancement** — removes under-eye dark circles and brightens eyes using MediaPipe Face Mesh landmark detection: +``` +eye_enhance.execute({ + "input_path": "", + "output_path": "/assets/video/eye_enhanced.mp4", + "operations": ["dark_circles", "brighten_eyes"], + "dark_circle_intensity": 0.4, # 0-1, subtle is better + "eye_brighten_intensity": 0.3, +}) +``` +**Important:** Keep intensities low (0.2-0.5). Over-processing makes eyes look unnatural. Always compare before/after. +### Step 1b: Speed Adjustment (if requested) + +If the user wants the video sped up or slowed down, use `video_trimmer`: +``` +video_trimmer.execute({ + "operation": "speed", + "input_path": "", + "output_path": "/assets/video/speed_adjusted.mp4", + "speed_factor": 1.25 # 0.5x (slow), 1.25x, 1.5x, 2x (fast) +}) +``` + +Common speed factors: +| Factor | Use Case | +|--------|----------| +| `0.5` | Slow-mo for dramatic effect | +| `1.0` | Normal (no change) | +| `1.25` | Slightly faster — tighter pacing without sounding unnatural | +| `1.5` | Noticeably faster — good for recaps or condensed content | +| `2.0` | Double speed — time-lapse effect | + +Apply speed AFTER enhancements, BEFORE reframing. + +### Step 2: Auto-Reframe (if target platform requires it) + +If the target platform requires a different aspect ratio (e.g. Instagram Reels = 9:16), use `auto_reframe`: + +``` +auto_reframe.execute({ + "input_path": "", + "output_path": "/renders/reframed.mp4", + "target_aspect": "portrait", # 9:16 for Reels/TikTok/Shorts + "smoothing_window": 15, # smooth camera pan + "face_padding": 0.4, # 40% padding around face +}) +``` + +**Aspect ratio presets:** +| Preset | Ratio | Platform | +|--------|-------|----------| +| `portrait` | 9:16 | Instagram Reels, TikTok, YouTube Shorts | +| `square` | 1:1 | Instagram Feed | +| `landscape` | 16:9 | YouTube, LinkedIn | +| `vertical_4_5` | 4:5 | Instagram portrait post | + +The tool automatically runs face detection and keeps the speaker centered. If MediaPipe is not installed, falls back to center-crop. + +**Important:** Run auto_reframe AFTER face_enhance and color_grade but BEFORE burning subtitles. Subtitles need to be positioned for the final aspect ratio. + +### Step 3: Burn Subtitles + +**Preferred: Remotion captions** (if `remotion_caption_burn` tool available): +``` +remotion_caption_burn.execute({ + "input_path": "", + "output_path": "/assets/video/captioned.mp4", + "segments": , + "corrections": {"cloud": "Claude", "co-pilot": "Copilot"}, + "words_per_page": 4, + "font_size": 52, + "highlight_color": "#22D3EE", +}) +``` +Remotion renders animated word-by-word captions at the bottom of the frame with active word highlighting. Captions are positioned away from the face. + +**Fallback: FFmpeg subtitles** (if Remotion unavailable): Use `video_compose` with `burn_subtitles` operation: -- Input: enhanced video (or raw if no enhancements) +- Input: reframed video (or enhanced video if no reframe needed) - Subtitle file from asset manifest - Style from playbook +- For vertical (9:16) output: position subtitles in the lower 20% of frame with `MarginV=100` +- **Never** position subtitles in the center of the frame — they will occlude the face -### Step 3: Mix Audio +### Step 3b: Build Showcase Cards (if multi-clip reel) -Use `audio_mixer` to: -- Layer original audio with any background music +If the output is a reel with showcase clips, use `showcase_card` for each: +``` +showcase_card.execute({ + "input_path": "", + "output_path": "/assets/video/sc_.mp4", + "title": "VIDEO TITLE", + "subtitle": "Description | Style | Cost: $0.15", + "background_color": "0x0A0F1A", +}) +``` +This creates letterboxed 9:16 cards with typography. + +### Step 4: Assemble Multi-Clip (if applicable) + +If the output has multiple segments (e.g. talking head + showcase clips), use `video_stitch`: +``` +video_stitch.execute({ + "operation": "stitch", + "clips": ["intro.mp4", "showcase1.mp4", ..., "outro.mp4"], + "output_path": "/renders/assembled.mp4", + "transition": "crossfade", # or "fade" for fade-through-black + "transition_duration": 0.5, +}) +``` +**Transition guidance:** +- `crossfade` (fade): smooth blend between talking head and showcase +- `fade` (fade-through-black): brief dip to black between showcase clips +- Mix transition types: use `crossfade` for talk→showcase, `fade` between showcases + +### Step 5: Mix Audio + +Use `audio_mixer` to layer background music: + +**For multi-clip reels** — use `segmented_music` to play music only during talking head sections: +``` +audio_mixer.execute({ + "operation": "segmented_music", + "video_path": "", + "music_path": "", + "music_volume": 0.20, + "segments": [ + {"start": 0, "end": 17.0}, # intro speech + {"start": 167.0, "end": 175.0} # outro speech + ], + "fade_duration": 0.5, + "output_path": "/renders/final.mp4", +}) +``` + +**For single talking-head videos** — use `duck` or `full_mix`: +- Layer original audio with background music - Apply ducking if music is present - Normalize final levels -### Step 4: Final Encode +### Step 6: Final Encode Use `video_compose` with `encode` operation: -- Apply target media profile (youtube_landscape, tiktok, etc.) +- Apply target media profile (youtube_landscape, tiktok, instagram_reels, etc.) - Two-pass encoding for quality -### Step 5: Verify Output +### Step 7: Visual QA -- Check file exists and is playable -- Verify duration matches expectations -- Check audio is present +Use `visual_qa` to verify the output before declaring success: +``` +visual_qa.execute({ + "operation": "review", + "input_path": "", + "timestamps": [3.0, 10.0, 25.0, 50.0, 100.0, 170.0], +}) +``` +Then **read each extracted frame** to verify: +- Captions are visible and positioned at the bottom (not on the face) +- Face enhancement is applied (skin looks smooth, not over-processed) +- Transitions are clean (no artifacts at transition points) +- Showcase cards have readable typography -### Step 6: Build Render Report +Also run probe validation: +``` +visual_qa.execute({ + "operation": "probe", + "input_path": "", + "expected": { + "width": 1080, "height": 1920, + "has_audio": true, + "pixel_format": "yuv420p" + }, +}) +``` -Document output: path, format, resolution, duration, file size. +And check audio levels: +``` +visual_qa.execute({ + "operation": "audio_levels", + "input_path": "", + "timestamps": [5.0, 50.0, 170.0], +}) +``` +Verify: speech sections have higher volume than showcase sections (confirms music placement). -### Step 7: Self-Evaluate +### Step 8: Build Render Report + +Document output: path, format, resolution, duration, file size, QA results. + +### Step 9: Self-Evaluate | Criterion | Question | |-----------|----------| | **Playability** | Does the video play without errors? | | **Quality** | Are enhancements applied correctly? | -| **Audio** | Is speech clear with balanced levels? | -| **Subtitles** | Are subtitles visible and synced? | +| **Framing** | If reframed — is the face centered? No important content cropped? | +| **Audio** | Is speech clear with balanced levels? Music only during intended segments? | +| **Subtitles** | Are captions visible at the bottom? Not occluding the face? Word highlighting working? | +| **Transitions** | Are transitions clean? Correct type (crossfade vs fadeblack)? | +| **Showcase** | Are showcase cards properly letterboxed with readable typography? | -### Step 8: Submit +### Step 10: Submit Validate the render_report against the schema and persist via checkpoint. diff --git a/skills/pipelines/talking-head/edit-director.md b/skills/pipelines/talking-head/edit-director.md index 9e2613b..a80316b 100644 --- a/skills/pipelines/talking-head/edit-director.md +++ b/skills/pipelines/talking-head/edit-director.md @@ -14,39 +14,63 @@ You have a scene plan and asset manifest. Your job is to assemble the edit decis ## Process -### Step 1: Define Primary Cut +### Step 1: Apply Silence Cuts (if planned) + +If the scene plan includes silence removal, run `silence_cutter` before defining cuts: + +``` +silence_cutter.execute({ + "input_path": "", + "mode": "remove", # or "speed_up" for less jarring result + "silence_threshold_db": -35, + "min_silence_duration": 0.5, + "padding_seconds": 0.08, # prevents clipped words + "output_path": "/assets/video/footage_cut.mp4" +}) +``` + +**Choosing the mode:** +- `remove` — Hard jump cuts. Best for fast-paced social content (Reels, TikTok, Shorts) +- `speed_up` — Fast-forwards through silence at 6x. Less jarring for longer-form content (YouTube, LinkedIn) + +Present the result to the user: "Removed X seconds of silence (Y%) — output is now Z seconds." + +Use the cut footage as the source for all subsequent steps. + +### Step 2: Define Primary Cut For talking-head, the primary cut is usually the full footage (or trimmed segments). Create cuts that: -- Reference the raw footage as source +- Reference the raw footage (or silence-cut footage) as source - Use timestamps from the script sections - Apply any trim decisions (cut dead air, false starts) -### Step 2: Configure Subtitles +### Step 3: Configure Subtitles - Enable subtitles with playbook-compatible styling - Reference the subtitle asset from the manifest - Set position (usually bottom-center) -### Step 3: Configure Audio +### Step 4: Configure Audio - Set narration to the raw footage audio - If background music is desired, configure ducking - Set music volume per playbook -### Step 4: Plan Enhancements +### Step 5: Plan Enhancements If the scene plan includes overlays: - Add overlay cuts for text cards, lower thirds - Time them to match speech content -### Step 5: Self-Evaluate +### Step 6: Self-Evaluate | Criterion | Question | |-----------|----------| | **Coverage** | Do cuts span the full intended duration? | +| **Silence** | Were silence cuts applied if planned? What % was removed? | | **Subtitles** | Are subtitles enabled and styled? | | **Audio** | Is audio configuration complete? | -### Step 6: Submit +### Step 7: Submit Validate the edit_decisions against the schema and persist via checkpoint. diff --git a/skills/pipelines/talking-head/scene-director.md b/skills/pipelines/talking-head/scene-director.md index 707d682..7da3931 100644 --- a/skills/pipelines/talking-head/scene-director.md +++ b/skills/pipelines/talking-head/scene-director.md @@ -11,28 +11,70 @@ You have a script (from transcription) and raw footage. Your job is to create a | Schema | `schemas/artifacts/scene_plan.schema.json` | Artifact validation | | Prior artifacts | Script, Brief | Section timing and context | | Tools | `frame_sampler` (optional) | Extract representative frames | +| Tools | `face_tracker` (optional) | Analyze speaker face position for reframing | +| Tools | `silence_cutter` (optional) | Detect silence for jump cut planning | ## Process -### Step 1: Plan Base Scenes +### Step 1: Analyze Footage (if tools available) + +**Face tracking** — If `face_tracker` is available, run it on the raw footage: +``` +face_tracker.execute({ + "input_path": "", + "sample_fps": 5 +}) +``` +This outputs per-frame face bounding boxes. Use this data to: +- Decide if reframing is needed (e.g. speaker is off-center for vertical crop) +- Identify sections where the speaker moves significantly (needs dynamic crop) +- Note face position for auto_reframe in the compose stage + +**Silence detection** — If `silence_cutter` is available, run in `mark` mode: +``` +silence_cutter.execute({ + "input_path": "", + "mode": "mark", + "silence_threshold_db": -35, + "min_silence_duration": 0.5 +}) +``` +This outputs silence/speech segment timestamps. Use this to: +- Plan which segments should be jump-cut or sped up +- Identify dead air, false starts, and long pauses +- Estimate the final video duration after cuts +- Present the user with a summary: "Found X seconds of silence across Y segments — recommend removing?" + +### Step 2: Plan Base Scenes For talking-head, the base is simple: one scene per script section, all type `talking_head`. The raw footage IS the scene. -### Step 2: Plan Enhancement Scenes +### Step 3: Plan Enhancement Scenes Based on script enhancement cues, plan overlay scenes: - Text cards for key terms or statistics - Lower thirds for speaker identification - B-roll suggestions for topic illustrations -### Step 3: Build Scene Plan +### Step 4: Plan Reframing & Cuts + +If the target platform requires a different aspect ratio (e.g. Instagram Reels = 9:16): +- Note `auto_reframe` should be applied in the compose stage +- Record the target aspect ratio in the scene plan +- If face tracking data shows significant speaker movement, note that dynamic crop is needed + +If silence detection found segments to cut: +- Record the recommended cut mode (`remove` or `speed_up`) in the scene plan +- Note padding preferences (default 0.08s to avoid clipping words) + +### Step 5: Build Scene Plan Create a scene per section with: - Type: `talking_head` (primary) - Timing from script sections - Required assets: subtitle file, any overlay images -### Step 4: Self-Evaluate +### Step 6: Self-Evaluate | Criterion | Question | |-----------|----------| @@ -40,6 +82,6 @@ Create a scene per section with: | **Enhancement** | Are overlay opportunities identified? | | **Feasibility** | Can all required assets be generated? | -### Step 5: Submit +### Step 7: Submit Validate the scene_plan against the schema and persist via checkpoint. diff --git a/tools/analysis/face_tracker.py b/tools/analysis/face_tracker.py new file mode 100644 index 0000000..f9ed63e --- /dev/null +++ b/tools/analysis/face_tracker.py @@ -0,0 +1,314 @@ +"""Face tracking tool using MediaPipe Face Mesh. + +Tracks face bounding boxes, landmarks, and head pose across video frames. +Outputs per-frame face data as JSON — used by auto_reframe, face_enhance, +and other tools that need to know where the speaker's face is. + +Falls back to OpenCV Haar cascade if MediaPipe is not installed. +""" + +from __future__ import annotations + +import json +import time +from pathlib import Path +from typing import Any + +from tools.base_tool import ( + BaseTool, + Determinism, + ExecutionMode, + ResourceProfile, + ToolResult, + ToolStability, + ToolStatus, + ToolTier, +) + + +class FaceTracker(BaseTool): + name = "face_tracker" + version = "0.1.0" + tier = ToolTier.CORE + capability = "analysis" + provider = "mediapipe" + stability = ToolStability.EXPERIMENTAL + execution_mode = ExecutionMode.SYNC + determinism = Determinism.DETERMINISTIC + + dependencies = ["cmd:ffmpeg"] + install_instructions = ( + "For best results install MediaPipe:\n" + "pip install mediapipe opencv-python\n\n" + "Falls back to OpenCV Haar cascade (ships with opencv-python)." + ) + agent_skills = ["ffmpeg"] + + capabilities = [ + "face_detection", + "face_tracking", + "face_bounding_box", + "head_pose_estimation", + ] + + input_schema = { + "type": "object", + "required": ["input_path"], + "properties": { + "input_path": {"type": "string"}, + "output_path": { + "type": "string", + "description": "Path for face tracking JSON output", + }, + "sample_fps": { + "type": "number", + "default": 5, + "description": "Frames per second to sample (lower = faster, less precise)", + }, + "min_detection_confidence": { + "type": "number", + "default": 0.5, + "minimum": 0.0, + "maximum": 1.0, + }, + }, + } + + output_schema = { + "type": "object", + "properties": { + "frame_count": {"type": "integer"}, + "face_detected_count": {"type": "integer"}, + "video_width": {"type": "integer"}, + "video_height": {"type": "integer"}, + "fps": {"type": "number"}, + "duration_seconds": {"type": "number"}, + "faces": { + "type": "array", + "items": { + "type": "object", + "properties": { + "frame_index": {"type": "integer"}, + "timestamp_seconds": {"type": "number"}, + "bbox": { + "type": "object", + "properties": { + "x": {"type": "number"}, + "y": {"type": "number"}, + "width": {"type": "number"}, + "height": {"type": "number"}, + }, + }, + }, + }, + }, + }, + } + + resource_profile = ResourceProfile(cpu_cores=2, ram_mb=1024, vram_mb=0, disk_mb=100) + idempotency_key_fields = ["input_path", "sample_fps", "min_detection_confidence"] + side_effects = ["writes face tracking JSON to output_path"] + user_visible_verification = [ + "Spot-check bounding boxes against video frames", + ] + + fallback_tools = [] + + def _has_mediapipe(self) -> bool: + try: + import mediapipe # noqa: F401 + return True + except ImportError: + return False + + def _has_opencv(self) -> bool: + try: + import cv2 # noqa: F401 + return True + except ImportError: + return False + + def get_status(self) -> ToolStatus: + if self._has_mediapipe() and self._has_opencv(): + return ToolStatus.AVAILABLE + if self._has_opencv(): + return ToolStatus.DEGRADED + return ToolStatus.UNAVAILABLE + + def execute(self, inputs: dict[str, Any]) -> ToolResult: + input_path = Path(inputs["input_path"]) + if not input_path.exists(): + return ToolResult(success=False, error=f"Input not found: {input_path}") + + if not self._has_opencv(): + return ToolResult( + success=False, + error="opencv-python is required. Install: pip install opencv-python", + ) + + output_path = Path( + inputs.get("output_path", str(input_path.with_suffix(".faces.json"))) + ) + output_path.parent.mkdir(parents=True, exist_ok=True) + + sample_fps = inputs.get("sample_fps", 5) + confidence = inputs.get("min_detection_confidence", 0.5) + + start = time.time() + + if self._has_mediapipe(): + result_data = self._track_mediapipe(input_path, sample_fps, confidence) + else: + result_data = self._track_opencv(input_path, sample_fps) + + elapsed = time.time() - start + + output_path.write_text(json.dumps(result_data, indent=2), encoding="utf-8") + + return ToolResult( + success=True, + data={ + "output": str(output_path), + "video_width": result_data["video_width"], + "video_height": result_data["video_height"], + "fps": result_data["fps"], + "duration_seconds": result_data["duration_seconds"], + "frames_sampled": result_data["frame_count"], + "faces_detected": result_data["face_detected_count"], + "method": "mediapipe" if self._has_mediapipe() else "opencv_haar", + }, + artifacts=[str(output_path)], + duration_seconds=round(elapsed, 2), + ) + + def _track_mediapipe( + self, input_path: Path, sample_fps: float, confidence: float + ) -> dict: + import cv2 + import mediapipe as mp + + mp_face = mp.solutions.face_detection + cap = cv2.VideoCapture(str(input_path)) + + video_fps = cap.get(cv2.CAP_PROP_FPS) or 30.0 + video_w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) + video_h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) + total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) + duration = total_frames / video_fps if video_fps > 0 else 0 + + # Calculate frame sampling interval + sample_interval = max(1, int(video_fps / sample_fps)) + + faces_data: list[dict] = [] + frame_idx = 0 + sampled = 0 + + with mp_face.FaceDetection( + model_selection=1, # 1 = full range (up to 5m), 0 = short range (up to 2m) + min_detection_confidence=confidence, + ) as detector: + while cap.isOpened(): + ret, frame = cap.read() + if not ret: + break + + if frame_idx % sample_interval == 0: + sampled += 1 + rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) + results = detector.process(rgb) + + if results.detections: + # Use the highest-confidence detection + det = max( + results.detections, + key=lambda d: d.score[0], + ) + bbox = det.location_data.relative_bounding_box + faces_data.append({ + "frame_index": frame_idx, + "timestamp_seconds": round(frame_idx / video_fps, 3), + "confidence": round(det.score[0], 3), + "bbox": { + "x": round(bbox.xmin, 4), + "y": round(bbox.ymin, 4), + "width": round(bbox.width, 4), + "height": round(bbox.height, 4), + }, + }) + + frame_idx += 1 + + cap.release() + + return { + "video_width": video_w, + "video_height": video_h, + "fps": round(video_fps, 2), + "duration_seconds": round(duration, 3), + "frame_count": sampled, + "face_detected_count": len(faces_data), + "faces": faces_data, + } + + def _track_opencv(self, input_path: Path, sample_fps: float) -> dict: + """Fallback: OpenCV Haar cascade face detection.""" + import cv2 + + cascade_path = cv2.data.haarcascades + "haarcascade_frontalface_default.xml" + cascade = cv2.CascadeClassifier(cascade_path) + + cap = cv2.VideoCapture(str(input_path)) + video_fps = cap.get(cv2.CAP_PROP_FPS) or 30.0 + video_w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) + video_h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) + total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) + duration = total_frames / video_fps if video_fps > 0 else 0 + + sample_interval = max(1, int(video_fps / sample_fps)) + + faces_data: list[dict] = [] + frame_idx = 0 + sampled = 0 + + while cap.isOpened(): + ret, frame = cap.read() + if not ret: + break + + if frame_idx % sample_interval == 0: + sampled += 1 + gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) + detected = cascade.detectMultiScale( + gray, scaleFactor=1.1, minNeighbors=5, minSize=(60, 60) + ) + + if len(detected) > 0: + # Pick largest face + areas = [w * h for (_, _, w, h) in detected] + best_idx = areas.index(max(areas)) + x, y, w, h = detected[best_idx] + faces_data.append({ + "frame_index": frame_idx, + "timestamp_seconds": round(frame_idx / video_fps, 3), + "confidence": 0.0, # Haar doesn't provide confidence + "bbox": { + "x": round(x / video_w, 4), + "y": round(y / video_h, 4), + "width": round(w / video_w, 4), + "height": round(h / video_h, 4), + }, + }) + + frame_idx += 1 + + cap.release() + + return { + "video_width": video_w, + "video_height": video_h, + "fps": round(video_fps, 2), + "duration_seconds": round(duration, 3), + "frame_count": sampled, + "face_detected_count": len(faces_data), + "faces": faces_data, + } diff --git a/tools/analysis/visual_qa.py b/tools/analysis/visual_qa.py new file mode 100644 index 0000000..7aa3015 --- /dev/null +++ b/tools/analysis/visual_qa.py @@ -0,0 +1,343 @@ +"""Visual QA tool for automated video quality checks. + +Extracts frames at specified timestamps and runs basic quality checks: +- File existence, resolution, duration, codec validation +- Frame extraction for visual inspection by the agent +- Caption occlusion check (compares brightness in face vs caption zones) +- Transition verification (frame similarity at transition points) + +Returns frame paths so the agent can visually inspect them. +""" + +from __future__ import annotations + +import time +from pathlib import Path +from typing import Any + +from tools.base_tool import ( + BaseTool, + Determinism, + ExecutionMode, + ResourceProfile, + ToolResult, + ToolStability, + ToolTier, +) + + +class VisualQA(BaseTool): + name = "visual_qa" + version = "0.1.0" + tier = ToolTier.CORE + capability = "analysis" + provider = "ffmpeg" + stability = ToolStability.EXPERIMENTAL + execution_mode = ExecutionMode.SYNC + determinism = Determinism.DETERMINISTIC + + dependencies = ["cmd:ffmpeg", "cmd:ffprobe"] + install_instructions = "Install FFmpeg: https://ffmpeg.org/download.html" + agent_skills = ["ffmpeg"] + + capabilities = [ + "extract_review_frames", + "probe_video", + "check_audio_levels", + ] + + input_schema = { + "type": "object", + "required": ["operation", "input_path"], + "properties": { + "operation": { + "type": "string", + "enum": ["review", "probe", "audio_levels"], + "description": ( + "review: extract frames at timestamps for visual inspection. " + "probe: get video metadata (duration, resolution, codecs). " + "audio_levels: check audio volume at specified timestamps." + ), + }, + "input_path": { + "type": "string", + "description": "Path to the video file to inspect.", + }, + "timestamps": { + "type": "array", + "items": {"type": "number"}, + "description": ( + "Timestamps (in seconds) at which to extract frames or " + "check audio levels." + ), + }, + "output_dir": { + "type": "string", + "description": ( + "Directory to save extracted frames. Defaults to a " + "'review_frames' subdirectory next to the input file." + ), + }, + "checks": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "resolution", + "duration", + "audio_present", + "pixel_format", + "file_size", + ], + }, + "description": "Specific checks to run (probe operation).", + }, + "expected": { + "type": "object", + "description": ( + "Expected values for validation. " + "Keys: width, height, min_duration, max_duration, " + "pixel_format, has_audio." + ), + "properties": { + "width": {"type": "integer"}, + "height": {"type": "integer"}, + "min_duration": {"type": "number"}, + "max_duration": {"type": "number"}, + "pixel_format": {"type": "string"}, + "has_audio": {"type": "boolean"}, + }, + }, + }, + } + + resource_profile = ResourceProfile(cpu_cores=1, ram_mb=512, vram_mb=0, disk_mb=200) + idempotency_key_fields = ["operation", "input_path", "timestamps"] + side_effects = ["writes frame images to output_dir"] + user_visible_verification = [ + "Visually inspect extracted frames for quality issues", + ] + + def execute(self, inputs: dict[str, Any]) -> ToolResult: + operation = inputs["operation"] + input_path = inputs["input_path"] + + if not Path(input_path).exists(): + return ToolResult(success=False, error=f"Input not found: {input_path}") + + start = time.time() + + try: + if operation == "review": + result = self._review(inputs) + elif operation == "probe": + result = self._probe(inputs) + elif operation == "audio_levels": + result = self._audio_levels(inputs) + else: + return ToolResult(success=False, error=f"Unknown operation: {operation}") + except Exception as e: + return ToolResult(success=False, error=str(e)) + + result.duration_seconds = round(time.time() - start, 2) + return result + + def _review(self, inputs: dict[str, Any]) -> ToolResult: + """Extract frames at specified timestamps for visual review.""" + input_path = inputs["input_path"] + timestamps = inputs.get("timestamps", []) + + if not timestamps: + # Auto-generate timestamps: start, 25%, 50%, 75%, end-1s + dur = self._get_duration(input_path) + timestamps = [ + 1.0, + dur * 0.25, + dur * 0.50, + dur * 0.75, + max(dur - 1.0, 0), + ] + + output_dir = inputs.get("output_dir") + if not output_dir: + output_dir = str(Path(input_path).parent / "review_frames") + Path(output_dir).mkdir(parents=True, exist_ok=True) + + frames = [] + for ts in timestamps: + ts_label = f"{ts:.1f}".replace(".", "_") + frame_path = str(Path(output_dir) / f"frame_{ts_label}s.jpg") + cmd = [ + "ffmpeg", "-y", + "-ss", str(ts), + "-i", input_path, + "-frames:v", "1", + "-q:v", "2", + frame_path, + ] + try: + self.run_command(cmd) + if Path(frame_path).exists(): + frames.append({ + "timestamp": ts, + "path": frame_path, + }) + except Exception: + frames.append({ + "timestamp": ts, + "path": None, + "error": f"Failed to extract frame at {ts}s", + }) + + return ToolResult( + success=True, + data={ + "operation": "review", + "input": input_path, + "frame_count": len([f for f in frames if f.get("path")]), + "frames": frames, + }, + artifacts=[f["path"] for f in frames if f.get("path")], + ) + + def _probe(self, inputs: dict[str, Any]) -> ToolResult: + """Probe video metadata and optionally validate against expectations.""" + input_path = inputs["input_path"] + expected = inputs.get("expected", {}) + + # Get comprehensive probe data + cmd = [ + "ffprobe", "-v", "error", + "-show_entries", + "format=duration,size:stream=width,height,codec_name,pix_fmt," + "r_frame_rate,sample_rate,channels,codec_type", + "-of", "json", + input_path, + ] + import json + probe_out = self.run_command(cmd, capture=True) + probe_data = json.loads(probe_out) + + # Extract key info + video_stream = None + audio_stream = None + for s in probe_data.get("streams", []): + if s.get("codec_type") == "video" and not video_stream: + video_stream = s + elif s.get("codec_type") == "audio" and not audio_stream: + audio_stream = s + + info = { + "duration": float(probe_data.get("format", {}).get("duration", 0)), + "file_size_mb": round( + int(probe_data.get("format", {}).get("size", 0)) / 1048576, 1 + ), + "has_audio": audio_stream is not None, + } + if video_stream: + info.update({ + "width": video_stream.get("width"), + "height": video_stream.get("height"), + "pixel_format": video_stream.get("pix_fmt"), + "video_codec": video_stream.get("codec_name"), + "frame_rate": video_stream.get("r_frame_rate"), + }) + if audio_stream: + info.update({ + "audio_codec": audio_stream.get("codec_name"), + "sample_rate": audio_stream.get("sample_rate"), + "channels": audio_stream.get("channels"), + }) + + # Validate against expectations + issues = [] + if "width" in expected and info.get("width") != expected["width"]: + issues.append(f"Width: expected {expected['width']}, got {info.get('width')}") + if "height" in expected and info.get("height") != expected["height"]: + issues.append(f"Height: expected {expected['height']}, got {info.get('height')}") + if "min_duration" in expected and info["duration"] < expected["min_duration"]: + issues.append( + f"Duration too short: {info['duration']:.1f}s < {expected['min_duration']}s" + ) + if "max_duration" in expected and info["duration"] > expected["max_duration"]: + issues.append( + f"Duration too long: {info['duration']:.1f}s > {expected['max_duration']}s" + ) + if "pixel_format" in expected and info.get("pixel_format") != expected["pixel_format"]: + issues.append( + f"Pixel format: expected {expected['pixel_format']}, got {info.get('pixel_format')}" + ) + if "has_audio" in expected and info["has_audio"] != expected["has_audio"]: + issues.append( + f"Audio: expected {'present' if expected['has_audio'] else 'absent'}, " + f"got {'present' if info['has_audio'] else 'absent'}" + ) + + info["validation_issues"] = issues + info["validation_passed"] = len(issues) == 0 + + return ToolResult( + success=True, + data={ + "operation": "probe", + "input": input_path, + **info, + }, + ) + + def _audio_levels(self, inputs: dict[str, Any]) -> ToolResult: + """Check audio levels at specified timestamps.""" + input_path = inputs["input_path"] + timestamps = inputs.get("timestamps", []) + + if not timestamps: + dur = self._get_duration(input_path) + timestamps = [1.0, dur * 0.5, max(dur - 2.0, 0)] + + levels = [] + for ts in timestamps: + cmd = [ + "ffmpeg", "-y", + "-ss", str(ts), + "-t", "3", + "-i", input_path, + "-vn", "-af", "volumedetect", + "-f", "null", "/dev/null", + ] + try: + output = self.run_command(cmd, capture=True, stderr=True) + mean_vol = None + max_vol = None + for line in output.split("\n"): + if "mean_volume" in line: + mean_vol = float(line.split("mean_volume:")[1].strip().split()[0]) + elif "max_volume" in line: + max_vol = float(line.split("max_volume:")[1].strip().split()[0]) + levels.append({ + "timestamp": ts, + "mean_volume_db": mean_vol, + "max_volume_db": max_vol, + }) + except Exception as e: + levels.append({ + "timestamp": ts, + "error": str(e), + }) + + return ToolResult( + success=True, + data={ + "operation": "audio_levels", + "input": input_path, + "levels": levels, + }, + ) + + def _get_duration(self, path: str) -> float: + cmd = [ + "ffprobe", "-v", "error", + "-show_entries", "format=duration", + "-of", "csv=p=0", + path, + ] + return float(self.run_command(cmd, capture=True).strip().split("\n")[0]) diff --git a/tools/audio/audio_mixer.py b/tools/audio/audio_mixer.py index ab2b967..39be5a2 100644 --- a/tools/audio/audio_mixer.py +++ b/tools/audio/audio_mixer.py @@ -40,7 +40,7 @@ class AudioMixer(BaseTool): ) agent_skills = ["ffmpeg", "video_toolkit"] - capabilities = ["mix", "duck", "fade", "normalize", "extract_audio"] + capabilities = ["mix", "duck", "fade", "normalize", "extract_audio", "segmented_music"] input_schema = { "type": "object", @@ -48,13 +48,16 @@ class AudioMixer(BaseTool): "properties": { "operation": { "type": "string", - "enum": ["mix", "duck", "extract", "full_mix"], + "enum": ["mix", "duck", "extract", "full_mix", "segmented_music"], "description": ( "mix: layer multiple tracks with volume/delay/fades. " "duck: lower music volume when speech is present. " "extract: extract audio from video file. " "full_mix: combine narration tracks + music with ducking + normalize " - "in a single call (preferred for compose-director)." + "in a single call (preferred for compose-director). " + "segmented_music: mix music into a video only during specified " + "time segments (e.g. music during talking head, silence during " + "showcase clips)." ), }, "tracks": { @@ -128,6 +131,45 @@ class AudioMixer(BaseTool): }, }, "normalize": {"type": "boolean", "default": True}, + "video_path": { + "type": "string", + "description": ( + "Path to the assembled video (segmented_music operation). " + "Music is mixed into this video's audio at specified segments." + ), + }, + "music_path": { + "type": "string", + "description": "Path to background music file (segmented_music operation).", + }, + "music_volume": { + "type": "number", + "minimum": 0, + "maximum": 1.0, + "default": 0.20, + "description": "Volume level for music during active segments.", + }, + "segments": { + "type": "array", + "description": ( + "Time segments where music should play (segmented_music operation). " + "Each segment: {start: seconds, end: seconds}. Music fades in/out " + "at segment boundaries. Outside these segments, music is silent." + ), + "items": { + "type": "object", + "required": ["start", "end"], + "properties": { + "start": {"type": "number", "minimum": 0}, + "end": {"type": "number", "minimum": 0}, + }, + }, + }, + "fade_duration": { + "type": "number", + "default": 0.5, + "description": "Duration of fade in/out at segment boundaries (seconds).", + }, }, } @@ -151,6 +193,8 @@ class AudioMixer(BaseTool): result = self._extract(inputs) elif operation == "full_mix": result = self._full_mix(inputs) + elif operation == "segmented_music": + result = self._segmented_music(inputs) else: return ToolResult(success=False, error=f"Unknown operation: {operation}") except Exception as e: @@ -558,3 +602,105 @@ class AudioMixer(BaseTool): }, artifacts=[str(output_path)], ) + + def _segmented_music(self, inputs: dict[str, Any]) -> ToolResult: + """Mix background music into a video only during specified time segments. + + Uses FFmpeg volume expressions with smooth fades at segment boundaries. + Music is silent outside the specified segments. + + Input format: + { + "operation": "segmented_music", + "video_path": "assembled.mp4", + "music_path": "bg_music.mp3", + "music_volume": 0.20, + "segments": [ + {"start": 0, "end": 17.0}, + {"start": 167.0, "end": 175.0} + ], + "fade_duration": 0.5, + "output_path": "final_with_music.mp4" + } + """ + video_path = inputs.get("video_path") + music_path = inputs.get("music_path") + output_path = Path(inputs.get("output_path", "segmented_music_output.mp4")) + segments = inputs.get("segments", []) + music_volume = inputs.get("music_volume", 0.20) + fade_dur = inputs.get("fade_duration", 0.5) + + if not video_path or not Path(video_path).exists(): + return ToolResult(success=False, error=f"Video not found: {video_path}") + if not music_path or not Path(music_path).exists(): + return ToolResult(success=False, error=f"Music not found: {music_path}") + if not segments: + return ToolResult(success=False, error="No segments specified") + + output_path.parent.mkdir(parents=True, exist_ok=True) + + # Get video duration + dur_cmd = [ + "ffprobe", "-v", "error", + "-show_entries", "format=duration", + "-of", "csv=p=0", + video_path, + ] + total_dur = float(self.run_command(dur_cmd, capture=True).strip().split("\n")[0]) + + # Build volume expression for each segment with smooth fades + parts = [] + for seg in sorted(segments, key=lambda s: s["start"]): + s = seg["start"] + e = seg["end"] + fade_in_end = s + fade_dur + fade_out_start = e - fade_dur + parts.append( + f"if(lt(t,{s}),0," + f"if(lt(t,{fade_in_end}),{music_volume}*(t-{s})/{fade_dur}," + f"if(lt(t,{fade_out_start}),{music_volume}," + f"if(lt(t,{e}),{music_volume}*({e}-t)/{fade_dur}," + f"0))))" + ) + + vol_expr = "+".join(f"({p})" for p in parts) if len(parts) > 1 else parts[0] + + filter_complex = ( + f"[1:a]atrim=0:{total_dur},asetpts=PTS-STARTPTS," + f"volume='{vol_expr}':eval=frame[music_shaped];" + f"[0:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo[speech];" + f"[music_shaped]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo[music_fmt];" + f"[speech][music_fmt]amix=inputs=2:duration=first:dropout_transition=2[aout]" + ) + + cmd = [ + "ffmpeg", "-y", + "-i", video_path, + "-stream_loop", "-1", + "-i", music_path, + "-filter_complex", filter_complex, + "-map", "0:v", + "-map", "[aout]", + "-c:v", "copy", + "-c:a", "aac", "-b:a", "192k", + str(output_path), + ] + + self.run_command(cmd) + + if not output_path.exists(): + return ToolResult(success=False, error="No output produced") + + return ToolResult( + success=True, + data={ + "operation": "segmented_music", + "video": video_path, + "music": music_path, + "segments": segments, + "music_volume": music_volume, + "fade_duration": fade_dur, + "output": str(output_path), + }, + artifacts=[str(output_path)], + ) diff --git a/tools/enhancement/eye_enhance.py b/tools/enhancement/eye_enhance.py new file mode 100644 index 0000000..5ffe771 --- /dev/null +++ b/tools/enhancement/eye_enhance.py @@ -0,0 +1,578 @@ +"""Eye enhancement tool using MediaPipe Face Mesh + OpenCV. + +Targets the eye region for talking-head footage: +- Under-eye dark circle brightening +- Eye/iris sharpening and brightening +- Subtle under-eye smoothing + +Uses MediaPipe Face Mesh (468 landmarks) to precisely locate eye regions, +then applies targeted OpenCV adjustments. Processes video frame-by-frame. + +Falls back to FFmpeg region-based filters if MediaPipe is not installed. +""" + +from __future__ import annotations + +import json +import time +from pathlib import Path +from typing import Any + +from tools.base_tool import ( + BaseTool, + Determinism, + ExecutionMode, + ResourceProfile, + ToolResult, + ToolStability, + ToolStatus, + ToolTier, +) + +# MediaPipe Face Mesh landmark indices for eye regions. +# These form polygons around each eye area. +# Lower eyelid landmarks (used to define the under-eye region): +LEFT_LOWER_EYELID = [33, 7, 163, 144, 145, 153, 154, 155, 133] +RIGHT_LOWER_EYELID = [263, 249, 390, 373, 374, 380, 381, 382, 362] + +# Full eye contour (used for iris/eye brightening): +LEFT_EYE = [33, 7, 163, 144, 145, 153, 154, 155, 133, 173, 157, 158, 159, 160, 161, 246] +RIGHT_EYE = [263, 249, 390, 373, 374, 380, 381, 382, 362, 398, 384, 385, 386, 387, 388, 466] + +# Iris landmarks (available when refine_landmarks=True, indices 468-477): +LEFT_IRIS = [468, 469, 470, 471, 472] +RIGHT_IRIS = [473, 474, 475, 476, 477] + + +class EyeEnhance(BaseTool): + name = "eye_enhance" + version = "0.1.0" + tier = ToolTier.ENHANCE + capability = "enhancement" + provider = "mediapipe" + stability = ToolStability.EXPERIMENTAL + execution_mode = ExecutionMode.SYNC + determinism = Determinism.DETERMINISTIC + + dependencies = ["cmd:ffmpeg"] + install_instructions = ( + "For best results install MediaPipe and OpenCV:\n" + "pip install mediapipe opencv-python numpy\n\n" + "Without MediaPipe, falls back to FFmpeg eye-region filter (less precise)." + ) + agent_skills = ["ffmpeg"] + + capabilities = [ + "under_eye_brightening", + "dark_circle_removal", + "eye_sharpening", + "eye_brightening", + ] + + input_schema = { + "type": "object", + "required": ["input_path"], + "properties": { + "input_path": {"type": "string"}, + "output_path": {"type": "string"}, + "operations": { + "type": "array", + "items": { + "type": "string", + "enum": ["dark_circles", "brighten_eyes", "sharpen_eyes"], + }, + "default": ["dark_circles", "brighten_eyes"], + "description": "Which enhancements to apply", + }, + "dark_circle_intensity": { + "type": "number", + "default": 0.4, + "minimum": 0.0, + "maximum": 1.0, + "description": "Strength of dark circle removal (0=none, 1=max)", + }, + "eye_brighten_intensity": { + "type": "number", + "default": 0.3, + "minimum": 0.0, + "maximum": 1.0, + "description": "Strength of eye brightening (0=none, 1=max)", + }, + "sharpen_intensity": { + "type": "number", + "default": 0.3, + "minimum": 0.0, + "maximum": 1.0, + "description": "Strength of eye sharpening (0=none, 1=max)", + }, + "codec": {"type": "string", "default": "libx264"}, + "crf": {"type": "integer", "default": 18}, + }, + } + + resource_profile = ResourceProfile( + cpu_cores=4, ram_mb=2048, vram_mb=0, disk_mb=4000, network_required=False + ) + idempotency_key_fields = [ + "input_path", "operations", "dark_circle_intensity", + "eye_brighten_intensity", "sharpen_intensity", + ] + side_effects = ["writes enhanced video to output_path"] + user_visible_verification = [ + "Compare eyes in before/after — enhancement should be subtle and natural", + "Check for artifacts around eye region (halos, color shifts)", + "Verify enhancement doesn't make eyes look unnatural", + ] + + def _has_mediapipe(self) -> bool: + try: + import mediapipe # noqa: F401 + return True + except ImportError: + return False + + def _has_opencv(self) -> bool: + try: + import cv2 # noqa: F401 + import numpy # noqa: F401 + return True + except ImportError: + return False + + def get_status(self) -> ToolStatus: + if self._has_mediapipe() and self._has_opencv(): + return ToolStatus.AVAILABLE + if self._has_opencv(): + return ToolStatus.DEGRADED + return ToolStatus.UNAVAILABLE + + def execute(self, inputs: dict[str, Any]) -> ToolResult: + input_path = Path(inputs["input_path"]) + if not input_path.exists(): + return ToolResult(success=False, error=f"Input not found: {input_path}") + + operations = inputs.get("operations", ["dark_circles", "brighten_eyes"]) + output_path = Path( + inputs.get("output_path", str(input_path.with_stem(f"{input_path.stem}_eye_enhanced"))) + ) + output_path.parent.mkdir(parents=True, exist_ok=True) + + start = time.time() + + if self._has_mediapipe() and self._has_opencv(): + result = self._enhance_mediapipe(input_path, output_path, inputs) + elif self._has_opencv(): + result = self._enhance_opencv_only(input_path, output_path, inputs) + else: + result = self._enhance_ffmpeg_fallback(input_path, output_path, inputs) + + if not result.success: + return result + + elapsed = time.time() - start + result.duration_seconds = round(elapsed, 2) + return result + + def _enhance_mediapipe( + self, input_path: Path, output_path: Path, inputs: dict[str, Any] + ) -> ToolResult: + """Full MediaPipe Face Mesh + OpenCV pipeline for precise eye enhancement.""" + import cv2 + import numpy as np + import mediapipe as mp + + operations = inputs.get("operations", ["dark_circles", "brighten_eyes"]) + dark_intensity = inputs.get("dark_circle_intensity", 0.4) + brighten_intensity = inputs.get("eye_brighten_intensity", 0.3) + sharpen_intensity = inputs.get("sharpen_intensity", 0.3) + codec_fourcc = inputs.get("codec", "libx264") + crf = inputs.get("crf", 18) + + mp_face_mesh = mp.solutions.face_mesh + + cap = cv2.VideoCapture(str(input_path)) + fps = cap.get(cv2.CAP_PROP_FPS) or 30.0 + width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) + height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) + total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) + + # Write to temp file, then mux audio via FFmpeg + temp_video = output_path.parent / f".{output_path.stem}_temp.mp4" + + fourcc = cv2.VideoWriter_fourcc(*"mp4v") + writer = cv2.VideoWriter(str(temp_video), fourcc, fps, (width, height)) + + frames_processed = 0 + frames_enhanced = 0 + + with mp_face_mesh.FaceMesh( + static_image_mode=False, + max_num_faces=1, + refine_landmarks=True, # Enables iris landmarks (468-477) + min_detection_confidence=0.5, + min_tracking_confidence=0.5, + ) as face_mesh: + while cap.isOpened(): + ret, frame = cap.read() + if not ret: + break + + frames_processed += 1 + rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) + results = face_mesh.process(rgb) + + if results.multi_face_landmarks: + landmarks = results.multi_face_landmarks[0] + frame = self._apply_eye_enhancements( + frame, landmarks, width, height, + operations, dark_intensity, brighten_intensity, sharpen_intensity, + ) + frames_enhanced += 1 + + writer.write(frame) + + cap.release() + writer.release() + + # Mux original audio back with FFmpeg + cmd = [ + "ffmpeg", "-y", + "-i", str(temp_video), + "-i", str(input_path), + "-c:v", "libx264", "-crf", str(crf), "-preset", "fast", + "-c:a", "aac", "-b:a", "192k", + "-map", "0:v:0", "-map", "1:a:0?", + "-shortest", + str(output_path), + ] + + try: + self.run_command(cmd, timeout=600) + except Exception as e: + return ToolResult(success=False, error=f"Audio mux failed: {e}") + finally: + if temp_video.exists(): + temp_video.unlink() + + return ToolResult( + success=True, + data={ + "input": str(input_path), + "output": str(output_path), + "method": "mediapipe_face_mesh", + "frames_processed": frames_processed, + "frames_enhanced": frames_enhanced, + "operations": operations, + }, + artifacts=[str(output_path)], + ) + + def _apply_eye_enhancements( + self, + frame, + landmarks, + width: int, + height: int, + operations: list[str], + dark_intensity: float, + brighten_intensity: float, + sharpen_intensity: float, + ): + """Apply eye enhancements to a single frame using detected landmarks.""" + import cv2 + import numpy as np + + result = frame.copy() + + # Convert landmarks to pixel coordinates + def lm_to_px(indices): + points = [] + for idx in indices: + if idx < len(landmarks.landmark): + lm = landmarks.landmark[idx] + points.append((int(lm.x * width), int(lm.y * height))) + return np.array(points, dtype=np.int32) + + for side in ["left", "right"]: + lower_lid = lm_to_px(LEFT_LOWER_EYELID if side == "left" else RIGHT_LOWER_EYELID) + eye_contour = lm_to_px(LEFT_EYE if side == "left" else RIGHT_EYE) + + if len(lower_lid) < 3 or len(eye_contour) < 3: + continue + + # Under-eye region: expand lower eyelid downward + if "dark_circles" in operations: + result = self._remove_dark_circles( + result, lower_lid, width, height, dark_intensity + ) + + if "brighten_eyes" in operations: + iris = lm_to_px(LEFT_IRIS if side == "left" else RIGHT_IRIS) + result = self._brighten_eyes( + result, eye_contour, iris, brighten_intensity + ) + + if "sharpen_eyes" in operations: + result = self._sharpen_eyes( + result, eye_contour, sharpen_intensity + ) + + return result + + def _remove_dark_circles( + self, frame, lower_lid_points, width: int, height: int, intensity: float + ): + """Brighten the under-eye area to reduce dark circles.""" + import cv2 + import numpy as np + + # Create under-eye region by shifting lower eyelid points downward + under_eye = lower_lid_points.copy() + # Shift down by ~15% of face height (approximate eye-to-cheek distance) + shift = max(5, int(height * 0.025)) + under_eye_shifted = under_eye.copy() + under_eye_shifted[:, 1] += shift + + # Create polygon from lower lid + shifted points (forms a band) + polygon = np.vstack([lower_lid_points, under_eye_shifted[::-1]]) + + # Create soft mask + mask = np.zeros(frame.shape[:2], dtype=np.float32) + cv2.fillPoly(mask, [polygon], 1.0) + # Gaussian blur for soft edges + blur_size = max(15, int(width * 0.02)) | 1 # Ensure odd + mask = cv2.GaussianBlur(mask, (blur_size, blur_size), 0) + + # Apply brightening in LAB color space (perceptually uniform) + lab = cv2.cvtColor(frame, cv2.COLOR_BGR2LAB).astype(np.float32) + # Boost L channel (lightness) in the masked region + boost = 25 * intensity # 0-25 range + lab[:, :, 0] += mask * boost + lab[:, :, 0] = np.clip(lab[:, :, 0], 0, 255) + + # Also reduce saturation slightly (dark circles are often purplish) + hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV).astype(np.float32) + hsv[:, :, 1] -= mask * (20 * intensity) + hsv[:, :, 1] = np.clip(hsv[:, :, 1], 0, 255) + + # Blend: use LAB for brightness, HSV for desaturation + brightened = cv2.cvtColor(lab.astype(np.uint8), cv2.COLOR_LAB2BGR) + desaturated = cv2.cvtColor(hsv.astype(np.uint8), cv2.COLOR_HSV2BGR) + + # Combine: weighted blend of both adjustments + mask_3ch = np.stack([mask] * 3, axis=-1) + combined = frame.astype(np.float32) + combined = combined * (1 - mask_3ch * intensity) + \ + (brightened.astype(np.float32) * 0.6 + desaturated.astype(np.float32) * 0.4) * (mask_3ch * intensity) + + return np.clip(combined, 0, 255).astype(np.uint8) + + def _brighten_eyes(self, frame, eye_contour, iris_points, intensity: float): + """Subtly brighten the eye/sclera area.""" + import cv2 + import numpy as np + + if len(eye_contour) < 3: + return frame + + # Create mask from eye contour + mask = np.zeros(frame.shape[:2], dtype=np.float32) + cv2.fillPoly(mask, [eye_contour], 1.0) + blur_size = max(5, int(frame.shape[1] * 0.005)) | 1 + mask = cv2.GaussianBlur(mask, (blur_size, blur_size), 0) + + # Brighten in LAB space + lab = cv2.cvtColor(frame, cv2.COLOR_BGR2LAB).astype(np.float32) + boost = 15 * intensity + lab[:, :, 0] += mask * boost + lab[:, :, 0] = np.clip(lab[:, :, 0], 0, 255) + + brightened = cv2.cvtColor(lab.astype(np.uint8), cv2.COLOR_LAB2BGR) + + mask_3ch = np.stack([mask] * 3, axis=-1) + result = frame.astype(np.float32) * (1 - mask_3ch * intensity) + \ + brightened.astype(np.float32) * (mask_3ch * intensity) + + return np.clip(result, 0, 255).astype(np.uint8) + + def _sharpen_eyes(self, frame, eye_contour, intensity: float): + """Sharpen the eye region for more detail.""" + import cv2 + import numpy as np + + if len(eye_contour) < 3: + return frame + + # Create mask + mask = np.zeros(frame.shape[:2], dtype=np.float32) + cv2.fillPoly(mask, [eye_contour], 1.0) + # Expand slightly for natural blend + kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)) + mask = cv2.dilate(mask, kernel, iterations=1) + blur_size = max(5, int(frame.shape[1] * 0.005)) | 1 + mask = cv2.GaussianBlur(mask, (blur_size, blur_size), 0) + + # Unsharp mask for sharpening + blur = cv2.GaussianBlur(frame, (0, 0), 3) + sharpened = cv2.addWeighted(frame, 1.0 + intensity, blur, -intensity, 0) + + mask_3ch = np.stack([mask] * 3, axis=-1) + result = frame.astype(np.float32) * (1 - mask_3ch) + \ + sharpened.astype(np.float32) * mask_3ch + + return np.clip(result, 0, 255).astype(np.uint8) + + def _enhance_opencv_only( + self, input_path: Path, output_path: Path, inputs: dict[str, Any] + ) -> ToolResult: + """Fallback: OpenCV Haar cascade for face detection + generic eye region enhancement.""" + import cv2 + import numpy as np + + operations = inputs.get("operations", ["dark_circles", "brighten_eyes"]) + dark_intensity = inputs.get("dark_circle_intensity", 0.4) + crf = inputs.get("crf", 18) + + face_cascade = cv2.CascadeClassifier( + cv2.data.haarcascades + "haarcascade_frontalface_default.xml" + ) + eye_cascade = cv2.CascadeClassifier( + cv2.data.haarcascades + "haarcascade_eye.xml" + ) + + cap = cv2.VideoCapture(str(input_path)) + fps = cap.get(cv2.CAP_PROP_FPS) or 30.0 + width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) + height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) + + temp_video = output_path.parent / f".{output_path.stem}_temp.mp4" + fourcc = cv2.VideoWriter_fourcc(*"mp4v") + writer = cv2.VideoWriter(str(temp_video), fourcc, fps, (width, height)) + + frames_processed = 0 + frames_enhanced = 0 + + while cap.isOpened(): + ret, frame = cap.read() + if not ret: + break + + frames_processed += 1 + gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) + faces = face_cascade.detectMultiScale(gray, 1.1, 5, minSize=(60, 60)) + + if len(faces) > 0: + # Use largest face + areas = [w * h for (_, _, w, h) in faces] + fi = areas.index(max(areas)) + fx, fy, fw, fh = faces[fi] + + # Detect eyes within face region + face_roi_gray = gray[fy:fy + fh, fx:fx + fw] + eyes = eye_cascade.detectMultiScale(face_roi_gray, 1.1, 5, minSize=(20, 20)) + + for (ex, ey, ew, eh) in eyes: + # Under-eye region: below the detected eye box + under_y = fy + ey + eh + under_h = max(5, int(eh * 0.4)) + under_x = fx + ex + under_w = ew + + if under_y + under_h <= height and under_x + under_w <= width: + if "dark_circles" in operations: + # Create soft mask for under-eye + mask = np.zeros((height, width), dtype=np.float32) + cv2.ellipse( + mask, + (under_x + under_w // 2, under_y + under_h // 2), + (under_w // 2, under_h // 2), + 0, 0, 360, 1.0, -1, + ) + mask = cv2.GaussianBlur(mask, (15, 15), 0) + + lab = cv2.cvtColor(frame, cv2.COLOR_BGR2LAB).astype(np.float32) + lab[:, :, 0] += mask * (25 * dark_intensity) + lab[:, :, 0] = np.clip(lab[:, :, 0], 0, 255) + frame = cv2.cvtColor(lab.astype(np.uint8), cv2.COLOR_LAB2BGR) + + frames_enhanced += 1 + + writer.write(frame) + + cap.release() + writer.release() + + # Mux audio + cmd = [ + "ffmpeg", "-y", + "-i", str(temp_video), + "-i", str(input_path), + "-c:v", "libx264", "-crf", str(crf), "-preset", "fast", + "-c:a", "aac", "-b:a", "192k", + "-map", "0:v:0", "-map", "1:a:0?", + "-shortest", + str(output_path), + ] + + try: + self.run_command(cmd, timeout=600) + except Exception as e: + return ToolResult(success=False, error=f"Audio mux failed: {e}") + finally: + if temp_video.exists(): + temp_video.unlink() + + return ToolResult( + success=True, + data={ + "input": str(input_path), + "output": str(output_path), + "method": "opencv_haar_cascade", + "frames_processed": frames_processed, + "frames_enhanced": frames_enhanced, + "operations": operations, + }, + artifacts=[str(output_path)], + ) + + def _enhance_ffmpeg_fallback( + self, input_path: Path, output_path: Path, inputs: dict[str, Any] + ) -> ToolResult: + """Last resort: FFmpeg-only. Applies general face-area enhancement (not eye-specific).""" + crf = inputs.get("crf", 18) + intensity = inputs.get("dark_circle_intensity", 0.4) + + # General brightness + contrast lift for the whole frame + # Not eye-specific but better than nothing + brightness = 0.02 * intensity + contrast = 1.0 + (0.05 * intensity) + + cmd = [ + "ffmpeg", "-y", + "-i", str(input_path), + "-vf", f"eq=brightness={brightness}:contrast={contrast}", + "-c:v", "libx264", "-crf", str(crf), "-preset", "fast", + "-c:a", "copy", + str(output_path), + ] + + try: + self.run_command(cmd, timeout=600) + except Exception as e: + return ToolResult(success=False, error=f"FFmpeg fallback failed: {e}") + + return ToolResult( + success=True, + data={ + "input": str(input_path), + "output": str(output_path), + "method": "ffmpeg_global_brightness", + "operations": ["global_brightness_contrast"], + "note": "Install mediapipe + opencv-python for precise eye-region enhancement", + }, + artifacts=[str(output_path)], + ) + + def estimate_runtime(self, inputs: dict[str, Any]) -> float: + """Eye enhancement is roughly 0.5x-1x realtime depending on resolution.""" + return 90.0 diff --git a/tools/subtitle/subtitle_gen.py b/tools/subtitle/subtitle_gen.py index 6344352..ac8472b 100644 --- a/tools/subtitle/subtitle_gen.py +++ b/tools/subtitle/subtitle_gen.py @@ -60,6 +60,15 @@ class SubtitleGen(BaseTool): "enum": ["none", "word_by_word", "karaoke"], "default": "none", }, + "corrections": { + "type": "object", + "description": ( + "Dictionary of word corrections for common ASR misrecognitions. " + "Keys are the wrong word (case-insensitive), values are the " + "correct replacement. Applied before generating subtitles. " + "Example: {\"cloud\": \"Claude\", \"co-pilot\": \"Copilot\"}." + ), + }, }, } @@ -77,9 +86,14 @@ class SubtitleGen(BaseTool): max_chars = inputs.get("max_chars_per_line", 42) highlight_style = inputs.get("highlight_style", "none") output_path = inputs.get("output_path") + corrections = inputs.get("corrections") start = time.time() + # Apply word corrections if provided + if corrections: + segments = self._apply_corrections(segments, corrections) + # Build cues from word-level timestamps cues = self._build_cues(segments, max_words, max_chars) @@ -114,6 +128,43 @@ class SubtitleGen(BaseTool): duration_seconds=round(elapsed, 2), ) + @staticmethod + def _apply_corrections( + segments: list[dict], corrections: dict[str, str] + ) -> list[dict]: + """Apply word-level corrections to transcript segments. + + Handles case-insensitive matching and preserves punctuation. + """ + import copy + + corr = {k.lower(): v for k, v in corrections.items()} + result = copy.deepcopy(segments) + + for seg in result: + words = seg.get("words", []) + for w in words: + raw = w.get("word", "").strip() + # Strip punctuation for lookup, preserve it + stripped = raw.lower().rstrip(".,!?;:'\"") + if stripped in corr: + trailing = raw[len(stripped):] + w["word"] = corr[stripped] + trailing + # Also fix segment-level text + if "text" in seg and words: + seg["text"] = " ".join(w["word"] for w in words) + elif "text" in seg: + for wrong, right in corr.items(): + import re as _re + seg["text"] = _re.sub( + r"\b" + _re.escape(wrong) + r"\b", + right, + seg["text"], + flags=_re.IGNORECASE, + ) + + return result + def _build_cues( self, segments: list[dict], max_words: int, max_chars: int ) -> list[dict]: diff --git a/tools/video/auto_reframe.py b/tools/video/auto_reframe.py new file mode 100644 index 0000000..d054046 --- /dev/null +++ b/tools/video/auto_reframe.py @@ -0,0 +1,537 @@ +"""Auto-reframe tool for aspect ratio conversion with face tracking. + +Converts video between aspect ratios (e.g. 16:9 → 9:16 for Instagram Reels) +while keeping the speaker's face centered in frame. Uses face_tracker data +for smooth, content-aware cropping. + +Primary use: converting talking-head footage shot in landscape to vertical +format for social media (TikTok, Reels, Shorts). + +Approach: MediaPipe/OpenCV face detection → smoothed bounding box trajectory +→ FFmpeg crop filter. No GPU required. +""" + +from __future__ import annotations + +import json +import time +from pathlib import Path +from typing import Any + +from tools.base_tool import ( + BaseTool, + Determinism, + ExecutionMode, + ResourceProfile, + RetryPolicy, + ResumeSupport, + ToolResult, + ToolStability, + ToolTier, +) + + +# Common target aspect ratios +ASPECT_PRESETS = { + "portrait": (9, 16), # Instagram Reels, TikTok, YouTube Shorts + "square": (1, 1), # Instagram Feed + "landscape": (16, 9), # YouTube, LinkedIn + "cinematic": (21, 9), # Ultra-wide + "vertical_4_5": (4, 5), # Instagram portrait post +} + + +class AutoReframe(BaseTool): + name = "auto_reframe" + version = "0.1.0" + tier = ToolTier.CORE + capability = "video_post" + provider = "ffmpeg" + stability = ToolStability.EXPERIMENTAL + execution_mode = ExecutionMode.SYNC + determinism = Determinism.DETERMINISTIC + + dependencies = ["cmd:ffmpeg"] + install_instructions = ( + "FFmpeg is required. For face-tracked reframing, also install:\n" + "pip install mediapipe opencv-python\n\n" + "Without MediaPipe/OpenCV, falls back to center-crop." + ) + agent_skills = ["ffmpeg"] + + capabilities = [ + "aspect_ratio_conversion", + "face_tracked_crop", + "smart_reframe", + "center_crop", + ] + + input_schema = { + "type": "object", + "required": ["input_path"], + "properties": { + "input_path": {"type": "string"}, + "output_path": {"type": "string"}, + "target_aspect": { + "type": "string", + "enum": list(ASPECT_PRESETS.keys()), + "default": "portrait", + "description": "Target aspect ratio preset", + }, + "target_width": { + "type": "integer", + "description": "Explicit target width (overrides preset)", + }, + "target_height": { + "type": "integer", + "description": "Explicit target height (overrides preset)", + }, + "face_tracking_json": { + "type": "string", + "description": "Path to pre-computed face_tracker JSON. If omitted, runs face detection internally.", + }, + "smoothing_window": { + "type": "integer", + "default": 15, + "minimum": 1, + "description": "Number of frames for position smoothing (higher = smoother pan, lower = more responsive)", + }, + "face_padding": { + "type": "number", + "default": 0.4, + "minimum": 0.0, + "maximum": 1.0, + "description": "Extra space around face as fraction of face size (0.4 = 40% padding)", + }, + "sample_fps": { + "type": "number", + "default": 5, + "description": "Face detection sample rate (only used if no face_tracking_json)", + }, + "codec": {"type": "string", "default": "libx264"}, + "crf": {"type": "integer", "default": 18}, + }, + } + + resource_profile = ResourceProfile( + cpu_cores=4, ram_mb=2048, vram_mb=0, disk_mb=4000, network_required=False + ) + retry_policy = RetryPolicy(max_retries=1, retryable_errors=["FFmpeg error"]) + resume_support = ResumeSupport.FROM_START + idempotency_key_fields = [ + "input_path", "target_aspect", "target_width", "target_height", + "smoothing_window", "face_padding", + ] + side_effects = ["writes reframed video to output_path"] + user_visible_verification = [ + "Play reframed output — verify face stays centered and framing is smooth", + "Check that no important content is cropped out", + ] + + def execute(self, inputs: dict[str, Any]) -> ToolResult: + input_path = Path(inputs["input_path"]) + if not input_path.exists(): + return ToolResult(success=False, error=f"Input not found: {input_path}") + + start = time.time() + + # Get source video dimensions + src_w, src_h, src_fps = self._get_video_info(input_path) + if src_w == 0 or src_h == 0: + return ToolResult(success=False, error="Could not read video dimensions") + + # Determine target crop dimensions (in source pixel space) + target_w, target_h = self._compute_crop_size(inputs, src_w, src_h) + + # If source already matches target aspect, no crop needed + if target_w == src_w and target_h == src_h: + return ToolResult( + success=True, + data={"message": "Source already matches target aspect ratio", "output": str(input_path)}, + artifacts=[str(input_path)], + ) + + # Get face tracking data + face_data = self._get_face_data(inputs, input_path, src_fps) + + # Compute per-frame crop positions + if face_data and len(face_data) > 0: + crop_x, crop_y = self._compute_face_tracked_crop( + face_data, src_w, src_h, target_w, target_h, + src_fps, + inputs.get("smoothing_window", 15), + inputs.get("face_padding", 0.4), + ) + method = "face_tracked" + else: + # Fallback: center crop + crop_x = (src_w - target_w) // 2 + crop_y = (src_h - target_h) // 2 + method = "center_crop" + + # Determine output resolution + out_w, out_h = self._compute_output_resolution(inputs, target_w, target_h, src_w, src_h) + + # Build output path + aspect_name = inputs.get("target_aspect", "portrait") + output_path = Path( + inputs.get("output_path", str(input_path.with_stem(f"{input_path.stem}_{aspect_name}"))) + ) + output_path.parent.mkdir(parents=True, exist_ok=True) + + # Render via FFmpeg + codec = inputs.get("codec", "libx264") + crf = inputs.get("crf", 18) + + if method == "face_tracked" and isinstance(crop_x, list): + # Dynamic crop: write crop coordinates to a file and use sendcmd + result = self._render_dynamic_crop( + input_path, output_path, crop_x, crop_y, + target_w, target_h, out_w, out_h, + src_fps, codec, crf, + ) + else: + # Static crop + result = self._render_static_crop( + input_path, output_path, + crop_x, crop_y, target_w, target_h, + out_w, out_h, codec, crf, + ) + + if not result.success: + return result + + elapsed = time.time() - start + + return ToolResult( + success=True, + data={ + "input": str(input_path), + "output": str(output_path), + "source_resolution": f"{src_w}x{src_h}", + "crop_resolution": f"{target_w}x{target_h}", + "output_resolution": f"{out_w}x{out_h}", + "method": method, + "target_aspect": inputs.get("target_aspect", "portrait"), + }, + artifacts=[str(output_path)], + duration_seconds=round(elapsed, 2), + ) + + def _get_video_info(self, path: Path) -> tuple[int, int, float]: + """Get video width, height, fps via ffprobe.""" + cmd = [ + "ffprobe", "-v", "quiet", + "-select_streams", "v:0", + "-show_entries", "stream=width,height,r_frame_rate", + "-of", "json", str(path), + ] + try: + result = self.run_command(cmd) + data = json.loads(result.stdout) + stream = data["streams"][0] + w = int(stream["width"]) + h = int(stream["height"]) + # Parse r_frame_rate (e.g. "30000/1001") + fps_parts = stream["r_frame_rate"].split("/") + fps = float(fps_parts[0]) / float(fps_parts[1]) if len(fps_parts) == 2 else float(fps_parts[0]) + return w, h, fps + except Exception: + return 0, 0, 30.0 + + def _compute_crop_size( + self, inputs: dict[str, Any], src_w: int, src_h: int + ) -> tuple[int, int]: + """Compute crop dimensions in source pixel space that match the target aspect ratio.""" + if "target_width" in inputs and "target_height" in inputs: + # Explicit dimensions — compute crop in source space matching this ratio + tw, th = inputs["target_width"], inputs["target_height"] + else: + aspect_name = inputs.get("target_aspect", "portrait") + tw, th = ASPECT_PRESETS.get(aspect_name, (9, 16)) + + target_ratio = tw / th + src_ratio = src_w / src_h + + if target_ratio > src_ratio: + # Target is wider — crop height + crop_w = src_w + crop_h = int(src_w / target_ratio) + else: + # Target is taller/narrower — crop width + crop_h = src_h + crop_w = int(src_h * target_ratio) + + # Ensure even dimensions (required by most codecs) + crop_w = crop_w - (crop_w % 2) + crop_h = crop_h - (crop_h % 2) + + return crop_w, crop_h + + def _compute_output_resolution( + self, inputs: dict[str, Any], + crop_w: int, crop_h: int, + src_w: int, src_h: int, + ) -> tuple[int, int]: + """Determine final output resolution. Scales to standard sizes.""" + if "target_width" in inputs and "target_height" in inputs: + out_w = inputs["target_width"] + out_h = inputs["target_height"] + else: + aspect_name = inputs.get("target_aspect", "portrait") + if aspect_name == "portrait": + out_w, out_h = 1080, 1920 + elif aspect_name == "square": + out_w, out_h = 1080, 1080 + elif aspect_name == "landscape": + out_w, out_h = 1920, 1080 + elif aspect_name == "cinematic": + out_w, out_h = 2560, 1080 + elif aspect_name == "vertical_4_5": + out_w, out_h = 1080, 1350 + else: + out_w, out_h = crop_w, crop_h + + # Ensure even + out_w = out_w - (out_w % 2) + out_h = out_h - (out_h % 2) + return out_w, out_h + + def _get_face_data( + self, inputs: dict[str, Any], input_path: Path, src_fps: float + ) -> list[dict]: + """Get face tracking data — from pre-computed JSON or by running detection.""" + # Check for pre-computed tracking data + tracking_json = inputs.get("face_tracking_json") + if tracking_json: + p = Path(tracking_json) + if p.exists(): + data = json.loads(p.read_text(encoding="utf-8")) + return data.get("faces", []) + + # Try to run face_tracker internally + try: + from tools.analysis.face_tracker import FaceTracker + tracker = FaceTracker() + if tracker.get_status().name == "UNAVAILABLE": + return [] + sample_fps = inputs.get("sample_fps", 5) + result = tracker.execute({ + "input_path": str(input_path), + "sample_fps": sample_fps, + }) + if result.success and result.data: + # Read the generated JSON + output_file = result.data.get("output") + if output_file: + data = json.loads(Path(output_file).read_text(encoding="utf-8")) + return data.get("faces", []) + except Exception: + pass + + return [] + + def _compute_face_tracked_crop( + self, + faces: list[dict], + src_w: int, src_h: int, + crop_w: int, crop_h: int, + fps: float, + smoothing_window: int, + face_padding: float, + ) -> tuple[list[int], list[int]]: + """Compute smoothed crop positions from face tracking data. + + Returns a single (x, y) if face positions are stable enough, + or lists of per-frame positions for dynamic cropping. + """ + if not faces: + cx = (src_w - crop_w) // 2 + cy = (src_h - crop_h) // 2 + return cx, cy + + # Convert relative bbox centers to pixel positions + face_centers_x = [] + face_centers_y = [] + face_timestamps = [] + + for f in faces: + bbox = f["bbox"] + # Center of face in pixel space + center_x = (bbox["x"] + bbox["width"] / 2) * src_w + center_y = (bbox["y"] + bbox["height"] / 2) * src_h + face_centers_x.append(center_x) + face_centers_y.append(center_y) + face_timestamps.append(f["timestamp_seconds"]) + + # Check if face position is stable (talking head usually is) + x_range = max(face_centers_x) - min(face_centers_x) + y_range = max(face_centers_y) - min(face_centers_y) + + # If face barely moves (<10% of frame), use a single static crop + if x_range < src_w * 0.10 and y_range < src_h * 0.10: + avg_x = sum(face_centers_x) / len(face_centers_x) + avg_y = sum(face_centers_y) / len(face_centers_y) + + # Position crop window centered on face, with bias toward upper third + crop_x = int(avg_x - crop_w / 2) + crop_y = int(avg_y - crop_h * 0.35) # Face in upper 35% of frame + + # Clamp to frame bounds + crop_x = max(0, min(crop_x, src_w - crop_w)) + crop_y = max(0, min(crop_y, src_h - crop_h)) + + return crop_x, crop_y + + # Dynamic crop: smooth the trajectory + smoothed_x = self._smooth_positions(face_centers_x, smoothing_window) + smoothed_y = self._smooth_positions(face_centers_y, smoothing_window) + + # Convert to crop positions (top-left corner), clamped + crop_xs = [] + crop_ys = [] + for sx, sy in zip(smoothed_x, smoothed_y): + cx = int(sx - crop_w / 2) + cy = int(sy - crop_h * 0.35) + cx = max(0, min(cx, src_w - crop_w)) + cy = max(0, min(cy, src_h - crop_h)) + crop_xs.append(cx) + crop_ys.append(cy) + + return crop_xs, crop_ys + + def _smooth_positions(self, values: list[float], window: int) -> list[float]: + """Simple moving average smoothing.""" + smoothed = [] + for i in range(len(values)): + start = max(0, i - window // 2) + end = min(len(values), i + window // 2 + 1) + smoothed.append(sum(values[start:end]) / (end - start)) + return smoothed + + def _render_static_crop( + self, + input_path: Path, output_path: Path, + crop_x: int, crop_y: int, + crop_w: int, crop_h: int, + out_w: int, out_h: int, + codec: str, crf: int, + ) -> ToolResult: + """Render with a static crop position.""" + vf = f"crop={crop_w}:{crop_h}:{crop_x}:{crop_y},scale={out_w}:{out_h}" + + cmd = [ + "ffmpeg", "-y", + "-i", str(input_path), + "-vf", vf, + "-c:v", codec, "-crf", str(crf), "-preset", "fast", + "-c:a", "aac", "-b:a", "192k", + str(output_path), + ] + + try: + self.run_command(cmd, timeout=600) + except Exception as e: + return ToolResult(success=False, error=f"FFmpeg render failed: {e}") + + return ToolResult(success=True) + + def _render_dynamic_crop( + self, + input_path: Path, output_path: Path, + crop_xs: list[int], crop_ys: list[int], + crop_w: int, crop_h: int, + out_w: int, out_h: int, + fps: float, + codec: str, crf: int, + ) -> ToolResult: + """Render with dynamic crop positions that follow the face. + + Uses FFmpeg's sendcmd filter to update crop position over time. + For simplicity and reliability, we interpolate between key positions + using FFmpeg expression-based crop. + """ + # Build a piecewise-linear x(t) and y(t) using FFmpeg expressions + # We'll sample at the face tracking rate and interpolate between points + if not crop_xs: + return ToolResult(success=False, error="No crop positions computed") + + # If very few data points, fall back to static using average + if len(crop_xs) < 3: + avg_x = int(sum(crop_xs) / len(crop_xs)) + avg_y = int(sum(crop_ys) / len(crop_ys)) + return self._render_static_crop( + input_path, output_path, avg_x, avg_y, + crop_w, crop_h, out_w, out_h, codec, crf, + ) + + # Build sendcmd script for crop filter position updates + # Each command sets the crop x,y at the corresponding timestamp + temp_dir = output_path.parent / ".reframe_tmp" + temp_dir.mkdir(parents=True, exist_ok=True) + sendcmd_path = temp_dir / "crop_commands.txt" + + # Approximate timestamps from the face tracking sample rate + # The face data was sampled at sample_fps intervals + sample_interval = 1.0 / (fps / max(1, int(fps / 5))) # Approximate + + lines = [] + for i, (cx, cy) in enumerate(zip(crop_xs, crop_ys)): + ts = i * sample_interval + lines.append(f"{ts:.3f} [enter] crop x {cx};") + lines.append(f"{ts:.3f} [enter] crop y {cy};") + + sendcmd_path.write_text("\n".join(lines), encoding="utf-8") + + # Use crop with sendcmd for dynamic positioning + vf = ( + f"sendcmd=f='{str(sendcmd_path).replace(chr(92), '/')}':flags=enter," + f"crop={crop_w}:{crop_h}:{crop_xs[0]}:{crop_ys[0]}," + f"scale={out_w}:{out_h}" + ) + + cmd = [ + "ffmpeg", "-y", + "-i", str(input_path), + "-vf", vf, + "-c:v", codec, "-crf", str(crf), "-preset", "fast", + "-c:a", "aac", "-b:a", "192k", + str(output_path), + ] + + try: + self.run_command(cmd, timeout=600) + except Exception: + # sendcmd can be finicky — fall back to static crop with average position + avg_x = int(sum(crop_xs) / len(crop_xs)) + avg_y = int(sum(crop_ys) / len(crop_ys)) + result = self._render_static_crop( + input_path, output_path, avg_x, avg_y, + crop_w, crop_h, out_w, out_h, codec, crf, + ) + if result.success: + result.data = result.data or {} + result.data["fallback"] = "sendcmd failed, used static average crop" + return result + finally: + # Clean up + if sendcmd_path.exists(): + sendcmd_path.unlink() + try: + temp_dir.rmdir() + except OSError: + pass + + return ToolResult(success=True) + + def estimate_runtime(self, inputs: dict[str, Any]) -> float: + """Estimate runtime in seconds. Roughly 1x realtime for face tracking + render.""" + return 60.0 # Conservative default + + @staticmethod + def list_presets() -> dict[str, str]: + """Return available aspect ratio presets.""" + return { + name: f"{w}:{h}" + for name, (w, h) in ASPECT_PRESETS.items() + } diff --git a/tools/video/remotion_caption_burn.py b/tools/video/remotion_caption_burn.py new file mode 100644 index 0000000..6824e69 --- /dev/null +++ b/tools/video/remotion_caption_burn.py @@ -0,0 +1,439 @@ +"""Remotion caption burn tool. + +Renders animated word-by-word captions onto a talking-head video using +the Remotion CaptionOverlay component. Falls back to FFmpeg subtitle +burning if Remotion is not available. + +The tool: +1. Converts word-level transcript segments to Remotion WordCaption JSON +2. Writes a props file for the TalkingHead composition +3. Renders via ``npx remotion render`` +4. Returns the captioned video path + +Fallback: if Remotion is unavailable, burns subtitles at the bottom of +the frame using FFmpeg's ``subtitles`` filter with bold styling. +""" + +from __future__ import annotations + +import json +import math +import re +import shutil +import time +from pathlib import Path +from typing import Any + +from tools.base_tool import ( + BaseTool, + Determinism, + ExecutionMode, + ResourceProfile, + ToolResult, + ToolStability, + ToolTier, +) + + +class RemotionCaptionBurn(BaseTool): + name = "remotion_caption_burn" + version = "0.1.0" + tier = ToolTier.CORE + capability = "subtitle" + provider = "remotion" + stability = ToolStability.EXPERIMENTAL + execution_mode = ExecutionMode.SYNC + determinism = Determinism.DETERMINISTIC + + dependencies = ["cmd:ffmpeg", "cmd:ffprobe"] + install_instructions = ( + "Remotion (optional, preferred): npm install in remotion-composer/\n" + "FFmpeg (required for fallback): https://ffmpeg.org/download.html" + ) + agent_skills = ["remotion-best-practices", "ffmpeg"] + + capabilities = [ + "burn_remotion_captions", + "burn_ffmpeg_captions_fallback", + ] + + input_schema = { + "type": "object", + "required": ["input_path", "output_path"], + "properties": { + "input_path": { + "type": "string", + "description": "Path to the input video (enhanced talking-head footage).", + }, + "output_path": { + "type": "string", + "description": "Path for the output video with captions burned in.", + }, + "segments": { + "type": "array", + "description": ( + "Word-level transcript segments from transcriber tool. " + "Each segment has 'words' array with {word, start, end}." + ), + }, + "srt_path": { + "type": "string", + "description": ( + "Path to an SRT file. Used as an alternative to segments. " + "If both provided, segments take priority." + ), + }, + "words_per_page": { + "type": "integer", + "default": 4, + "description": "Words shown at once in the caption overlay.", + }, + "font_size": { + "type": "integer", + "default": 52, + "description": "Font size for captions.", + }, + "highlight_color": { + "type": "string", + "default": "#22D3EE", + "description": "Highlight color for the active word (hex).", + }, + "corrections": { + "type": "object", + "description": ( + "Dictionary of word corrections for common misrecognitions. " + "Keys are the wrong word (case-insensitive), values are the " + "correct replacement. Example: {\"cloud\": \"Claude\"}." + ), + }, + "force_ffmpeg": { + "type": "boolean", + "default": False, + "description": "Force FFmpeg fallback even if Remotion is available.", + }, + }, + } + + resource_profile = ResourceProfile(cpu_cores=4, ram_mb=2048, vram_mb=0, disk_mb=500) + idempotency_key_fields = ["input_path", "segments", "srt_path"] + side_effects = ["writes captioned video to output_path"] + user_visible_verification = [ + "Play the output video and verify captions appear at the bottom of the frame", + "Check that the active word is highlighted in the specified color", + "Verify face is not occluded by caption text", + ] + + # ------------------------------------------------------------------ # + # Remotion detection + # ------------------------------------------------------------------ # + + def _find_remotion_root(self) -> Path | None: + """Find the remotion-composer directory relative to the repo.""" + candidates = [ + Path.cwd() / "remotion-composer", + Path(__file__).resolve().parent.parent.parent / "remotion-composer", + ] + for p in candidates: + if ( + p.is_dir() + and (p / "package.json").exists() + and (p / "node_modules").is_dir() + ): + return p + return None + + def _remotion_available(self) -> bool: + return ( + shutil.which("npx") is not None + and self._find_remotion_root() is not None + ) + + # ------------------------------------------------------------------ # + # Word caption conversion + # ------------------------------------------------------------------ # + + def _segments_to_word_captions( + self, segments: list[dict], corrections: dict[str, str] | None = None + ) -> list[dict]: + """Convert transcriber segments to [{word, startMs, endMs}, ...].""" + captions: list[dict] = [] + corr = {k.lower(): v for k, v in (corrections or {}).items()} + + for seg in segments: + words = seg.get("words", []) + if words: + for w in words: + raw = w["word"].strip() + fixed = corr.get(raw.lower().strip(".,!?;:"), raw) + # Preserve trailing punctuation from original + trailing = "" + if raw and raw[-1] in ".,!?;:": + trailing = raw[-1] + if fixed != raw and not fixed.endswith(trailing): + fixed = fixed + trailing + captions.append({ + "word": fixed, + "startMs": int(w["start"] * 1000), + "endMs": int(w["end"] * 1000), + }) + elif "text" in seg: + text_words = seg["text"].strip().split() + dur = seg["end"] - seg["start"] + per_word = dur / max(len(text_words), 1) + for i, tw in enumerate(text_words): + fixed = corr.get(tw.lower().strip(".,!?;:"), tw) + captions.append({ + "word": fixed, + "startMs": int((seg["start"] + i * per_word) * 1000), + "endMs": int((seg["start"] + (i + 1) * per_word) * 1000), + }) + return captions + + def _srt_to_word_captions( + self, srt_path: str, corrections: dict[str, str] | None = None + ) -> list[dict]: + """Parse SRT file into word captions.""" + content = Path(srt_path).read_text(encoding="utf-8") + blocks = re.split(r"\n\n+", content.strip()) + corr = {k.lower(): v for k, v in (corrections or {}).items()} + captions: list[dict] = [] + + for block in blocks: + lines = block.strip().split("\n") + if len(lines) < 3: + continue + m = re.match( + r"(\d{2}):(\d{2}):(\d{2}),(\d{3})\s*-->\s*" + r"(\d{2}):(\d{2}):(\d{2}),(\d{3})", + lines[1], + ) + if not m: + continue + start_ms = ( + int(m.group(1)) * 3600000 + + int(m.group(2)) * 60000 + + int(m.group(3)) * 1000 + + int(m.group(4)) + ) + end_ms = ( + int(m.group(5)) * 3600000 + + int(m.group(6)) * 60000 + + int(m.group(7)) * 1000 + + int(m.group(8)) + ) + text = " ".join(lines[2:]).strip() + words = text.split() + per_word = (end_ms - start_ms) / max(len(words), 1) + for i, w in enumerate(words): + fixed = corr.get(w.lower().strip(".,!?;:"), w) + captions.append({ + "word": fixed, + "startMs": int(start_ms + i * per_word), + "endMs": int(start_ms + (i + 1) * per_word), + }) + return captions + + # ------------------------------------------------------------------ # + # Remotion render + # ------------------------------------------------------------------ # + + def _render_remotion( + self, + input_path: str, + output_path: str, + captions: list[dict], + words_per_page: int, + font_size: int, + highlight_color: str, + ) -> ToolResult: + root = self._find_remotion_root() + if root is None: + return ToolResult(success=False, error="Remotion root not found") + + # Get video duration in frames + dur_cmd = [ + "ffprobe", "-v", "error", + "-show_entries", "format=duration", + "-of", "csv=p=0", + input_path, + ] + dur_out = self.run_command(dur_cmd, capture=True) + duration_s = float(dur_out.strip().split("\n")[0]) + total_frames = math.ceil(duration_s * 30) + + # Copy video to Remotion public folder + pub_dir = root / "public" / "talking-head" + pub_dir.mkdir(parents=True, exist_ok=True) + video_filename = Path(input_path).name + dest_video = pub_dir / video_filename + shutil.copy2(input_path, dest_video) + + # Build props JSON + props = { + "videoSrc": f"public/talking-head/{video_filename}", + "captions": captions, + "wordsPerPage": words_per_page, + "fontSize": font_size, + "highlightColor": highlight_color, + } + props_dir = root / "public" / "demo-props" + props_dir.mkdir(parents=True, exist_ok=True) + props_file = props_dir / f"caption-burn-{Path(input_path).stem}.json" + props_file.write_text(json.dumps(props, indent=2), encoding="utf-8") + + # Render + render_cmd = [ + "npx", "remotion", "render", + "src/index.tsx", "TalkingHead", + f"--props={props_file.relative_to(root)}", + "--width=1080", "--height=1920", "--fps=30", + f"--frames=0-{total_frames - 1}", + "--codec=h264", "--crf=18", + str(Path(output_path).resolve()), + ] + self.run_command(render_cmd, cwd=str(root)) + + if not Path(output_path).exists(): + return ToolResult(success=False, error="Remotion render produced no output") + + return ToolResult( + success=True, + data={ + "method": "remotion", + "output": output_path, + "duration_seconds": round(duration_s, 2), + "total_frames": total_frames, + "caption_count": len(captions), + "words_per_page": words_per_page, + }, + artifacts=[output_path], + ) + + # ------------------------------------------------------------------ # + # FFmpeg fallback + # ------------------------------------------------------------------ # + + def _render_ffmpeg( + self, + input_path: str, + output_path: str, + captions: list[dict], + ) -> ToolResult: + """Fall back to FFmpeg subtitle burning at bottom of frame.""" + # Generate temporary SRT from word captions + tmp_srt = Path(output_path).parent / f"_tmp_captions_{int(time.time())}.srt" + tmp_srt.parent.mkdir(parents=True, exist_ok=True) + + srt_lines = [] + idx = 1 + # Group into pages of ~4 words + page_size = 4 + for i in range(0, len(captions), page_size): + page = captions[i : i + page_size] + text = " ".join(c["word"] for c in page) + start = page[0]["startMs"] + end = page[-1]["endMs"] + srt_lines.append(str(idx)) + srt_lines.append( + f"{self._ms_to_srt(start)} --> {self._ms_to_srt(end)}" + ) + srt_lines.append(text) + srt_lines.append("") + idx += 1 + + tmp_srt.write_text("\n".join(srt_lines), encoding="utf-8") + + # Escape path for FFmpeg subtitles filter (Windows colon issue) + srt_escaped = str(tmp_srt).replace("\\", "/").replace(":", "\\:") + + cmd = [ + "ffmpeg", "-y", + "-i", input_path, + "-vf", ( + f"subtitles='{srt_escaped}'" + ":force_style='FontName=Segoe UI,FontSize=24,Bold=1," + "PrimaryColour=&H00FFFFFF,OutlineColour=&H00000000," + "Outline=3,Shadow=2,Alignment=2,MarginV=100'" + ), + "-c:v", "libx264", "-preset", "fast", "-crf", "18", + "-pix_fmt", "yuv420p", + "-c:a", "copy", + output_path, + ] + self.run_command(cmd) + + # Clean up temp SRT + try: + tmp_srt.unlink() + except OSError: + pass + + if not Path(output_path).exists(): + return ToolResult(success=False, error="FFmpeg subtitle burn produced no output") + + return ToolResult( + success=True, + data={ + "method": "ffmpeg_fallback", + "output": output_path, + "caption_count": len(captions), + "note": "Used FFmpeg fallback. Install Remotion for animated captions.", + }, + artifacts=[output_path], + ) + + @staticmethod + def _ms_to_srt(ms: int) -> str: + h = ms // 3600000 + m = (ms % 3600000) // 60000 + s = (ms % 60000) // 1000 + rem = ms % 1000 + return f"{h:02d}:{m:02d}:{s:02d},{rem:03d}" + + # ------------------------------------------------------------------ # + # Main execute + # ------------------------------------------------------------------ # + + def execute(self, inputs: dict[str, Any]) -> ToolResult: + input_path = inputs["input_path"] + output_path = inputs["output_path"] + corrections = inputs.get("corrections") + force_ffmpeg = inputs.get("force_ffmpeg", False) + words_per_page = inputs.get("words_per_page", 4) + font_size = inputs.get("font_size", 52) + highlight_color = inputs.get("highlight_color", "#22D3EE") + + if not Path(input_path).exists(): + return ToolResult(success=False, error=f"Input video not found: {input_path}") + + Path(output_path).parent.mkdir(parents=True, exist_ok=True) + start = time.time() + + # Build word captions from segments or SRT + segments = inputs.get("segments") + srt_path = inputs.get("srt_path") + + if segments: + captions = self._segments_to_word_captions(segments, corrections) + elif srt_path: + captions = self._srt_to_word_captions(srt_path, corrections) + else: + return ToolResult( + success=False, + error="Provide either 'segments' (from transcriber) or 'srt_path'.", + ) + + if not captions: + return ToolResult(success=False, error="No caption words extracted.") + + # Choose render method + if not force_ffmpeg and self._remotion_available(): + result = self._render_remotion( + input_path, output_path, captions, + words_per_page, font_size, highlight_color, + ) + else: + result = self._render_ffmpeg(input_path, output_path, captions) + + result.duration_seconds = round(time.time() - start, 2) + return result diff --git a/tools/video/showcase_card.py b/tools/video/showcase_card.py new file mode 100644 index 0000000..ec0f3f4 --- /dev/null +++ b/tools/video/showcase_card.py @@ -0,0 +1,226 @@ +"""Showcase card tool wrapping FFmpeg. + +Creates a presentation-ready 9:16 card from a source video: letterboxes +the content, adds a bold title at the top, a subtitle description at the +bottom, and a dark background. Designed for Instagram Reels / TikTok +showcase segments. +""" + +from __future__ import annotations + +import time +from pathlib import Path +from typing import Any + +from tools.base_tool import ( + BaseTool, + Determinism, + ExecutionMode, + ResourceProfile, + ToolResult, + ToolStability, + ToolTier, +) + + +class ShowcaseCard(BaseTool): + name = "showcase_card" + version = "0.1.0" + tier = ToolTier.CORE + capability = "video_post" + provider = "ffmpeg" + stability = ToolStability.EXPERIMENTAL + execution_mode = ExecutionMode.SYNC + determinism = Determinism.DETERMINISTIC + + dependencies = ["cmd:ffmpeg", "cmd:ffprobe"] + install_instructions = "Install FFmpeg: https://ffmpeg.org/download.html" + agent_skills = ["ffmpeg", "video_toolkit"] + + capabilities = ["create_showcase_card"] + + input_schema = { + "type": "object", + "required": ["input_path", "output_path", "title"], + "properties": { + "input_path": { + "type": "string", + "description": "Path to the source video.", + }, + "output_path": { + "type": "string", + "description": "Path for the output showcase card video.", + }, + "title": { + "type": "string", + "description": "Bold title text displayed at the top of the card.", + }, + "subtitle": { + "type": "string", + "default": "", + "description": "Subtitle text displayed at the bottom of the card.", + }, + "output_width": { + "type": "integer", + "default": 1080, + "description": "Output width in pixels.", + }, + "output_height": { + "type": "integer", + "default": 1920, + "description": "Output height in pixels.", + }, + "background_color": { + "type": "string", + "default": "0x0A0F1A", + "description": "Background color in hex (FFmpeg format, e.g. 0x0A0F1A).", + }, + "title_font": { + "type": "string", + "default": "segoeuib.ttf", + "description": "Font file for the title. Uses system font lookup.", + }, + "title_font_size": { + "type": "integer", + "default": 52, + "description": "Font size for the title.", + }, + "subtitle_font_size": { + "type": "integer", + "default": 28, + "description": "Font size for the subtitle.", + }, + "title_color": { + "type": "string", + "default": "white", + "description": "Title text color.", + }, + "watermark": { + "type": "string", + "default": "", + "description": "Optional watermark text overlaid on the video (e.g. brand name).", + }, + }, + } + + resource_profile = ResourceProfile(cpu_cores=2, ram_mb=1024, vram_mb=0, disk_mb=500) + idempotency_key_fields = ["input_path", "title", "subtitle"] + side_effects = ["writes showcase card video to output_path"] + user_visible_verification = [ + "Play output and verify title, subtitle, and video are positioned correctly", + "Verify the video content is fully visible (not cropped)", + ] + + def execute(self, inputs: dict[str, Any]) -> ToolResult: + input_path = inputs["input_path"] + output_path = inputs["output_path"] + title = inputs["title"] + subtitle = inputs.get("subtitle", "") + out_w = inputs.get("output_width", 1080) + out_h = inputs.get("output_height", 1920) + bg_color = inputs.get("background_color", "0x0A0F1A") + title_font = inputs.get("title_font", "segoeuib.ttf") + title_font_size = inputs.get("title_font_size", 52) + subtitle_font_size = inputs.get("subtitle_font_size", 28) + title_color = inputs.get("title_color", "white") + watermark = inputs.get("watermark", "") + + if not Path(input_path).exists(): + return ToolResult(success=False, error=f"Input not found: {input_path}") + + Path(output_path).parent.mkdir(parents=True, exist_ok=True) + start = time.time() + + # Get source dimensions + probe_cmd = [ + "ffprobe", "-v", "error", + "-select_streams", "v:0", + "-show_entries", "stream=width,height", + "-of", "csv=p=0", + input_path, + ] + probe_out = self.run_command(probe_cmd, capture=True).strip() + src_w, src_h = [int(x.strip()) for x in probe_out.split(",")[:2]] + + # Calculate letterbox dimensions — fit source into output width, + # center vertically in the frame. + scale_factor = out_w / src_w + scaled_h = int(src_h * scale_factor) + # Ensure even dimensions + scaled_h = scaled_h if scaled_h % 2 == 0 else scaled_h + 1 + pad_y = (out_h - scaled_h) // 2 + + # Build filter chain + filters = [ + f"scale={out_w}:{scaled_h}", + f"pad={out_w}:{out_h}:0:{pad_y}:color={bg_color}", + ] + + # Title text at top + title_escaped = title.replace("'", "\\'").replace(":", "\\:") + filters.append( + f"drawtext=text='{title_escaped}'" + f":fontfile='{title_font}'" + f":fontsize={title_font_size}" + f":fontcolor={title_color}" + f":borderw=3:bordercolor=black" + f":x=(w-text_w)/2:y=60" + ) + + # Subtitle text at bottom + if subtitle: + sub_escaped = subtitle.replace("'", "\\'").replace(":", "\\:") + filters.append( + f"drawtext=text='{sub_escaped}'" + f":fontfile='segoeui.ttf'" + f":fontsize={subtitle_font_size}" + f":fontcolor=white@0.85" + f":x=(w-text_w)/2:y=h-100" + ) + + # Watermark centered on video + if watermark: + wm_escaped = watermark.replace("'", "\\'").replace(":", "\\:") + filters.append( + f"drawtext=text='{wm_escaped}'" + f":fontfile='segoeui.ttf'" + f":fontsize=36" + f":fontcolor=white@0.3" + f":x=(w-text_w)/2:y=(h-text_h)/2" + ) + + vf = ",".join(filters) + + cmd = [ + "ffmpeg", "-y", + "-i", input_path, + "-vf", vf, + "-c:v", "libx264", "-preset", "fast", "-crf", "18", + "-pix_fmt", "yuv420p", + "-c:a", "aac", "-b:a", "192k", + output_path, + ] + + try: + self.run_command(cmd) + except Exception as e: + return ToolResult(success=False, error=f"FFmpeg failed: {e}") + + if not Path(output_path).exists(): + return ToolResult(success=False, error="No output produced") + + elapsed = round(time.time() - start, 2) + + return ToolResult( + success=True, + data={ + "output": output_path, + "source_resolution": f"{src_w}x{src_h}", + "output_resolution": f"{out_w}x{out_h}", + "title": title, + "subtitle": subtitle, + "letterbox_y_offset": pad_y, + }, + artifacts=[output_path], + duration_seconds=elapsed, + ) diff --git a/tools/video/silence_cutter.py b/tools/video/silence_cutter.py new file mode 100644 index 0000000..922b1d6 --- /dev/null +++ b/tools/video/silence_cutter.py @@ -0,0 +1,481 @@ +"""Silence cutter tool for automatic jump cuts. + +Detects silent segments in talking-head footage and removes them, +creating tight jump cuts. Uses FFmpeg's silencedetect filter — no +external dependencies beyond FFmpeg. + +Modes: + - remove: Cut out silent segments entirely (jump cut) + - speed_up: Speed up silent segments instead of cutting (less jarring) + - mark: Don't cut — just output silence timestamps for manual review +""" + +from __future__ import annotations + +import json +import re +import time +from pathlib import Path +from typing import Any + +from tools.base_tool import ( + BaseTool, + Determinism, + ExecutionMode, + ResourceProfile, + RetryPolicy, + ResumeSupport, + ToolResult, + ToolStability, + ToolTier, +) + + +class SilenceCutter(BaseTool): + name = "silence_cutter" + version = "0.1.0" + tier = ToolTier.CORE + capability = "video_post" + provider = "ffmpeg" + stability = ToolStability.EXPERIMENTAL + execution_mode = ExecutionMode.SYNC + determinism = Determinism.DETERMINISTIC + + dependencies = ["cmd:ffmpeg"] + install_instructions = "Install FFmpeg: https://ffmpeg.org/download.html" + agent_skills = ["ffmpeg"] + + capabilities = [ + "silence_detection", + "jump_cut", + "silence_removal", + "silence_speedup", + ] + + input_schema = { + "type": "object", + "required": ["input_path"], + "properties": { + "input_path": {"type": "string"}, + "output_path": {"type": "string"}, + "mode": { + "type": "string", + "enum": ["remove", "speed_up", "mark"], + "default": "remove", + "description": "remove=jump cut, speed_up=fast-forward silence, mark=detect only", + }, + "silence_threshold_db": { + "type": "number", + "default": -35, + "description": "Audio level below this (in dB) is considered silence. Lower = more sensitive.", + }, + "min_silence_duration": { + "type": "number", + "default": 0.5, + "minimum": 0.1, + "description": "Minimum silence duration in seconds to trigger a cut", + }, + "padding_seconds": { + "type": "number", + "default": 0.08, + "minimum": 0.0, + "description": "Seconds of silence to keep on each side of speech (prevents clipped words)", + }, + "silence_speed_factor": { + "type": "number", + "default": 6.0, + "minimum": 1.5, + "maximum": 100.0, + "description": "Speed multiplier for silent segments (only used in speed_up mode)", + }, + "codec": {"type": "string", "default": "libx264"}, + "crf": {"type": "integer", "default": 18}, + }, + } + + resource_profile = ResourceProfile( + cpu_cores=4, ram_mb=2048, vram_mb=0, disk_mb=4000, network_required=False + ) + retry_policy = RetryPolicy(max_retries=1, retryable_errors=["FFmpeg error"]) + resume_support = ResumeSupport.FROM_START + idempotency_key_fields = [ + "input_path", "mode", "silence_threshold_db", + "min_silence_duration", "padding_seconds", + ] + side_effects = ["writes cut video to output_path"] + user_visible_verification = [ + "Watch output for unnaturally clipped words at cut points", + "Compare duration: output should be noticeably shorter than input", + ] + + def execute(self, inputs: dict[str, Any]) -> ToolResult: + input_path = Path(inputs["input_path"]) + if not input_path.exists(): + return ToolResult(success=False, error=f"Input not found: {input_path}") + + mode = inputs.get("mode", "remove") + start = time.time() + + # Step 1: Detect silence segments + threshold_db = inputs.get("silence_threshold_db", -35) + min_dur = inputs.get("min_silence_duration", 0.5) + padding = inputs.get("padding_seconds", 0.08) + + silences = self._detect_silence(input_path, threshold_db, min_dur) + + if not silences: + elapsed = time.time() - start + return ToolResult( + success=True, + data={ + "message": "No silence detected — video unchanged", + "silence_segments": 0, + "input": str(input_path), + "output": str(input_path), + }, + artifacts=[str(input_path)], + duration_seconds=round(elapsed, 2), + ) + + # Get total duration + total_duration = self._get_duration(input_path) + + # Step 2: Compute speech segments (inverse of silence) + speech_segments = self._compute_speech_segments( + silences, total_duration, padding + ) + + # Step 3: Handle based on mode + if mode == "mark": + elapsed = time.time() - start + output_json = Path( + inputs.get("output_path", str(input_path.with_suffix(".silence.json"))) + ) + result_data = { + "silences": silences, + "speech_segments": speech_segments, + "total_duration": total_duration, + "silence_duration": sum(s["duration"] for s in silences), + "speech_duration": sum(s["end"] - s["start"] for s in speech_segments), + } + output_json.parent.mkdir(parents=True, exist_ok=True) + output_json.write_text(json.dumps(result_data, indent=2), encoding="utf-8") + return ToolResult( + success=True, + data={ + "mode": "mark", + "silence_segments": len(silences), + "speech_segments": len(speech_segments), + "silence_duration_seconds": round(result_data["silence_duration"], 2), + "speech_duration_seconds": round(result_data["speech_duration"], 2), + "output": str(output_json), + }, + artifacts=[str(output_json)], + duration_seconds=round(elapsed, 2), + ) + + output_path = Path( + inputs.get("output_path", str(input_path.with_stem(f"{input_path.stem}_cut"))) + ) + output_path.parent.mkdir(parents=True, exist_ok=True) + codec = inputs.get("codec", "libx264") + crf = inputs.get("crf", 18) + + if mode == "speed_up": + speed_factor = inputs.get("silence_speed_factor", 6.0) + result = self._render_speed_up( + input_path, output_path, silences, speech_segments, + total_duration, speed_factor, codec, crf, + ) + else: + result = self._render_jump_cut( + input_path, output_path, speech_segments, codec, crf, + ) + + if not result.success: + return result + + elapsed = time.time() - start + + silence_dur = sum(s["duration"] for s in silences) + speech_dur = sum(s["end"] - s["start"] for s in speech_segments) + + return ToolResult( + success=True, + data={ + "mode": mode, + "input": str(input_path), + "output": str(output_path), + "input_duration": round(total_duration, 2), + "output_duration": round(speech_dur, 2) if mode == "remove" else None, + "silence_removed_seconds": round(silence_dur, 2), + "silence_segments": len(silences), + "speech_segments": len(speech_segments), + "time_saved_percent": round(silence_dur / total_duration * 100, 1) if total_duration > 0 else 0, + }, + artifacts=[str(output_path)], + duration_seconds=round(elapsed, 2), + ) + + def _detect_silence( + self, input_path: Path, threshold_db: float, min_duration: float + ) -> list[dict]: + """Detect silent segments using FFmpeg silencedetect filter.""" + cmd = [ + "ffmpeg", + "-i", str(input_path), + "-af", f"silencedetect=noise={threshold_db}dB:d={min_duration}", + "-f", "null", "-", + ] + + try: + result = self.run_command(cmd, timeout=300) + output = result.stderr + except Exception as e: + # FFmpeg writes to stderr even on success for filters + output = str(e) + + # Parse silencedetect output + # Format: [silencedetect @ ...] silence_start: 1.234 + # [silencedetect @ ...] silence_end: 2.567 | silence_duration: 1.333 + starts = re.findall(r"silence_start:\s*([\d.]+)", output) + ends = re.findall(r"silence_end:\s*([\d.]+)", output) + durations = re.findall(r"silence_duration:\s*([\d.]+)", output) + + silences = [] + for i in range(min(len(starts), len(ends))): + silences.append({ + "start": float(starts[i]), + "end": float(ends[i]), + "duration": float(durations[i]) if i < len(durations) else float(ends[i]) - float(starts[i]), + }) + + return silences + + def _get_duration(self, input_path: Path) -> float: + """Get video duration via ffprobe.""" + cmd = [ + "ffprobe", "-v", "quiet", + "-show_entries", "format=duration", + "-of", "json", str(input_path), + ] + try: + result = self.run_command(cmd) + data = json.loads(result.stdout) + return float(data["format"]["duration"]) + except Exception: + return 0.0 + + def _compute_speech_segments( + self, silences: list[dict], total_duration: float, padding: float + ) -> list[dict]: + """Compute speech segments as the inverse of silence segments, with padding.""" + segments = [] + cursor = 0.0 + + for silence in silences: + speech_end = silence["start"] + padding + if speech_end > cursor: + segments.append({"start": cursor, "end": min(speech_end, total_duration)}) + cursor = max(cursor, silence["end"] - padding) + + # Final segment after last silence + if cursor < total_duration: + segments.append({"start": cursor, "end": total_duration}) + + # Merge very short gaps (segments < 0.05s apart) + merged = [] + for seg in segments: + if seg["end"] - seg["start"] < 0.01: + continue # Skip tiny segments + if merged and seg["start"] - merged[-1]["end"] < 0.05: + merged[-1]["end"] = seg["end"] + else: + merged.append(seg) + + return merged + + def _render_jump_cut( + self, + input_path: Path, output_path: Path, + speech_segments: list[dict], + codec: str, crf: int, + ) -> ToolResult: + """Remove silence by concatenating speech segments.""" + if not speech_segments: + return ToolResult(success=False, error="No speech segments found") + + temp_dir = output_path.parent / ".silence_cut_tmp" + temp_dir.mkdir(parents=True, exist_ok=True) + + try: + # Cut each speech segment + seg_files = [] + for i, seg in enumerate(speech_segments): + seg_path = temp_dir / f"seg_{i:04d}.mp4" + cmd = [ + "ffmpeg", "-y", + "-i", str(input_path), + "-ss", f"{seg['start']:.3f}", + "-to", f"{seg['end']:.3f}", + "-c:v", codec, "-crf", str(crf), "-preset", "fast", + "-c:a", "aac", "-b:a", "192k", + # Force keyframe at start for clean cuts + "-force_key_frames", f"{seg['start']:.3f}", + str(seg_path), + ] + self.run_command(cmd, timeout=120) + if seg_path.exists() and seg_path.stat().st_size > 0: + seg_files.append(seg_path) + + if not seg_files: + return ToolResult(success=False, error="No segments were successfully cut") + + # Concat all segments + list_path = temp_dir / "concat_list.txt" + with open(list_path, "w", encoding="utf-8") as f: + for sf in seg_files: + safe_path = str(sf.resolve()).replace("\\", "/") + f.write(f"file '{safe_path}'\n") + + cmd = [ + "ffmpeg", "-y", + "-f", "concat", "-safe", "0", + "-i", str(list_path), + "-c", "copy", + str(output_path), + ] + self.run_command(cmd, timeout=120) + + return ToolResult(success=True) + except Exception as e: + return ToolResult(success=False, error=f"Jump cut render failed: {e}") + finally: + # Clean up temp files + for f in temp_dir.glob("*"): + try: + f.unlink() + except OSError: + pass + try: + temp_dir.rmdir() + except OSError: + pass + + def _render_speed_up( + self, + input_path: Path, output_path: Path, + silences: list[dict], speech_segments: list[dict], + total_duration: float, + speed_factor: float, + codec: str, crf: int, + ) -> ToolResult: + """Speed up silent segments instead of removing them. + + This is less jarring than jump cuts — the viewer sees a brief + fast-forward during pauses. + """ + temp_dir = output_path.parent / ".silence_speed_tmp" + temp_dir.mkdir(parents=True, exist_ok=True) + + try: + # Build a timeline of segments: speech at 1x, silence at Nx + all_segments = [] + + for seg in speech_segments: + all_segments.append({"start": seg["start"], "end": seg["end"], "speed": 1.0}) + + for sil in silences: + all_segments.append({"start": sil["start"], "end": sil["end"], "speed": speed_factor}) + + # Sort by start time and merge overlaps + all_segments.sort(key=lambda s: s["start"]) + + # Process each segment + seg_files = [] + for i, seg in enumerate(all_segments): + seg_path = temp_dir / f"seg_{i:04d}.mp4" + duration = seg["end"] - seg["start"] + if duration < 0.05: + continue + + if seg["speed"] == 1.0: + # Normal speed + cmd = [ + "ffmpeg", "-y", + "-i", str(input_path), + "-ss", f"{seg['start']:.3f}", + "-to", f"{seg['end']:.3f}", + "-c:v", codec, "-crf", str(crf), "-preset", "fast", + "-c:a", "aac", "-b:a", "192k", + str(seg_path), + ] + else: + # Speed up + pts = 1.0 / seg["speed"] + atempo_chain = self._build_atempo_chain(seg["speed"]) + cmd = [ + "ffmpeg", "-y", + "-i", str(input_path), + "-ss", f"{seg['start']:.3f}", + "-to", f"{seg['end']:.3f}", + "-filter:v", f"setpts={pts:.4f}*PTS", + "-filter:a", atempo_chain, + "-c:v", codec, "-crf", str(crf), "-preset", "fast", + "-c:a", "aac", "-b:a", "192k", + str(seg_path), + ] + + self.run_command(cmd, timeout=120) + if seg_path.exists() and seg_path.stat().st_size > 0: + seg_files.append(seg_path) + + if not seg_files: + return ToolResult(success=False, error="No segments rendered") + + # Concat + list_path = temp_dir / "concat_list.txt" + with open(list_path, "w", encoding="utf-8") as f: + for sf in seg_files: + safe_path = str(sf.resolve()).replace("\\", "/") + f.write(f"file '{safe_path}'\n") + + cmd = [ + "ffmpeg", "-y", + "-f", "concat", "-safe", "0", + "-i", str(list_path), + "-c", "copy", + str(output_path), + ] + self.run_command(cmd, timeout=120) + + return ToolResult(success=True) + except Exception as e: + return ToolResult(success=False, error=f"Speed-up render failed: {e}") + finally: + for f in temp_dir.glob("*"): + try: + f.unlink() + except OSError: + pass + try: + temp_dir.rmdir() + except OSError: + pass + + @staticmethod + def _build_atempo_chain(factor: float) -> str: + """Build atempo filter chain. atempo accepts [0.5, 100.0].""" + filters = [] + remaining = factor + while remaining > 100.0: + filters.append("atempo=100.0") + remaining /= 100.0 + while remaining < 0.5: + filters.append("atempo=0.5") + remaining /= 0.5 + filters.append(f"atempo={remaining:.4f}") + return ",".join(filters) + + def estimate_runtime(self, inputs: dict[str, Any]) -> float: + return 45.0