Commit graph

42 commits

Author SHA1 Message Date
michael
e5ff124140 fix: use allow_join_result for celery subtask result retrieval
Celery doesn't allow calling result.get() within a task by default to
prevent deadlocks. Use allow_join_result() context manager since we've
already confirmed the task is complete via ready() polling.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 18:09:37 -06:00
michael
bf1c321088 feat: add dedicated ffmpeg queue to prevent server overload
Add a dedicated Celery queue (ffmpeg) with concurrency=1 to serialize
all FFmpeg operations. This prevents CPU spikes when multiple render
tasks run in parallel with multiple languages.

Changes:
- Add ffmpeg_operations.py with run_ffmpeg_command and run_ffprobe_command tasks
- Update VideoRendererService to dispatch ffmpeg commands via the queue
- Add ffmpeg-worker service to docker-compose with --concurrency=1
- Configure main worker to exclude the ffmpeg queue

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 17:56:23 -06:00
michael
fd68d1ef54 feat: add accessible video validation, remove AI confidence check
- Add validation for accessible_video_gcs (file exists, size 0.1MB-5GB)
- Add validation for retimed_captions_vtt_gcs when accessible video exists
- Add AD Videos count to asset validation panel
- Include retimed captions in VTT file count
- Remove AI confidence from validation panel and backend checks

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 16:41:57 -06:00
michael
3cdea9dfec fix: video review caption sync and event listener issues
- Fix video event listeners not re-attaching when video element remounts
  (add activeTab?.videoUrl to useEffect dependency array)
- Add retimed_captions_vtt to VTT API response for accessible videos
- Use retimed captions for accessible video tab in VideoReviewPlayer

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 16:23:48 -06:00
michael
6effe58dc9 feat: add video review with timestamped notes to Final Review
Add a comprehensive video review feature to the Final Review page that allows
reviewers to watch videos with caption overlays and add timestamped notes.

Backend:
- New ReviewNote model for MongoDB with job_id, asset_key, timestamp, content
- CRUD API endpoints at /jobs/{job_id}/review-notes
- Owner-only edit/delete permissions (admins can bypass)
- Database indexes for efficient querying

Frontend:
- VideoReviewPlayer component with video player and caption overlay
- NotesSidebar for viewing/adding notes with auto-highlight when video reaches timestamp
- SyncedCaptionList with auto-scroll and click-to-seek
- AssetTabs for switching between languages and accessible videos
- React Query hooks with 30s polling for collaborative updates

Features:
- Notes persist to database and are shared across all reviewers
- Notes highlight for 5 seconds when video playback reaches their timestamp
- Click note to seek video to that position
- Pause video to add note at current timestamp
- Accessible videos use retimed captions when available

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 15:30:00 -06:00
michael
81872987cc fix: remove accessible_video_method from downloads response
The method field (overlay/pause_insert) is metadata, not a downloadable
file. Including it in the downloads dict caused the frontend to render
a broken download link.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 12:31:30 -06:00
michael
54667fbcb8 fix: resolve audio/video sync issues in accessible video renderer
- Update _get_video_properties() to extract audio sample_rate, channels,
  and pix_fmt in addition to video properties
- Add _extract_segment_reencoded() for frame-accurate cuts using
  re-encoding instead of stream copy (fixes keyframe-only cut limitation)
- Add _create_freeze_segment_matched() to enforce source audio property
  matching (fixes silent pauses caused by sample rate mismatch)
- Update _render_pause_insert_method() to use new methods with uniform
  encoding parameters
- Add -video_track_timescale 90000 for consistent timebase across segments

Root causes fixed:
1. -c copy could only cut at keyframes, causing audio dropouts
2. Sample rate mismatch (48kHz source vs 44.1kHz MP3) caused silent
   freeze-frame segments when concatenated

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 12:05:32 -06:00
michael
6acb452cfa fix: add render queue to Celery worker
The accessible video render task was being dispatched to the 'render' queue
but no worker was listening to it. Added 'render' to:
- Dockerfile CMD args for worker queue list
- celery_worker.py import and log message

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 11:39:34 -06:00
michael
80d3866d32 feat: add accessible video (MP4 with embedded audio descriptions)
Add new deliverable type that renders video with audio descriptions embedded.
Supports two AI-determined methods:
- Direct Overlay: ducks original audio and overlays AD TTS (for minimal dialogue)
- Pause-Insert: freeze-frame video, insert AD, re-time subtitles (for significant dialogue)

Backend:
- Add Pydantic schemas for Gemini analysis response
- Add Gemini prompt and analyze_accessible_video_placement() method
- Add video_renderer.py service using FFmpeg for both rendering methods
- Add vtt_retimer.py service for pause-insert subtitle adjustment
- Add render_accessible_video.py Celery task
- Modify TTS service to return individual per-cue segments
- Update translate_and_synthesize.py to save segments and trigger rendering
- Update download endpoint to include accessible video outputs

Frontend:
- Add accessible_video_mp4 checkbox to NewJob form
- Update TypeScript types for new deliverable

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 11:06:41 -06:00
michael
dad7ea09df fix: generate audio descriptions in the video's detected language
Updated Gemini ingestion prompt to explicitly require:
- Detect the spoken language first
- Write ALL outputs (summary, transcript, captions, audio_description) in that language
- Do NOT translate to English - keep everything in the original language

This fixes the issue where German videos would get English audio descriptions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 19:01:14 -06:00
michael
865fcdc246 feat: add TTS settings panel with model, speed, and style options
- Add model selection (flash vs pro) for quality control
- Add speed slider (0.5x - 2.0x) for pacing adjustment
- Add style presets (neutral, calm, energetic, professional, warm, documentary)
- Add custom style prompt option for advanced customization
- New /tts/options endpoint returns available TTS options
- Voice preview now tests all settings so users hear exact output
- Backward compatible: all new fields have sensible defaults

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 15:22:14 -06:00
michael
093b55c473 fix: add ffmpeg to API container for TTS audio conversion
The Gemini TTS service uses pydub which requires ffmpeg to convert
audio formats. Previously only the Worker container had ffmpeg.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 14:55:14 -06:00
michael
3804692092 fix: correct import path for get_current_user in routes_tts
The import was using a non-existent module path `..deps` instead of
`...core.dependencies`, causing the API container to fail on startup.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 14:49:34 -06:00
michael
29643f6683 upgrade TTS to Gemini TTS with voice selection and preview
- Add Gemini TTS service with 30 voices and 24 languages
- Add TTS API endpoints for voice listing and preview
- Add per-language voice selection in job creation form
- Add voice override at QC approval stage
- Add VoiceSelector and VoicePreviewButton components
- Update TTSPreferences model with provider and voice mapping

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 14:41:57 -06:00
michael
46b6f25fd0 upgrade to Gemini 3 Pro preview model
- Change model from gemini-2.5-pro to gemini-3-pro-preview
- Upgrade google-genai package from ^1.31.0 to ^1.56.0

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 14:02:02 -06:00
michael
e6578e0ccf add approved_source and qc_feedback job statuses to MongoDB schema
- Add migration to update jobs collection validator with new statuses
- Update mongodb-init.js for fresh deployments
- Fix deploy.sh to properly run migrations with 'python migrate.py up'

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 13:12:14 -06:00
michael
58a4f1f627 add support for non-English original video uploads
- Upload form now has "English / Different language" radio with optional language hint
- Gemini auto-detects language and saves outputs to outputs.{detected_language}
- QC review dynamically loads/saves VTT for source language
- New APPROVED_SOURCE status for non-English videos (APPROVED_ENGLISH kept for backwards compat)
- Translation pipeline reads from source language and passes source_language to Google Translate
- All existing English jobs continue to work unchanged

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 10:33:58 -06:00
michael
762d7bcb38 fixed websockets live messaging for updates 2025-10-16 11:46:37 -05:00
michael
d25fb921a1 fixed dates on scheme validator migration 2025-10-10 10:59:20 -05:00
michael
92169d047b added scheme validator 2025-10-10 10:55:54 -05:00
michael
f59f5cf93b fixed front end build errors 2025-10-10 10:26:57 -05:00
michael
aefd559e68 added production user role and made it default for new MSAL users - production can access everything EXCEPT user management - that's only for admin 2025-10-10 10:07:30 -05:00
michael
665b49c3f1 added MSAL microsoft authentication 2025-10-10 09:19:39 -05:00
michael
0910ade371 more fixes for refresh token - this time maintaining the username and role properly across refresh 2025-10-08 23:09:29 -05:00
michael
8bdfaee57d hopefully fixed refresh token issue 2025-10-08 22:59:01 -05:00
michael
6031f9893d added logging to troubleshoot refresh token issue 2025-10-08 22:56:08 -05:00
michael
990f6f6fa1 fixed session refresh and added full deploy script - and added documentation including videos 2025-10-08 22:29:08 -05:00
michael
c2ed1429c9 better tts config for worker 2025-10-08 18:47:28 -05:00
michael
7ea23b9858 fixed objectID/stringID mismatch 2025-10-08 18:23:05 -05:00
michael
625b1fb8cc fixed middleware silent swallowing of exceptions FINALLY 2025-10-08 18:19:59 -05:00
michael
e2bc456539 added test endpoint 2025-10-08 18:14:32 -05:00
michael
58054ac813 added logging to jobs route 2025-10-08 18:08:22 -05:00
michael
eddc687f37 added logging to identify 500 errors 2025-10-08 18:00:13 -05:00
michael
b7f3687b6c disabled middleware 2025-10-08 17:53:44 -05:00
michael
38e6f37450 fixed overly aggressive security algorithm 2025-10-08 17:49:20 -05:00
michael
5c66abcd54 fixed create test users script 2025-10-08 17:22:08 -05:00
michael
41015c2a91 fixed dockerignore 2025-10-08 17:17:39 -05:00
michael
06f958c974 fixed docker file for dependency installs 2025-10-08 17:06:41 -05:00
michael
1a1ed3048d wrote docker files and deployment instructions 2025-10-08 16:00:12 -05:00
michael
de61d0bd39 removed mongodb change stream monitoring, added global websockets monitoring for notifications, broke symmetry between toasts and persistent notifications (and refined which notifications get sent and how) 2025-08-25 15:48:18 -05:00
michael
0c54dd4f29 added websockets for live job status updates with toast notifications on job list page 2025-08-24 19:41:23 -05:00
michael
af2562096a initial commit 2025-08-24 16:28:33 -05:00