长剧本分镜智能体:支持将任意自然语言剧本,转换为结构化分镜数据,支持视频生成与编辑。
Project description
剧本分镜智能体
中文 | English
一个基于多智能体协作的剧本分镜系统,能够将多种格式的剧本拆分为AI可生成的短视频脚本单元,输出高质量分镜片段描述,并保证叙事连续性。支持多种AI提供商,具有强大的可扩展性和易用性。
以 LangChain + LangGraph 实现通过 LLM 把任意格式剧本,解析转换为符合模型的 “Text to Video” 脚本片段提示词(5-n+5秒),且会保持片段间角色剧情的连贯性和一致性,可直接应用于Sora、Veo、Runway、Pika、Kling、通义万相、Stable Video Diffusion等模型。 支持 MCP、REST API 协议和 Function Call,可通过 A2A、LangGraph、API、Python 库等方式集成使用。
创作流程:客户端 → LLM 剧本创作 → 剧本解析(分镜转码) → DM 视频生成(文生视频) → 视频合成渲染(FFmpeg)
该项目是典型的自然语言处理(NLP)应用场景
需求描述:假如我有一段预估两分钟左右的剧本,想通过AI模型生成对应的短视频。
技术受限:目前的各种模型仅支持一次生成5-10秒长度的视频,想要生成两分钟长度的视频,只能通过“拼接”的方式,将多个5秒的片段合成为一个视频。
任务&挑战点:要实现视频拼接,第一步就需要拆分原剧本,拆分后的剧本尽量接近5-10秒时长(取决于模型),且每个视频片段还必须要保持连贯性,不然生成的视频片段合成后会导致场景、动作、人物等衔接不上。
架构及详细设计,参照博客文档:剧本分镜智能体架构设计与实现(v1.0)
核心功能
- 智能剧本解析:自动识别场景、对话和动作指令,理解故事结构
- 精准时序规划:按镜头粒度智能切分内容,分配合理时长(符合AI)
- 连续性守护:确保相邻分镜间角色状态、场景和情节的一致性
- 高质量分镜生成:生成详细的中文画面描述和英文AI视频提示词
- 音频提示词支持:为每个分镜生成对应的环境音和声音设计提示词
- 多模型支持:兼容OpenAI、Qwen、DeepSeek、Ollama等多种AI提供商
- 易用的API接口:提供Python库、Web API、LangGraph节点和A2A系统集成方式
- 可配置的生成参数:支持温度、时长、模型选择等多维度参数配置
- 错误处理与重试机制:自动重试失败的生成任务,确保高成功率
- 结果可追溯:每个分镜片段都可追溯到原剧本位置,便于验证和调整
系统说明
- 依赖外部API:LLM版本需要稳定的网络连接
- AI模型限制:生成的视频质量受限于AI视频模型能力
- 处理长剧本:长剧本可能需要分段处理
- 多语言支持:主要针对中文优化,其他语言效果待测试
- 生成时长不确定:AI生成的片段时长可能与预估不完全一致
- 连续性挑战:保持分镜间的连续性可能存在技术难点
- 用户反馈机制:当前版本不支持从用户反馈中学习优化
- 错误处理:异常情况可能导致生成失败
- 声音同步:实现声音与画面的一致性挑战,口型同步、环境音设计等需要进一步优化
- 专业级分镜:达到专业导演水准需要持续迭代和优化
快速上手
1. 环境准备
前置条件:Python 3.10 或更高版本
# 克隆项目
git clone https://github.com/neopen/video-shot-agent.git
cd video-shot-agent
# 安装为可编辑包
pip install -e .
######### 方式1:自动安装 #########
# 脚本会自动创建虚拟环境、安装依赖并启动服务,若失败,可手动安装
python main.py
######### 方式2:手动安装(uv) #########
uv venv --python 3.11
# 激活虚拟环境 (Linux/macOS)
source .venv/bin/activate
# 激活虚拟环境 (Windows)
.venv\Scripts\activate
# 安装依赖
uv pip install -r requirements.txt
2. 环境配置
复制配置文件并设置环境变量:
cp .env.example .env
编辑 .env 文件,配置必要的参数:
########################## LLM 模型配置 #########################
# 系统支持的厂商(openai, qwen, deepseek, ollama)
LLM__DEFAULT__BASE_URL=https://dashscope-intl.aliyuncs.com/api/v1
LLM__DEFAULT__API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
LLM__DEFAULT__MODEL_NAME=qwen-plus
########################## 嵌入模型配置 #########################
# 系统支持的厂商(openai, qwen, HuggingFace, ollama)
EMBED__DEFAULT__BASE_URL=https://dashscope-intl.aliyuncs.com/api/v1
EMBED__DEFAULT__API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
EMBED__DEFAULT__MODEL_NAME=text-embedding-v4
3. 启动应用
python main.py
应用将在
http://0.0.0.0:8000启动,提供API 接口服务。
4. 提交任务
提交任务(自然语言短剧本):
curl --location --request POST 'http://localhost:8000/api/v1/storyboard' \
--header 'Content-Type: application/json' \
--data-raw '{
"script": "深夜11点,城市公寓客厅,窗外大雨滂沱。林然裹着旧羊毛毯蜷在沙发里,电视静音播放着黑白老电影。茶几上半杯凉茶已凝出水雾,旁边摊开一本旧相册。手机突然震动,屏幕亮起“未知号码”。她盯着看了三秒,指尖悬停在接听键上方,喉头轻轻滚动。终于,她按下接听,将手机贴到耳边。电话那头沉默两秒,传来一个沙哑的男声:“是我。” 林然的手指瞬间收紧,指节泛白,呼吸停滞了一瞬。 她声音微颤:“……陈默?你还好吗?” 对方停顿片刻,低声说:“我回来了。” 林然猛地坐直,瞳孔收缩,泪水在眼眶中打转。她张了张嘴,却发不出声音,只有毛毯从肩头滑落。”"
}'
5. 获取结果
查看任务状态:
# HL202603061937129004 为任务提交成功后返回的 task_id
curl --location --request GET 'http://localhost:8000/api/v1/status/HL202603061937129004'
获取任务结果:
# HL202603061937129004 为任务提交成功后返回的 task_id
curl --location --request GET 'http://localhost:8000/api/v1/result/HL202603061937129004'
输出:结构化分镜结果(audio_prompt 为音频提示词信息,提示词包含双语)
{
"fragments": [
{
"fragment_id": "frag_001",
"prompt": "Cinematic wide shot: midnight 11 PM in a compact urban apartment living room — rain lashes violently against the window, blurring distant neon signs (pink, cyan, magenta) into soft streaks; dim ambient light from a silent black-and-white vintage film playing on an old CRT TV casts faint flickering glow; medium-gray fabric sofa, weathered oak coffee table, analog wall clock frozen at 11:00, half-drawn beige curtains; woman (Lin Ran) curled on sofa under a thick, off-white hand-knitted wool blanket — coarse texture, yellowed edges, visible pilling and wear; she wears a loose, muted gray cotton long-sleeve top with subtle collar folds; her face is tired but alert, eyes slightly red, jaw gently tensed; shallow depth of field, film grain, naturalistic color grading, moody chiaroscuro lighting, 35mm cinematic realism\n\n全景镜头:深夜11点的城市公寓客厅,窗外大雨滂沱,雨幕模糊映出远处霓虹灯(粉、青、洋红)的光斑;室内微光来自静音播放的黑白老电影CRT电视,泛出轻微闪烁荧光;米灰布艺沙发、原木茶几、指针停在11点的老式挂钟、半掩的米色窗帘;林然蜷坐于沙发,裹着厚实米白旧羊毛毯——粗纺质感、边缘泛黄起球、生活磨损明显;身穿中性灰素色棉质长袖上衣,宽松剪裁、领口微褶;神情疲惫而警觉,眼眶微红,下颌线轻绷;浅景深,胶片颗粒感,自然影调,明暗对比克制的电影级写实风格",
"negative_prompt": "cartoon, anime, 3D render, photorealistic stock photo, bright lighting, smiling face, modern fashion, high saturation, text, logo, watermark, sharp focus everywhere, clean unused objects, glossy surfaces, daylight, people walking, dialogue subtitles",
"duration": 4.2,
"model": "runway_gen2",
"style": "cinematic 35mm film, moody realism, shallow depth of field, natural lighting, muted palette, subtle motion blur on rain streaks",
"requires_special_attention": false,
"audio_prompt": {
"audio_id": "audio_001",
"prompt": "Low-frequency rain ambience (intensity 0.95), distant muffled TV static hiss (black-and-white film tone), near-silence punctuated by faint breath and fabric rustle — no speech, no music, no sudden transients; highly restrained dynamic range, immersive spatial audio, slight reverb suggesting small enclosed apartment space\n\n低频雨声基底(强度0.95),远处模糊的老式黑白电视底噪(嘶嘶白噪音),近乎寂静中夹杂极轻微呼吸声与羊毛毯摩擦声——无人声台词、无音乐、无突兀瞬态;高度克制的动态范围,沉浸式空间音频,轻微混响体现小户型密闭空间感",
"negative_prompt": "speech, dialogue, footsteps, door creak, music, birdsong, wind howl, thunderclap, laughter, applause, narration",
"model_type": "AudioLDM_3",
"voice_type": "narration",
"audio_style": "cinematic",
"voice_description": "ambient sound design only, no voice, pure atmospheric field recording style",
"emotion": "neutral"
}
},
......
]
}
使用方法
环境准备
安装依赖:
# 直接安装
pip install penshot
# 内部默认安装使用 ollama,如果要使用其他平台,需要安装对应的LLM包
# pip install langchain-openai 使用 openai 或 deepseek
# pip install dashscope 使用千问
配置环境:
复制示例文件:
cp .env.example .env编辑 .env 文件,填入配置
# ================= LLM默认配置 ================= # 系统支持的厂商(openai, qwen, deepseek, ollama) LLM__DEFAULT__BASE_URL=https://api.openai.com/v1 LLM__DEFAULT__API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx LLM__DEFAULT__MODEL_NAME=gpt-4-turbo-preview LLM__DEFAULT__TIMEOUT=30 # ================ 嵌入模型默认配置 ================ # 系统支持的厂商(openai, qwen, HuggingFace, ollama) EMBED__DEFAULT__BASE_URL=https://dashscope-intl.aliyuncs.com/api/v1 EMBED__DEFAULT__API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx EMBED__DEFAULT__MODEL_NAME=text-embedding-v4
1. 作为Python库使用
from penshot.api import create_penshot_agent
penshot = create_penshot_agent(max_concurrent=5)
script = """
早晨,一个女孩在咖啡馆读书,阳光透过窗户...
"""
# 异步提交任务
task_id = penshot.breakdown_script_async(
script,
callback=lambda r: print(f"回调: 任务 {r.task_id} 完成")
)
# 查询状态
status = penshot.get_task_status(task_id)
print(f"初始状态: {status.get('status')}")
# 等待结果
result = await penshot.wait_for_result_async(task_id)
print(f"最终结果: 成功={result.success}, 状态={result.status}")
示例代码:video-shot-agent/example/direct_usage.py at main · neopen/video-shot-agent
2. 集成到Web应用(API)
可以通过 HTTP API 将剧本分镜智能体集成到各种 Web 应用中:
from penshot.api import create_penshot_agent
from penshot.neopen.task import TaskStatus
app = FastAPI(
title="Penshot 分镜生成 API",
description="智能分镜视频生成服务",
version="0.1.0"
)
# 初始化服务
penshot = create_penshot_agent(max_concurrent=5)
@app.post("/api/generate", response_model=TaskResponse, tags=["Storyboard"])
async def generate_storyboard(request: ScriptRequest):
"""
生成视频分镜(异步)
"""
try:
# 异步模式
task_id = penshot.breakdown_script_async(script_text=request.script_text)
return TaskResponse(
task_id=task_id,
status=TaskStatus.PENDING,
message="任务已提交,请使用 /api/status/{task_id} 查询状态",
created_at=datetime.now(timezone.utc)
)
except Exception as e:
raise HTTPException(status_code=500, detail=f"生成失败: {str(e)}")
@app.get("/api/result/{task_id}", response_model=TaskResultResponse, tags=["Task"])
async def get_task_result(task_id: str):
"""
获取任务结果
"""
result = penshot.get_task_result(task_id)
if not result:
raise HTTPException(status_code=404, detail=f"任务不存在或未完成: {task_id}")
return TaskResultResponse(
task_id=result.task_id,
success=result.success,
status=result.status,
data=result.data,
error=result.error,
processing_time_ms=result.processing_time_ms
)
示例代码:video-shot-agent/example/web_app.py at main · neopen/video-shot-agent
3. 集成到 LangGraph 节点
可以将剧本分镜智能体作为 LangGraph 工作流中的一个节点。
示例代码:video-shot-agent/example/langgraph_integration.py at main · neopen/video-shot-agent
4. 集成到 A2A 系统
将剧本分镜智能体集成到 Agent-to-Agent 协作系统中。如:上游是剧本创作智能体,下游是 文生视频+剪辑 智能体。
示例代码:video-shot-agent/example/a2a_integration.py at main · neopen/video-shot-agent
5. 使用 MCP Client
安装环境
# 使用 Python 模块方式启动 MCP Server
python -m penshot.mcp_server
# 或指定参数启动 MCP Server
python -m penshot.mcp_server --max-concurrent 5 --queue-size 500
客户端方法示例
def breakdown_script(self, script: str, wait: bool = False, timeout: int = 300) -> dict:
"""拆分剧本"""
result = self._call("tools/call", {
"name": "breakdown_script",
"arguments": {
"script": script.strip(),
"wait": wait,
"timeout": timeout
}
})
if "error" in result:
raise Exception(result["error"]["message"])
content = result.get("result", {}).get("content", [])
if content and content[0].get("type") == "text":
text_content = content[0]["text"]
try:
parsed = json.loads(text_content)
return parsed
except json.JSONDecodeError:
print(f" [DEBUG] JSON解析失败,原始文本: {text_content}")
return {}
return {}
def get_task_result(self, task_id: str) -> dict:
"""获取任务结果"""
result = self._call("tools/call", {
"name": "get_task_result",
"arguments": {"task_id": task_id}
})
content = result.get("result", {}).get("content", [])
if content and content[0].get("type") == "text":
return json.loads(content[0]["text"])
return {}
示例代码:video-shot-agent/example/mcp_client.py at main · neopen/video-shot-agent
版本与展望
短期计划
- 智能分割:优化长镜头分割逻辑,保持动作连贯性
- 连续性检查:角色服装、位置、道具的一致性验证
- 多模型适配:针对Sora、Pika等模型的提示词优化
- 规则+LLM混合:支持本地规则处理,两种方式结合
- 英文剧本:完整支持英文剧本输入
- 错误恢复:节点失败时智能降级
- 配置扩展:更细粒度的参数控制
- 质量评分:为每个片段输出置信度评分
- 调试模式:保存中间结果,便于问题定位
- 声音支持:支持声音提示词生成,配合文生音频智能体使用,实现声音与画面的一致性
中期计划
- 高级镜头语言:支持复杂镜头运动(推拉摇移跟)
- 情感分析:根据剧本情感自动调整视觉风格
- 超长剧本:分块处理+上下文记忆(RAG + 向量数据库)
- 自动优化:从历史结果学习成功模式
- 批量处理:多剧本队列处理
- Web界面:可视化操作
- 素材库集成:支持角色/场景参考图
- 多格式导出:故事板、时间线XML、数据集格式
- 更多参数:支持更多细节控制,如镜头运动类型、构图规则、色调风格等
- 结果下载:支持导出完整分镜结果文件
长期计划
- 多模态输入:支持图片+音频+文本混合输入
- 实时预览:低分辨率快速预览
- 智能修复:自动检测并修复连续性问题
- 生态集成:Premiere/FCP/DaVinci插件
- 协作功能:多人协同+版本控制
- 学习进化:从用户反馈中自动改进
- 商业化:用量统计、团队管理、企业SLA
- 剧本仓库:历史剧本管理+版本追溯
- 增量处理:仅处理修改部分,复用已有结果
- AI导演助理:提供创意建议、镜头设计指导等增值功能
- 跨模态一致性:确保视觉输出与剧本文字描述在情感、风格上的高度一致
- 个性化定制:根据用户偏好调整分镜风格、节奏、构图等参数,满足不同创作者的需求
终极目标
- 任意剧本适配:任何长度、任何语言、任何类型
- 零信息损失:剧本100%内容被视觉化呈现
- 专业级输出:达到专业导演分镜水准
- 实时交互:边写剧本边生成预览
- 风格定制:可指定任何导演风格/电影美学
- 自动优化循环:每次使用都在进化
- 剧本-片段双向追溯:每个片段可追溯回原文位置,支持交叉验证
- 语义对齐度检测:评估生成片段与原文的匹配程度
- 多轮修正机制:根据检测结果自动调整再生成
- 剧本理解深度:潜台词、隐喻、象征的视觉化映射
- 风格一致性引擎:全剧视觉风格统一(色调、构图、节奏)
- 自动分镜评分:从专业导演视角评估分镜质量
- 人工反馈闭环:用户调整结果反馈给模型持续优化
贡献指南
欢迎提交 Issue 和 Pull Request 来改进这个项目:
- 报告问题:在使用中遇到的问题
- 功能建议:希望添加的新功能
- 代码优化:性能优化或代码重构
- 文档改进:补充或修正文档
问题反馈
- 提交 Issue:https://github.com/neopen/video-shot-agent/issues
- 功能建议:使用 Enhancement 标签
- Bug 报告:使用 Bug 标签并提供复现步骤
- 安全漏洞:请直接发送邮件至作者邮箱
许可证
MIT License - 详见 LICENSE 文件
Copyright (c) 2024 HiPeng
致谢
感谢所有贡献者和开源社区的支持。
联系方式
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file penshot-0.2.3.tar.gz.
File metadata
- Download URL: penshot-0.2.3.tar.gz
- Upload date:
- Size: 413.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
67f704dab1f49b86a303e5bad341a2ced8d8216f0c1e271d2bdba81aa6c33e4a
|
|
| MD5 |
e8210047945201baeff2015515c58912
|
|
| BLAKE2b-256 |
0956f6f6132ee0f6c9af0cc306e1b4c134927f90df1e7b54ffee45e43cdc0973
|
Provenance
The following attestation bundles were made for penshot-0.2.3.tar.gz:
Publisher:
publish-pypi.yml on neopen/video-shot-agent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
penshot-0.2.3.tar.gz -
Subject digest:
67f704dab1f49b86a303e5bad341a2ced8d8216f0c1e271d2bdba81aa6c33e4a - Sigstore transparency entry: 1243082769
- Sigstore integration time:
-
Permalink:
neopen/video-shot-agent@597a52a7c975b9ffd5a5695af756c9140f17256c -
Branch / Tag:
refs/tags/v0.2.3 - Owner: https://github.com/neopen
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@597a52a7c975b9ffd5a5695af756c9140f17256c -
Trigger Event:
release
-
Statement type:
File details
Details for the file penshot-0.2.3-py3-none-any.whl.
File metadata
- Download URL: penshot-0.2.3-py3-none-any.whl
- Upload date:
- Size: 445.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3ca17f38b18e9d5477bfd3093fd0efd8380973efce8b7656bf3012c877b4f43a
|
|
| MD5 |
9135b57191509eeb455f41a740ef74c5
|
|
| BLAKE2b-256 |
3894fdf3236611fc454174775d34cb2b343d0cf08f477b11456b47b1cf433f73
|
Provenance
The following attestation bundles were made for penshot-0.2.3-py3-none-any.whl:
Publisher:
publish-pypi.yml on neopen/video-shot-agent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
penshot-0.2.3-py3-none-any.whl -
Subject digest:
3ca17f38b18e9d5477bfd3093fd0efd8380973efce8b7656bf3012c877b4f43a - Sigstore transparency entry: 1243082806
- Sigstore integration time:
-
Permalink:
neopen/video-shot-agent@597a52a7c975b9ffd5a5695af756c9140f17256c -
Branch / Tag:
refs/tags/v0.2.3 - Owner: https://github.com/neopen
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@597a52a7c975b9ffd5a5695af756c9140f17256c -
Trigger Event:
release
-
Statement type: