133 lines
4.1 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
视频脚本生成引擎 (示例模板)
将此文件移动到 engines/ 目录即可启用
"""
from typing import Dict, Any
from ..base import BaseAIGCEngine, EngineResult
class VideoScriptEngine(BaseAIGCEngine):
"""
视频脚本生成引擎
根据景点信息生成短视频分镜脚本
"""
engine_id = "video_script"
engine_name = "视频脚本生成"
version = "1.0.0"
description = "根据景点信息生成短视频分镜脚本"
def get_param_schema(self) -> Dict[str, Any]:
return {
"scenic_spot_id": {
"type": "int",
"required": True,
"desc": "景区 ID",
},
"duration": {
"type": "int",
"required": True,
"desc": "视频时长 (秒)",
},
"style": {
"type": "str",
"required": False,
"default": "vlog",
"enum": ["vlog", "documentary", "promo", "tutorial"],
"desc": "视频风格",
},
"target_platform": {
"type": "str",
"required": False,
"default": "xiaohongshu",
"enum": ["xiaohongshu", "douyin", "bilibili"],
"desc": "目标平台",
},
}
def estimate_duration(self, params: Dict[str, Any]) -> int:
duration = params.get('duration', 60)
return 20 + (duration // 10) # 基础时间 + 每10秒视频约1秒生成时间
async def execute(self, params: Dict[str, Any]) -> EngineResult:
task_id = params.get('_task_id', 'unknown')
try:
self.set_progress(task_id, 10)
# 1. 获取景区信息
scenic_spot_id = params['scenic_spot_id']
spot = await self.db.scenic_spot.find_by_id(scenic_spot_id)
if not spot:
return EngineResult(
success=False,
error=f"景区不存在: {scenic_spot_id}",
error_code="SPOT_NOT_FOUND"
)
self.set_progress(task_id, 20)
# 2. 构建提示词
duration = params['duration']
style = params.get('style', 'vlog')
platform = params.get('target_platform', 'xiaohongshu')
system_prompt, user_prompt = self.prompt.build_full(
"video_script",
spot_name=spot.get('name', ''),
spot_description=spot.get('description', ''),
duration=duration,
style=style,
platform=platform
)
self.set_progress(task_id, 40)
# 3. 调用 LLM
result = await self.llm.generate(
prompt=user_prompt,
system_prompt=system_prompt
)
self.set_progress(task_id, 80)
# 4. 解析结果
script = self.parse_json(result)
if not script:
return EngineResult(
success=False,
error="脚本解析失败",
error_code="PARSE_ERROR"
)
self.set_progress(task_id, 100)
return EngineResult(
success=True,
data={
"script": script,
"scene_count": len(script.get('scenes', [])),
"total_duration": duration,
},
metadata={
"scenic_spot_id": scenic_spot_id,
"style": style,
"platform": platform,
}
)
except Exception as e:
self.log(f"视频脚本生成失败: {e}", level='error')
return EngineResult(
success=False,
error=str(e),
error_code="EXECUTION_ERROR"
)