import os from fastapi import APIRouter, HTTPException from pydantic import BaseModel from typing import List, Optional from app.config import settings router = APIRouter() class ClipConfig(BaseModel): clip_id: str start_time_seconds: float end_time_seconds: float loop_count: int = 1 apply_zero_crossing: bool = True fade_in_ms: int = 150 fade_out_ms: int = 150 class TrackConfig(BaseModel): track_id: str file_id: str volume: float = 1.0 muted: bool = False clips: List[ClipConfig] = [] class ExportSettings(BaseModel): sample_rate: int = 44100 bit_depth: int = 16 format: str = "wav" class MultitrackSessionRequest(BaseModel): session_id: str export_settings: ExportSettings tracks: List[TrackConfig] @router.post("/mix") async def mix_multitrack_session(req: MultitrackSessionRequest): """ API endpoint để xử lý hòa âm đa kênh (Multitrack Mixdown). Nhận cấu hình JSON từ Client và gửi task xuống Celery Worker. """ # Kiểm tra xem các file nguồn có tồn tại không for track in req.tracks: if track.muted: continue upload_path = os.path.join(settings.UPLOADS_DIR, track.file_id) processed_path = os.path.join(settings.PROCESSED_DIR, track.file_id) if not os.path.exists(upload_path) and not os.path.exists(processed_path): raise HTTPException( status_code=404, detail=f"File not found for track {track.track_id}: {track.file_id}" ) # Gửi task xuống Celery Worker from app.tasks.worker import mix_multitrack_task task = mix_multitrack_task.delay(req.dict()) return { "task_id": task.id, "session_id": req.session_id, "status": "processing" } @router.post("/process-session") async def process_session(req: MultitrackSessionRequest): """ API endpoint để xử lý toàn bộ session với nhiều tracks và clips. Xử lý từng clip, sau đó hòa âm tất cả tracks lại với nhau. """ from app.tasks.worker import process_multitrack_session_task task = process_multitrack_session_task.delay(req.dict()) return { "task_id": task.id, "session_id": req.session_id, "status": "processing" }