Commit Graph

19 Commits

Author SHA1 Message Date
Jeff Emmett 8efeae63c7 Wire Infisical for backend and worker secrets
- Add Python entrypoint.sh for Infisical secret injection
- Both backend and worker fetch DATABASE_URL, OPENAI_API_KEY from Infisical
- Worker uses network_mode:service:wireguard (shares traefik-public via WG)
- Keep env_file for non-secret config vars

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 09:32:45 -08:00
Jeff Emmett e1d9085396 feat: inline video previews and caption rendering with style options
- Replace download links with inline <video> players for clip preview
- Add clip download endpoint separate from inline preview
- Add caption style options: TikTok, Hormozi, Karaoke, Minimal, None
- Implement ASS subtitle generation from word-level Whisper timestamps
- Render pipeline: aspect ratio conversion + burned-in captions via FFmpeg
- Add render preview endpoint for inline playback of rendered clips
- Add fonts to Docker image for subtitle rendering

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 02:11:20 +00:00
Jeff Emmett db4b7b10fd fix: use raw seconds in transcript timestamps to prevent AI misinterpretation
The AI model was interpreting MM:SS timestamps (e.g., 38:07) as decimal
seconds (38.07s) instead of 2287s, causing clips from long videos to have
near-zero durations. Switching to raw seconds (e.g., [2287.0s - 2295.0s])
eliminates the ambiguity.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 01:43:38 +00:00
Jeff Emmett 3ce7945096 fix: robust JSON parsing with regex fallback for LLM responses
Gemini sometimes produces JSON with unescaped characters that break
standard parsing. Added multiple fallback strategies including regex
extraction of individual clip objects.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 01:17:15 +00:00
Jeff Emmett 1bac0b90a6 debug: improve AI analysis JSON parsing error logging
Show more context in error messages to diagnose parse failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 01:13:00 +00:00
Jeff Emmett 72efed481f perf: limit YouTube downloads to 720p max
4K downloads are 229MB+ and too slow through the WG tunnel.
720p is sufficient quality for clip analysis and extraction.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 01:08:52 +00:00
Jeff Emmett 6c40f713a4 fix: strip markdown code fences from LLM JSON response
Gemini wraps JSON output in ```json fences which broke the parser.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 00:50:10 +00:00
Jeff Emmett 362fe1e860 feat: add cloud AI inference support (Gemini/OpenAI-compatible)
CPU-based Ollama inference on Netcup is too slow due to server memory
pressure. Add OpenAI-compatible API support so we can use Gemini Flash
or other cloud APIs for clip analysis. Also increase transcript sample
size to 20K chars since cloud APIs handle it easily.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 00:44:13 +00:00
Jeff Emmett d480c635ff Increase Ollama timeout to 1800s for long video transcripts
47-minute videos produce ~48K chars of transcript which takes
>10 minutes for llama3.1:8b on CPU to process.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 21:27:36 +00:00
Jeff Emmett 0e4eec4f12 fix: add web_creator client fallback, friendlier YouTube bot error
- Try multiple YouTube player clients for better compatibility
- Show user-friendly error suggesting upload when YouTube blocks download

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 18:41:19 +00:00
Jeff Emmett be3b1ca706 fix: copy cookies to temp file so yt-dlp doesn't overwrite originals
yt-dlp saves rotated cookies back on exit, destroying fresh exports.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 18:39:35 +00:00
Jeff Emmett c5505417a5 feat: add deno runtime for yt-dlp YouTube JS extraction
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 18:35:11 +00:00
Jeff Emmett 5c9b7c74e0 fix: use raw string for HTML template to preserve JS backslashes
Python was interpreting \' as ' in the onclick handlers, breaking JS.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 11:36:48 +00:00
Jeff Emmett 128aad405c feat: add user-friendly frontend with upload, progress, and clip gallery
Replaces API endpoint listing with a proper UI:
- YouTube URL input or drag-and-drop video upload
- Real-time SSE progress bar with stage messages
- Clip results gallery with virality scores, categories, transcripts
- Preview/download links for extracted clips
- Recent jobs history with click-to-view

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 11:27:29 +00:00
Jeff Emmett 53c1ed5c4c feat: add landing page with API docs at root URL
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 13:14:13 +00:00
Jeff Emmett 1784bb35ff fix: increase Ollama timeout to 600s for CPU inference
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 13:05:29 +00:00
Jeff Emmett 4619b53b5e fix: update yt-dlp to latest for YouTube bot detection bypass
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 12:40:59 +00:00
Jeff Emmett 6ab5f805a4 fix: use arq CLI to start worker instead of python -m
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 12:33:02 +00:00
Jeff Emmett 6aa8a676ec feat: ClipForge Phase 1 - core pipeline MVP
Self-hosted AI video clipper (Opus Clip alternative).
Pipeline: YouTube URL -> yt-dlp download -> Whisper transcription ->
Ollama AI clip selection -> FFmpeg extraction.

- FastAPI backend with PostgreSQL + Redis + ARQ worker
- 7-stage processing pipeline with SSE progress tracking
- Services: download (yt-dlp), transcription (whisper.jeffemmett.com),
  AI analysis (Ollama), clip extraction (FFmpeg stream copy)
- API: create jobs, track progress, list clips, render, download
- Docker Compose with Traefik labels for clip.jeffemmett.com

Cost: $0/video using existing infrastructure.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 12:27:43 +00:00