Automated Action 55f5e5f5a8 Add comprehensive AI video dubbing features with Docker support
- Auto language detection using OpenAI Whisper during video upload
- Editable transcript interface for reviewing/correcting transcriptions
- Updated translation pipeline to use edited transcripts when available
- Migrated from JWT to Google OAuth-only authentication for better security
- Added complete Docker containerization with docker-compose.yml
- Updated database schema with language detection and transcript editing fields
- Enhanced API documentation and workflow in README
- Added comprehensive environment variable configuration

🤖 Generated with BackendIM

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-28 08:12:00 +00:00

162 lines
4.6 KiB
Python

from fastapi import APIRouter, Depends, HTTPException, status, BackgroundTasks
from sqlalchemy.orm import Session
from pydantic import BaseModel
from app.db.session import get_db
from app.models.user import User
from app.models.video import Video
from app.models.transcription import Transcription
from app.models.translation import Translation
from app.utils.auth import get_current_user
from app.services.translation_service import translate_text
router = APIRouter()
class TranslationResponse(BaseModel):
id: int
video_id: int
text: str
created_at: str
class Config:
orm_mode = True
class TranslationStartResponse(BaseModel):
message: str
video_id: int
async def background_translate(video_id: int, transcript_text: str, target_language: str, source_language: str, db: Session):
try:
# Update video status
video = db.query(Video).filter(Video.id == video_id).first()
if video:
video.status = "translating"
db.commit()
# Translate the text
translated_text = await translate_text(transcript_text, target_language, source_language)
if translated_text:
# Save translation to database
translation = Translation(
video_id=video_id,
text=translated_text
)
db.add(translation)
# Update video status
if video:
video.status = "translated"
db.commit()
else:
# Update video status to error
if video:
video.status = "translation_failed"
db.commit()
except Exception:
# Update video status to error
video = db.query(Video).filter(Video.id == video_id).first()
if video:
video.status = "translation_failed"
db.commit()
@router.post("/{video_id}", response_model=TranslationStartResponse)
async def start_translation(
video_id: int,
background_tasks: BackgroundTasks,
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
):
# Check if video exists and belongs to user
video = db.query(Video).filter(
Video.id == video_id,
Video.user_id == current_user.id
).first()
if not video:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Video not found"
)
# Check if transcription exists
transcription = db.query(Transcription).filter(
Transcription.video_id == video_id
).first()
if not transcription:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Transcription not found. Please transcribe the video first."
)
# Check if translation already exists
existing_translation = db.query(Translation).filter(
Translation.video_id == video_id
).first()
if existing_translation:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Translation already exists for this video"
)
# Use edited transcript if available, otherwise use original
transcript_text = transcription.edited_text if transcription.is_edited and transcription.edited_text else transcription.text
# Start background translation
background_tasks.add_task(
background_translate,
video_id,
transcript_text,
video.language_to,
video.language_from,
db
)
return TranslationStartResponse(
message="Translation started in background",
video_id=video_id
)
@router.get("/{video_id}", response_model=TranslationResponse)
async def get_translation(
video_id: int,
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
):
# Check if video exists and belongs to user
video = db.query(Video).filter(
Video.id == video_id,
Video.user_id == current_user.id
).first()
if not video:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Video not found"
)
# Get translation
translation = db.query(Translation).filter(
Translation.video_id == video_id
).first()
if not translation:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Translation not found"
)
return TranslationResponse(
id=translation.id,
video_id=translation.video_id,
text=translation.text,
created_at=str(translation.created_at)
)