commit
This commit is contained in:
63
backend/app/services/flow_generator.py
Normal file
63
backend/app/services/flow_generator.py
Normal file
@@ -0,0 +1,63 @@
|
||||
|
||||
import json
|
||||
from app.core.ai import ai_client
|
||||
from app.models.shot import Shot
|
||||
from app.models.scene import Scene
|
||||
|
||||
class FlowGeneratorService:
|
||||
async def generate_flow_json(self, shot: Shot, scene: Scene) -> dict:
|
||||
prompt = f"""
|
||||
You are a Virtual Cinematographer creating production instructions for Google Veo (Generative Video AI).
|
||||
|
||||
Generate a JSON configuration payload for the following shot.
|
||||
|
||||
CONTEXT:
|
||||
Scene Heading: {scene.slugline}
|
||||
Scene Description: {scene.raw_content}
|
||||
|
||||
SHOT DETAILS:
|
||||
Description: {shot.description}
|
||||
Additional Notes: {shot.llm_context_cache}
|
||||
|
||||
The JSON output should strictly follow this schema:
|
||||
{{
|
||||
"prompt": "Detailed visual description of the video to be generated...",
|
||||
"negative_prompt": "things to avoid...",
|
||||
"camera_movement": "string (e.g. pan left, zoom in, static)",
|
||||
"aspect_ratio": "16:9",
|
||||
"duration_seconds": 5
|
||||
}}
|
||||
|
||||
Enhance the 'prompt' field to be highly descriptive, visual, and suitable for a text-to-video model.
|
||||
Include lighting, style, and composition details based on the context.
|
||||
"""
|
||||
|
||||
json_str = await ai_client.generate_json(prompt)
|
||||
|
||||
try:
|
||||
return json.loads(json_str)
|
||||
except json.JSONDecodeError:
|
||||
raise ValueError("Failed to generate valid JSON from AI response")
|
||||
|
||||
async def refine_flow_json(self, current_json: dict, user_feedback: str) -> dict:
|
||||
prompt = f"""
|
||||
You are an AI Video Assistant.
|
||||
Update the following Google Veo JSON configuration based on the user's feedback.
|
||||
|
||||
CURRENT JSON:
|
||||
{json.dumps(current_json, indent=2)}
|
||||
|
||||
USER FEEDBACK:
|
||||
"{user_feedback}"
|
||||
|
||||
Return ONLY the updated JSON object. Do not wrap in markdown code blocks.
|
||||
"""
|
||||
|
||||
json_str = await ai_client.generate_json(prompt)
|
||||
|
||||
try:
|
||||
return json.loads(json_str)
|
||||
except json.JSONDecodeError:
|
||||
raise ValueError("Failed to refine JSON")
|
||||
|
||||
flow_generator = FlowGeneratorService()
|
||||
57
backend/app/services/script_parser.py
Normal file
57
backend/app/services/script_parser.py
Normal file
@@ -0,0 +1,57 @@
|
||||
|
||||
import json
|
||||
from app.core.ai import ai_client
|
||||
from app.schemas.script import ScriptAnalysisResponse
|
||||
|
||||
class ScriptParserService:
|
||||
async def parse_script(self, text_content: str) -> ScriptAnalysisResponse:
|
||||
prompt = f"""
|
||||
You are an expert Assistant Director and Script Supervisor.
|
||||
Analyze the following screenplay text and break it down into Scenes and Shots.
|
||||
|
||||
For each Scene, identify:
|
||||
- Scene Number (if present, or incrementing)
|
||||
- Heading (INT./EXT. LOCATION - DAY/NIGHT)
|
||||
- Brief Description of what happens
|
||||
|
||||
For each Scene, break the action down into a list of Shots (Camera setups).
|
||||
For each Shot, provide:
|
||||
- Shot Number (e.g. 1, 1A, etc)
|
||||
- Description of the action in the shot
|
||||
- Visual Notes (Camera angles, movement if implied)
|
||||
- Dialogue (if any covers this shot)
|
||||
|
||||
Output MUST be a valid JSON object matching this structure:
|
||||
{{
|
||||
"scenes": [
|
||||
{{
|
||||
"scene_number": "1",
|
||||
"heading": "INT. OFFICE - DAY",
|
||||
"description": "John sits at his desk.",
|
||||
"shots": [
|
||||
{{
|
||||
"shot_number": "1A",
|
||||
"description": "Wide shot of John at desk.",
|
||||
"visual_notes": "Static",
|
||||
"dialogue": null
|
||||
}}
|
||||
]
|
||||
}}
|
||||
]
|
||||
}}
|
||||
|
||||
SCRIPT TEXT:
|
||||
{text_content}
|
||||
"""
|
||||
|
||||
json_str = await ai_client.generate_json(prompt)
|
||||
|
||||
# Parse JSON and validate with Pydantic
|
||||
try:
|
||||
data = json.loads(json_str)
|
||||
return ScriptAnalysisResponse(**data)
|
||||
except json.JSONDecodeError:
|
||||
# Fallback or retry logic could go here
|
||||
raise ValueError("Failed to parse LLM response as JSON")
|
||||
|
||||
parser_service = ScriptParserService()
|
||||
Reference in New Issue
Block a user