diff --git a/backend/api/routes/video.py b/backend/api/routes/video.py index 528733e..4371ab3 100644 --- a/backend/api/routes/video.py +++ b/backend/api/routes/video.py @@ -1,10 +1,13 @@ -from fastapi import APIRouter, HTTPException +from fastapi import APIRouter, HTTPException, Depends from typing import List, Optional +from sqlalchemy.orm import Session from backend.models.schemas import ( - Scene, NovelProject, + Scene, NovelProject, DialogueLine, VideoFromAssetsRequest, VideoFromAssetsResponse, VideoComposeRequest ) +from backend.models.database import Scene as DBScene, Project, Dialogue +from backend.database import get_db from backend.services.video_composition.service import VideoCompositionService router = APIRouter() @@ -12,11 +15,57 @@ @router.post("/compose") -async def compose_video(request: VideoComposeRequest): +async def compose_video(request: VideoComposeRequest, db: Session = Depends(get_db)): try: + project = db.query(Project).filter(Project.id == request.project_id).first() + if not project: + raise HTTPException(status_code=404, detail="项目不存在") + + db_scenes = db.query(DBScene).filter( + DBScene.project_id == request.project_id + ).order_by(DBScene.sequence).all() + + if not db_scenes: + raise HTTPException(status_code=404, detail="该项目没有场景数据") + + scenes = [] + for db_scene in db_scenes: + dialogues = db.query(Dialogue).filter( + Dialogue.scene_id == db_scene.id, + Dialogue.project_id == request.project_id + ).order_by(Dialogue.sequence).all() + + lines = [ + DialogueLine( + character=dialogue.character, + text=dialogue.text, + emotion=dialogue.emotion or "neutral", + is_monologue=dialogue.is_monologue or False, + audio_url=None + ) + for dialogue in dialogues + ] + + scene = Scene( + id=str(db_scene.id), + sequence=db_scene.sequence, + description=db_scene.description or "", + dialogue=db_scene.dialogue, + narrator_text=None, + characters=db_scene.characters or [], + setting=db_scene.setting or "", + mood=db_scene.mood or "", + image_prompt=db_scene.image_prompt, + image_url=db_scene.image_url, + audio_url=db_scene.audio_url, + duration=float(db_scene.duration) if db_scene.duration else 5.0, + lines=lines + ) + scenes.append(scene) + video_path = video_service.generate_video_from_scenes( - scenes=request.scenes, - project_title=request.project_title, + scenes=scenes, + project_title=project.title, add_bgm=request.add_bgm, bgm_path=request.bgm_path, ) @@ -25,6 +74,8 @@ async def compose_video(request: VideoComposeRequest): "success": True, "video_path": video_path, } + except HTTPException: + raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) diff --git a/backend/models/schemas.py b/backend/models/schemas.py index 1b4fa32..c44332e 100644 --- a/backend/models/schemas.py +++ b/backend/models/schemas.py @@ -230,7 +230,6 @@ class VideoFromAssetsResponse(BaseModel): class VideoComposeRequest(BaseModel): - scenes: List[Scene] - project_title: str + project_id: str add_bgm: bool = False bgm_path: Optional[str] = None