generate-media
SKILL.md
短剧媒体生成技能 (Generate Media)
概述
本技能用于将 produce-anime 技能生成的作品脚本转化为实际的参考图片。生成时会读取作品的视觉风格配置(visual_style),将摄影机/镜头/胶片等参数自动注入到 AI 提示词中。当前标准流程:
- 风格选择:在生成前,使用
ask_questions工具让用户从visual_styles.json中选择视觉风格 - 生成角色参考图:根据
character_bible.md中每个角色的AI绘图关键词,使用配置图片模型批量生成角色参考图 - 生成场景四宫格图:根据
scenes/scene_bible.md中每个场景的AI绘图关键词,生成一张四宫格合成图(2×2布局:正面/左45°/右45°/背面),保存为{场景ID}_ref.png - 生成道具三视图:根据
props/prop_bible.md中每个道具的AI绘图关键词,生成一张三视图合成图(1×3布局:正面/侧面/俯视),保存为{道具ID}_ref.png - 生成分镜图片:按“两集一批”生成分镜图(每集A/B两张,共最多4张/批),角色一致性由同模型多模态提示保证,9宫格布局(3×3,16:9比例)
- 维护索引文件:media_index.json、ref_index.json 等
生成的媒体文件存放到对应各集的 EP{xx}/ 目录下。
注意:视频由 Seedance 平台生成,不在本技能中处理。分镜图片作为参考图提交到 Seedance。
前置条件
1. API 配置
需要配置 Google Gemini API Key 和 Base URL,从 /data/dongman/.config/api_keys.json 读取:
// /data/dongman/.config/api_keys.json
{
"gemini_api_key": "AIza...",
"gemini_base_url": "https://generativelanguage.googleapis.com/",
"gemini_image_model": "gemini-2.5-flash-image-preview"
}
字段说明:
gemini_api_key:Google Gemini API Key(必填)gemini_base_url:API 端点地址(可选,留空则使用 SDK 默认值;代理/自定义端点时配置)gemini_image_model:全局图片模型(必填推荐)- 默认:
gemini-2.5-flash-image-preview - 可选:
gemini-3-pro-image-preview
- 默认:
也支持环境变量覆盖(优先级高于配置文件):
GEMINI_API_KEYGEMINI_BASE_URLGEMINI_IMAGE_MODEL
2. Python 依赖
需要安装 Google Generative AI SDK:
pip install google-genai Pillow requests
3. 已有作品目录
目标作品目录必须已由 produce-anime 技能生成完毕,包含:
characters/character_bible.md(角色设定,含 AI 绘图关键词)scenes/scene_bible.md(场景设定,含 AI 绘图关键词)——可选,无则跳过场景生成props/prop_bible.md(道具设定,含 AI 绘图关键词)——可选,无则跳过道具生成- 各集
storyboard_config.json(含visual_style视觉风格配置)
执行流程
第一步:确定目标作品
- 如用户指定了作品编号(如
DM-001),直接定位到/data/dongman/projects/下对应目录 - 如用户未指定,读取
/data/dongman/projects/index.json,选择最新的作品 - 验证目标目录存在且包含
characters/character_bible.md和episodes/子目录
第二步:生成 Python 脚本并执行
在作品目录下生成 generate_media.py 脚本,然后执行。脚本逻辑如下:
2.1 脚本结构
#!/usr/bin/env python3
"""
短剧媒体生成脚本
Phase 1: 生成角色参考图
Phase 2: 参考角色图生成分镜图片
"""
import os
import re
import json
import time
import sys
from pathlib import Path
from google import genai
from google.genai import types
from PIL import Image
# ========== 配置 ==========
PROJECT_DIR = Path(__file__).parent
EPISODES_DIR = PROJECT_DIR / "episodes"
CHARACTERS_DIR = PROJECT_DIR / "characters"
# API 配置
def load_api_config():
"""从配置文件和环境变量加载 API Key 和 Base URL"""
api_key = None
base_url = None
# 先从配置文件读取
config_path = Path("/data/dongman/.config/api_keys.json")
if config_path.exists():
with open(config_path) as f:
config = json.load(f)
api_key = config.get("gemini_api_key")
base_url = config.get("gemini_base_url")
# 环境变量优先覆盖
api_key = os.environ.get("GEMINI_API_KEY", api_key)
base_url = os.environ.get("GEMINI_BASE_URL", base_url)
if not api_key:
raise RuntimeError("未找到 GEMINI_API_KEY,请配置 api_keys.json 或设置环境变量")
return api_key, base_url
api_key, base_url = load_api_config()
# 构建 Client(支持自定义 base_url)
http_options = types.HttpOptions(base_url=base_url) if base_url else None
client = genai.Client(api_key=api_key, http_options=http_options)
print(f"🔑 API 已配置 | Base URL: {base_url or '默认'}")
# ========== Phase 1: 角色参考图生成 ==========
def parse_character_bible(bible_path: str) -> list:
"""解析 character_bible.md,提取角色名和 AI 绘图关键词"""
with open(bible_path, "r", encoding="utf-8") as f:
content = f.read()
characters = []
# 匹配 ### 角色X:名字(英文名)或 ### 角色X:名字
blocks = re.split(r'### 角色\d+[::]', content)
names_pattern = re.findall(r'### 角色\d+[::]\s*(.+)', content)
for i, block in enumerate(blocks[1:]): # 跳过第一个空块
name = names_pattern[i].strip().split('(')[0].strip() if i < len(names_pattern) else f"角色{i+1}"
# 提取 AI 绘图关键词
prompt_match = re.search(r'AI绘图关键词(英文)[::]\s*(.+)', block)
if prompt_match:
ai_prompt = prompt_match.group(1).strip()
else:
continue
characters.append({
"name": name,
"ai_prompt": ai_prompt
})
return characters
def generate_character_ref(char_name: str, char_prompt: str, output_dir: Path):
"""为单个角色生成3张参考图(正面、侧面、表情)"""
views = [
{
"suffix": "front",
"label": "正面全身",
"extra": "full body front view, standing pose, white background, character reference sheet style, clear details"
},
{
"suffix": "face",
"label": "面部特写",
"extra": "face close-up portrait, front view, white background, detailed facial features, expressive eyes"
},
{
"suffix": "side",
"label": "侧面半身",
"extra": "upper body side view, three quarter angle, white background, character reference sheet"
}
]
results = []
for view in views:
filename = f"{char_name}_{view['suffix']}.png"
output_path = output_dir / filename
if output_path.exists():
print(f" ⏭️ 角色图已存在,跳过: {filename}")
results.append(str(output_path))
continue
full_prompt = f"{char_prompt}, {view['extra']}"
try:
response = client.models.generate_images(
model="imagen-3.0-generate-002",
prompt=full_prompt,
config=types.GenerateImagesConfig(
number_of_images=1,
aspect_ratio="3:4",
safety_filter_level="BLOCK_ONLY_HIGH",
person_generation="ALLOW_ADULT",
),
)
if response.generated_images:
response.generated_images[0].image.save(str(output_path))
print(f" ✅ 角色{view['label']}图: {filename}")
results.append(str(output_path))
else:
print(f" ⚠️ 角色{view['label']}图无结果: {filename}")
except Exception as e:
print(f" ❌ 角色{view['label']}图失败: {e}")
time.sleep(2)
return results
def phase1_generate_characters():
"""Phase 1: 生成所有角色参考图"""
bible_path = CHARACTERS_DIR / "character_bible.md"
if not bible_path.exists():
print("❌ character_bible.md 不存在,跳过角色参考图生成")
return {}
print("\n" + "=" * 60)
print("🎨 Phase 1: 生成角色参考图")
print("=" * 60)
characters = parse_character_bible(str(bible_path))
print(f"📋 发现 {len(characters)} 个角色")
char_ref_map = {} # name -> [image_paths]
for char in characters:
print(f"\n👤 生成角色: {char['name']}")
ref_images = generate_character_ref(char["name"], char["ai_prompt"], CHARACTERS_DIR)
char_ref_map[char["name"]] = ref_images
# 保存角色参考图索引
ref_index = {name: paths for name, paths in char_ref_map.items()}
index_path = CHARACTERS_DIR / "ref_index.json"
with open(index_path, "w", encoding="utf-8") as f:
json.dump(ref_index, f, ensure_ascii=False, indent=2)
print(f"\n📋 角色参考图索引: {index_path}")
return char_ref_map
# ========== Phase 2: 分镜图片生成(参考角色图) ==========
def upload_character_refs(char_ref_map: dict) -> dict:
"""将角色参考图上传到 Gemini,返回 name -> [uploaded_file] 映射"""
uploaded = {}
for name, paths in char_ref_map.items():
files = []
for p in paths:
if os.path.exists(p):
try:
f = client.files.upload(file=p)
files.append(f)
except Exception as e:
print(f" ⚠️ 上传 {p} 失败: {e}")
uploaded[name] = files
return uploaded
def generate_storyboard_image_with_refs(
grid_prompt: str,
grid_characters: list,
char_uploaded: dict,
output_path: str
) -> bool:
"""使用 Gemini 原生图片生成(参考角色图生成分镜图)"""
try:
# 构建包含角色参考图的 prompt
# 收集本格涉及的角色参考图
ref_parts = []
char_names = []
for char_info in grid_characters:
char_name = char_info.get("name", "")
if char_name and char_name in char_uploaded:
char_names.append(char_name)
for uploaded_file in char_uploaded[char_name]:
ref_parts.append(uploaded_file)
# 如果有角色参考图,使用 Gemini 多模态生成
if ref_parts:
ref_desc = "、".join(char_names)
combined_prompt = (
f"Based on these character reference images for {ref_desc}, "
f"generate a new cinematic scene image: {grid_prompt}. "
f"Keep the characters' appearance consistent with the reference images. "
f"16:9 aspect ratio, high quality cinematic style."
)
contents = []
for ref_file in ref_parts:
contents.append(ref_file)
contents.append(combined_prompt)
response = client.models.generate_content(
model="gemini-2.0-flash-exp",
contents=contents,
config=types.GenerateContentConfig(
response_modalities=["IMAGE", "TEXT"],
),
)
# 提取生成的图片
if response.candidates:
for part in response.candidates[0].content.parts:
if part.inline_data and part.inline_data.mime_type.startswith("image/"):
image = Image.open(io.BytesIO(part.inline_data.data))
image.save(output_path)
print(f" ✅ 分镜图(参考角色): {Path(output_path).name}")
return True
# 无角色参考图或 Gemini 生成失败,降级为 Imagen 直接生成
return generate_image_imagen(grid_prompt, output_path)
except Exception as e:
print(f" ⚠️ Gemini 参考生成失败 ({e}),降级为 Imagen...")
return generate_image_imagen(grid_prompt, output_path)
def generate_image_imagen(prompt: str, output_path: str) -> bool:
"""降级方案:直接使用 Imagen 生成图片(无角色参考)"""
try:
response = client.models.generate_images(
model="imagen-3.0-generate-002",
prompt=prompt,
config=types.GenerateImagesConfig(
number_of_images=1,
aspect_ratio="16:9",
safety_filter_level="BLOCK_ONLY_HIGH",
person_generation="ALLOW_ADULT",
),
)
if response.generated_images:
response.generated_images[0].image.save(output_path)
print(f" ✅ 分镜图(Imagen): {Path(output_path).name}")
return True
else:
print(f" ⚠️ Imagen 无结果: {Path(output_path).name}")
return False
except Exception as e:
print(f" ❌ Imagen 失败: {e}")
return False
# ========== 逐集处理 ==========
def process_episode(ep_dir: Path, ep_num: str, char_uploaded: dict):
"""处理单集:生成分镜图片(参考角色)"""
config_path = ep_dir / "storyboard_config.json"
if not config_path.exists():
print(f"⚠️ {ep_num}: storyboard_config.json 不存在,跳过")
return None
with open(config_path) as f:
config = json.load(f)
print(f"\n{'='*50}")
print(f"📺 处理 {ep_num}: {config.get('episode_title', '未知')}")
print(f"{'='*50}")
results = {"images": 0, "failed": 0}
for part_key, part_label in [("part_a", "上"), ("part_b", "下")]:
part = config.get(part_key)
if not part:
continue
video_id = part["video_id"]
print(f"\n--- {part_label}半部分 ({video_id}) ---")
# 生成6宫格分镜图片(参考角色图)
grids = part.get("storyboard_9grid", [])
for grid in grids:
grid_num = grid["grid_number"]
prompt = grid.get("ai_image_prompt", "")
if not prompt:
continue
img_filename = f"{video_id}_grid{grid_num}.png"
img_path = str(ep_dir / img_filename)
if os.path.exists(img_path):
print(f" ⏭️ 已存在: {img_filename}")
results["images"] += 1
continue
# 获取本格涉及的角色列表
grid_characters = grid.get("characters", [])
if grid_characters and char_uploaded:
# 有角色 → 使用 Gemini 参考角色图生成
success = generate_storyboard_image_with_refs(
prompt, grid_characters, char_uploaded, img_path
)
else:
# 无角色(纯场景) → 直接 Imagen
success = generate_image_imagen(prompt, img_path)
if success:
results["images"] += 1
else:
results["failed"] += 1
time.sleep(2)
return results
# ========== 主流程 ==========
def main():
import io # for BytesIO in Gemini image generation
start_ep = int(sys.argv[1]) if len(sys.argv) > 1 else 1
end_ep = int(sys.argv[2]) if len(sys.argv) > 2 else 25
skip_chars = "--skip-chars" in sys.argv # 跳过角色生成(已有时)
print(f"🎬 短剧媒体生成")
print(f"📁 项目: {PROJECT_DIR}")
print(f"📺 范围: EP{start_ep:02d} - EP{end_ep:02d}")
# ===== Phase 1: 角色参考图 =====
if skip_chars:
print("\n⏭️ 跳过角色参考图生成(使用已有)")
ref_index_path = CHARACTERS_DIR / "ref_index.json"
if ref_index_path.exists():
with open(ref_index_path) as f:
char_ref_map = json.load(f)
else:
char_ref_map = {}
else:
char_ref_map = phase1_generate_characters()
# ===== 上传角色图到 Gemini =====
print("\n📤 上传角色参考图到 Gemini...")
char_uploaded = upload_character_refs(char_ref_map) if char_ref_map else {}
print(f" 已上传 {sum(len(v) for v in char_uploaded.values())} 张角色参考图")
# ===== Phase 2: 逐集生成分镜图片 =====
total = {"images": 0, "failed": 0}
for ep in range(start_ep, end_ep + 1):
ep_num = f"EP{ep:02d}"
ep_dir = EPISODES_DIR / ep_num
if not ep_dir.exists():
print(f"⚠️ {ep_num} 不存在,跳过")
continue
result = process_episode(ep_dir, ep_num, char_uploaded)
if result:
for k in total:
total[k] += result[k]
# ===== 媒体索引 =====
generate_media_index(start_ep, end_ep)
print(f"\n{'='*60}")
print(f"🏁 全部完成!")
print(f"🎨 角色参考图: {sum(len(v) for v in char_ref_map.values())} 张")
print(f"🖼️ 分镜图片: {total['images']} 张")
print(f"❌ 失败: {total['failed']} 个")
print(f"{'='*60}")
def generate_media_index(start_ep, end_ep):
"""生成媒体文件索引"""
index = {
"characters": [],
"episodes": []
}
# 角色图索引
for f in sorted(CHARACTERS_DIR.iterdir()):
if f.suffix == ".png":
index["characters"].append({
"filename": f.name,
"size_bytes": f.stat().st_size
})
# 各集媒体索引
for ep in range(start_ep, end_ep + 1):
ep_num = f"EP{ep:02d}"
ep_dir = EPISODES_DIR / ep_num
if not ep_dir.exists():
continue
ep_entry = {"episode": ep_num, "files": []}
for f in sorted(ep_dir.iterdir()):
if f.suffix in (".png", ".mp4"):
ep_entry["files"].append({
"filename": f.name,
"type": "image" if f.suffix == ".png" else "video",
"size_bytes": f.stat().st_size
})
index["episodes"].append(ep_entry)
index_path = PROJECT_DIR / "media_index.json"
with open(index_path, "w", encoding="utf-8") as f:
json.dump(index, f, ensure_ascii=False, indent=2)
print(f"\n📋 媒体索引: {index_path}")
if __name__ == "__main__":
main()
第三步:执行脚本
运行脚本,支持多种模式:
# 完整流程:角色参考图 → 分镜图片(全25集)
python3 generate_media.py
# 指定集数范围(如 EP01-EP05)
python3 generate_media.py 1 5
# 跳过角色参考图生成(已有角色图时,直接生成分镜)
python3 generate_media.py 1 25 --skip-chars
第四步:验证生成结果
脚本执行完成后,验证:
characters/目录包含角色参考图(每角色1张:{角色名}_ref.png)scenes/目录包含场景四宫格图(每场景1张:{场景ID}_ref.png,含4视角合成)props/目录包含道具三视图(每道具1张:{道具ID}_ref.png,含3视角合成)- 每集目录包含 2 张分镜 PNG(A/B)
- 各
ref_index.json已生成
两阶段生成流程详解
Phase 1: 角色参考图生成(当前标准)
| 步骤 | 说明 |
|---|---|
解析 character_bible.md |
提取每个角色的名字和 AI绘图关键词(英文) |
| 生成方式 | 单次请求多图(最多7张),按角色顺序落盘 |
| 模型 | 单一配置模型:gemini_image_model |
| 存放位置 | characters/{角色名}_ref.png |
| 索引文件 | characters/ref_index.json(角色名 → 图片路径映射) |
| 失败策略 | 不做单张兜底(返回不足只记失败) |
Phase 1B: 场景四宫格图生成
| 步骤 | 说明 |
|---|---|
解析 scenes/scene_bible.md |
提取每个场景的 场景ID、场景名 和 AI绘图关键词(英文) |
| 生成方式 | 每个场景一次API请求,生成一张 2×2 四宫格合成图(正面/左45°/右45°/背面) |
| 模型 | 单一配置模型:gemini_image_model |
| 提示词结构 | 提示模型在单张图中绘制4格布局,含场景描述 + 视觉风格后缀 |
| 输出 | 每场景1张:scenes/{场景ID}_ref.png(四宫格合成图) |
| 索引文件 | scenes/ref_index.json(场景ID → 图片路径映射) |
| 失败策略 | 不做单张兜底(无返回只记失败) |
Phase 1C: 道具三视图生成
| 步骤 | 说明 |
|---|---|
解析 props/prop_bible.md |
提取每个道具的 道具ID、道具名 和 AI绘图关键词(英文) |
| 生成方式 | 每个道具一次API请求,生成一张 1×3 三视图合成图(正面/侧面/俯视) |
| 模型 | 单一配置模型:gemini_image_model |
| 提示词结构 | 提示模型在单张图中绘制3格横排布局,含道具描述 + 视觉风格后缀 |
| 输出 | 每道具1张:props/{道具ID}_ref.png(三视图合成图) |
| 索引文件 | props/ref_index.json(道具ID → 图片路径映射) |
| 失败策略 | 不做单张兜底(无返回只记失败) |
Phase 2: 分镜图片生成(当前标准)
| 步骤 | 说明 |
|---|---|
| 生成粒度 | 两集一批(每集A/B两张,共最多4张/请求) |
| 读取配置 | 从每集 storyboard_config.json 读取 storyboard_9grid 与角色列表 |
| 角色一致性 | 将角色参考图内联到请求中,保持外观一致 |
| 布局 | 3×3 九宫格,16:9比例 |
| 输出文件 | EPxx/{video_id}_storyboard.png(每集2张:A/B) |
| 失败策略 | 不做单张兜底(返回不足只记失败) |
视频生成:由 Seedance 平台处理。分镜图片和角色参考图作为
referenceFiles提交到 Seedance,由其生成最终视频。
生成文件命名规则
角色参考图
characters/
├── character_bible.md # 角色设定(原有)
├── ref_index.json # 角色参考图索引(生成)
├── 林策_ref.png
├── 沈璃_ref.png
├── 祁远_ref.png
└── ...
场景四宫格图(每场景1张合成图)
scenes/
├── scene_bible.md # 场景设定(原有)
├── ref_index.json # 场景参考图索引(生成)
├── scene_01_ref.png # 四宫格合成图(正面/左45°/右45°/背面)
├── scene_02_ref.png
└── ...
道具三视图(每道具1张合成图)
props/
├── prop_bible.md # 道具设定(原有)
├── ref_index.json # 道具参考图索引(生成)
├── prop_01_ref.png # 三视图合成图(正面/侧面/俯视)
├── prop_02_ref.png
└── ...
分镜图片
分镜图片命名格式:{视频编号}_storyboard.png
EP01/
├── DM-001-EP01-A_storyboard.png # 上半部分分镜图
├── DM-001-EP01-B_storyboard.png # 下半部分分镜图
├── dialogue.md # 对话脚本(原有)
├── storyboard_config.json # 故事板配置(原有)
└── seedance_tasks.json # Seedance提交任务(原有)
各文件说明
| 文件类型 | 数量/集 | 来源 | 格式 |
|---|---|---|---|
| 分镜图片 | 2张(A/B各1张) | storyboard_6grid + 批量提示词 |
PNG |
全作品统计(以3个主角、4个场景、3个道具为例)
| 指标 | 数量 |
|---|---|
| 角色参考图 | 3张(3角色 × 1张,含四宫格多视角) |
| 场景四宫格图 | 4张(4场景 × 1张合成图) |
| 道具三视图 | 3张(3道具 × 1张合成图) |
| 总集数 | 25 |
| 每集分镜图片 | 2张 |
| 总分镜图片 | 50张 |
| 总媒体文件 | 60个(3角色 + 4场景 + 3道具 + 50分镜) |
Google API 模型说明
图片模型(统一配置)
- 配置项:
gemini_image_model - 允许值:
gemini-2.5-flash-image-preview(默认推荐)gemini-3-pro-image-preview(可选)
- 用途:
- Phase 1 角色参考图批量生成
- Phase 2 分镜图批量生成
- 约束:全流程只使用这一个图片模型,不混用其他图片模型
API 限流与容错
限流策略
- 每次图片生成后 暂停 2 秒
容错机制
- 跳过已存在文件:如文件已存在则跳过,支持断点续传
- 单个失败不影响全局:某格/某集失败后继续处理下一个
- 集数范围可指定:支持只生成指定范围的集数,方便重试
重试示例
# 只重新生成第3集
python3 generate_media.py 3 3
# 重新生成第10-15集
python3 generate_media.py 10 15
如果某个文件需要重新生成,手动删除该文件后重新运行脚本即可。
运行指令
用户可以通过以下方式触发本技能:
- "生成分镜图片"
- "generate media"
- "生成短剧媒体"
- "调用API生成图片"
- "把分镜变成图片"
- "执行媒体生成"
可附带参数:
- 作品编号:如 "生成 DM-001 的图片"
- 集数范围:如 "生成第1到第5集的图片"
- 仅角色图:
--only-chars - 跳过角色图:
--skip-chars
执行检查清单
- 确认
GEMINI_API_KEY已配置(环境变量或配置文件) - 确认
google-genai、Pillow、requests已安装 - 确认
gemini_image_model已配置且合法 - 确认目标作品目录存在且
character_bible.md和storyboard_config.json完整 - 生成
generate_media.py脚本到作品目录 - 风格选择:已通过
ask_questions让用户选择视觉风格 - Phase 1:角色参考图已生成到
characters/目录 - Phase 1B:场景四宫格图已生成到
scenes/目录(每场景1张{场景ID}_ref.png) - Phase 1C:道具三视图已生成到
props/目录(每道具1张{道具ID}_ref.png) - Phase 2:分镜图片已生成且参考了角色外观
- 每集
seedance_tasks.json已存在(2条任务:Part-A/B) - 验证
characters/ref_index.json已生成 - 验证每集目录包含 2 张分镜 PNG(A/B)
- 验证
media_index.json已生成 - 检查是否有失败项需要重试
输出示例
生成完成后,向用户报告:
✅ 短剧媒体生成完成!
📋 作品信息
- 作品编号:DM-001
- 作品名称:《灯火归途》
- 视觉风格:Dark Thriller(暗黑悬疑)
📁 项目目录:/data/dongman/projects/DM-001_dhgt/
📊 生成统计
🎨 Phase 1 - 角色参考图
- 林策_ref.png, 沈璃_ref.png, 祁远_ref.png
- 小计: 3 张
🏙️ Phase 1B - 场景四宫格图
- scene_01_ref.png (办公室): 四宫格合成图
- scene_02_ref.png (车间): 四宫格合成图
- 小计: 2 张(每张含4视角)
🔧 Phase 1C - 道具三视图
- prop_01_ref.png (画作): 三视图合成图
- 小计: 1 张(每张含3视角)
🖼️ Phase 2 - 分镜图片(参考角色)
- 50 张(25集 × A/B各1张)
❌ 失败: 0 个
📂 文件结构
characters/
├── 林策_ref.png
├── ref_index.json
scenes/
├── scene_01_ref.png # 四宫格合成图
├── scene_02_ref.png
├── ref_index.json
props/
├── prop_01_ref.png # 三视图合成图
├── ref_index.json
EP01/
├── DM-001-EP01-A_storyboard.png
├── DM-001-EP01-B_storyboard.png
├── dialogue.md
└── storyboard_config.json
📋 媒体索引:media_index.json
💡 提示:使用 submit_project.py 提交任务到 Seedance 生成视频
Weekly Installs
9
Repository
zhaihao118/micr…a-skillsGitHub Stars
84
First Seen
Feb 22, 2026
Security Audits
Installed on
gemini-cli9
github-copilot9
codex9
amp9
kimi-cli9
openclaw9