前言
很多人想把小说或长文本“可视化”,但常见痛点是:
模型输出是 JSON,普通用户难以编辑
视频生成是异步任务,提交后不知道怎么查结果
需要一套完整流程:录入 → 分析 → 编辑 → 提交 → 查询
本文用一个入门级的 Flask + Vue 小系统,把“小说转视频”流程跑通,同时保留编辑能力。
目标效果
输入章节文本
自动分析 人物 / 场景 / 分镜
结果支持表单编辑(可切换原始 JSON)
提交后得到 task_id
超时后可通过查询接口拿到结果
-
项目结构
videoAgent/
web_app.py
templates/
index.html
services/
video_service.py
task_store.py
agents/
character_agent.py
scene_agent.py
storyboard_agent.py
prompt/
character_prompt.py
scene_prompt.py
storyboard_prompt.py -
核心思路
后端(Flask)
/api/analyze:调用三步 LLM 分析(人物/场景/分镜)
/api/submit:提交视频生成任务并记录 task_id
/api/tasks:列出任务
/api/task/<task_id>:查询任务结果
前端(Vue)
表单方式编辑人物/场景/分镜
“切换原始 JSON”给进阶用户
提交后展示任务列表并支持查询
- 后端实现
3.1 任务存储(JSON 文件持久化)
# services/task_store.py
import json, os, threading, time
TASK_DB = os.path.join("memory", "tasks.json")
_lock = threading.Lock()
def _load():
if not os.path.exists(TASK_DB):
return {}
with open(TASK_DB, "r", encoding="utf-8") as f:
return json.load(f)
def _save(data):
os.makedirs(os.path.dirname(TASK_DB), exist_ok=True)
with open(TASK_DB, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
def create_task(task_id, payload):
now = int(time.time())
with _lock:
data = _load()
data[task_id] = {"task_id": task_id, "status": "PENDING", "created_at": now, "updated_at": now, **payload}
_save(data)
3.2 视频任务提交 + 查询
# services/video_service.py
def submit_video_task(prompt, size="1920x1080", fps=30, quality="speed", with_audio=True, duration=10, max_retry=5):
...
for i in range(max_retry):
resp = requests.post(API_URL, headers=headers, json=data)
if resp.status_code == 429:
time.sleep(2 + i * 2)
continue
if resp.status_code >= 400:
raise ValueError(...)
result = resp.json()
task_id = result.get("id")
if task_id:
return task_id
raise ValueError("触发频率限制")
3.3 Flask 入口
# web_app.py
@app.post("/api/analyze")
def analyze():
payload = request.get_json(force=True)
chapter_text = (payload.get("chapter_text") or "").strip()
characters = extract_characters(chapter_text)
scenes = extract_scenes(chapter_text)
storyboard = generate_storyboard(scenes)
return jsonify({
"characters": characters,
"scenes": scenes,
"storyboard": storyboard if isinstance(storyboard, list) else storyboard["scenes"]
})
- 前端实现
4.1 Vue 表单模式(可编辑)
<div v-for="(c, idx) in characters" :key="idx">
<input v-model="c.name" placeholder="name" />
<input v-model="c.gender" placeholder="gender" />
<input v-model="c.abilitiesText" placeholder="abilities (逗号分隔)" />
</div>
4.2 切换原始 JSON
<button @click="toggleRaw('characters')">切换原始 JSON</button>
<textarea v-if="showRaw.characters" v-model="charactersJson"></textarea>
效果图


675



被折叠的 条评论
为什么被折叠?



