Skip to content

Conversation

@afrinxnahar
Copy link
Collaborator

@afrinxnahar afrinxnahar commented Jan 4, 2026

📝 Description

This PR implements a complete AI-powered audio/video dubbing feature using Murf.ai integration. Users can upload audio or video files and dub them into 21 different languages while preserving the original voice characteristics. The feature includes real-time progress tracking via Server-Sent Events (SSE), media storage with Supabase, and credit-based billing.

Key Features:

  • Backend dubbing service with Murf.ai API integration
  • Real-time SSE streaming for dubbing progress updates
  • Support for 21 languages (English, Spanish, French, German, Chinese, Japanese, etc.)
  • Scalable media storage via Supabase Storage
  • Credit system integration - deducts credits after successful dubbing
  • Custom React hook (useDubbing) for clean state management
  • Responsive UI with tabbed interface and side-by-side media comparison

🎯 Type of Change

  • ✨ New feature (non-breaking change which adds functionality)

🔗 Related Issue

Closes #14

🧪 Testing

  • I have tested my changes locally
  • I have added tests for my changes
  • All existing tests pass
  • I have tested on different browsers/devices (if applicable)

📋 Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have checked my code and corrected any misspellings
  • I have read the Contributing Guide

📸 Screenshots (if applicable)

Create Dub Page:

  • Tabbed interface with Create Dub / Preview Result tabs
  • File upload with drag & drop support
  • Language selection dropdown
  • Real-time progress bar with status messages
image

Dubbing Detail Page:

  • Side-by-side comparison of original and dubbed media
  • Media metadata sidebar (type, language, status, credits used)
  • Download and delete actions
image

🔧 Technical Details

Backend Architecture (apps/api)

New Files:

  • dubbing.module.ts - NestJS module registration
  • dubbing.controller.ts - REST endpoints with SSE streaming
  • dubbing.service.ts - Core business logic and Murf.ai integration

API Endpoints:

Method Endpoint Description
POST /api/v1/dubbing Create new dubbing job
GET /api/v1/dubbing List user's dubbing projects
GET /api/v1/dubbing/:id Get single dubbing details
GET /api/v1/dubbing/status/:projectId SSE stream for progress updates
DELETE /api/v1/dubbing/:id Delete dubbing project

Dubbing Flow:

  1. Frontend uploads media to Supabase Storage
  2. Backend downloads from Supabase, sends to Murf.ai
  3. SSE endpoint polls Murf.ai status with exponential backoff
  4. On completion: download dubbed file → upload to Supabase → update DB → deduct credits

Frontend Architecture (apps/web)

New Files:

  • hooks/useDubbing.ts - Custom hook managing all dubbing state
  • app/dashboard/dubbing/new/page.tsx - Create dubbing page
  • app/dashboard/dubbing/[id]/page.tsx - Dubbing detail page
  • lib/api/getDubbings.ts - API client functions

State Management:

// Progress states: idle → uploading → processing → completed/failed
interface DubbingProgress {
  state: "idle" | "uploading" | "processing" | "completed" | "failed";
  progress: number;
  message: string;
  creditsUsed?: number;
  finished?: boolean;
}

Shared Package (packages/validations)

Supported Languages: English, Chinese, Dutch, Finnish, French, German, Greek, Hindi, Croatian, Indonesian, Italian, Japanese, Korean, Norwegian, Polish, Portuguese, Romanian, Russian, Slovak, Spanish, Turkish

🚀 Deployment Notes

Environment Variables Required:

MURF_API_KEY=your_murf_api_key

Database Changes:

  • Uses existing dubbing_projects table with new columns:
    • is_video (boolean)
    • media_name (string)

Supabase Storage:

  • Uses dubbing_media bucket for both original and dubbed files

🔍 Review Notes

Please focus on:

  1. SSE implementation in dubbing.service.ts - exponential backoff and cleanup on disconnect
  2. Error handling in the useDubbing hook - especially EventSource error handling
  3. File size limits - currently set to 500MB max
  4. Credit deduction logic - ensure it's atomic with the update_user_credits RPC

📊 Performance Impact

  • No performance impact
  • Performance improvement
  • Performance regression (explain below)

The SSE polling uses exponential backoff (5s → 20s max) to reduce API calls while maintaining responsiveness.

🔒 Security Considerations

  • No security implications

  • Security improvement

  • Potential security concern (explain below)

  • All endpoints protected with SupabaseAuthGuard

  • User isolation enforced via user_id checks in all queries

  • Media URLs are public but use random UUIDs for obfuscation

Commits in this PR:

  1. 601177e - Update UI with custom hook and upload audio/video file to supabase storage
  2. df60d71 - Add backend controller for audio and video dubbing route + controller with murf.ai
  3. 19fb79a - Update frontend pages (list, create, detail), add styling, tabs, loading states
  4. 627feef - Add media naming and original media preview to dubbing

@vercel
Copy link
Contributor

vercel bot commented Jan 4, 2026

@afrinxnahar is attempting to deploy a commit to the afrin127329's projects Team on Vercel.

A member of the Team first needs to authorize it.

@afrinxnahar afrinxnahar merged commit 7c8f4b5 into scriptaiapp:main Jan 5, 2026
2 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feat: Multi language audio dubbing

1 participant