AI视频叙事Skill video-storytelling

AI视频叙事技能利用人工智能生成图像和语音配音,自动创建连贯的视频故事序列。适用于教育内容、娱乐视频、角色驱动叙事和多场景故事制作。关键词:AI生成图像、语音叙事、视频故事、AIGC、视觉一致性、自动视频组装、教育视频、角色配音。

AIGC 0 次安装 0 次浏览 更新于 3/12/2026

name: video-storytelling description: | 使用AI生成的图像和配音音频创建连贯的视频故事序列。 结合图像生成和elevenlabs技能,生成完整的视频故事,在所有场景中保持视觉和叙事一致性。在整个故事中维护角色外观、风格、照明和声音一致性。

当用户请求以下内容时使用此技能:

  • 带配音的视频故事
  • 动画故事序列
  • 教育视频内容
  • 带有视觉的角色驱动叙事
  • 多场景故事视频
  • 配音图像序列

功能:视觉一致性锁定、角色持久性、多轮图像生成、角色声音配音、自动视频组装

默认:1个标题场景 + 5个故事场景 依赖:image-generation技能、elevenlabs技能、ffmpeg allowed-tools: [“*”]

视频叙事

目的

此技能通过结合AI生成的图像与配音音频创建连贯的视频故事序列。充当故事导演和视觉协调员,在所有场景中保持角色、视觉风格、照明和叙事语调的完美一致性。生成包含同步图像和角色配音的完整MP4视频。

何时使用

当用户要求以下内容时,应调用此技能:

  • 创建视频故事或动画序列
  • 生成带视觉的配音故事
  • 制作带角色的教育视频内容
  • 制作带配音的视觉故事书
  • 创建角色驱动的视频叙事
  • 生成多场景故事视频
  • 制作带图片和配音的儿童故事

核心能力

视觉一致性系统

全局风格锁定:

  • 固定宽高比、相机设置、照明
  • 所有场景中一致的调色板
  • 统一的视觉风格和后处理
  • 防止视觉不连续

角色锁定:

  • 在场景间保持角色外观
  • 相同的服装、颜色、面部特征贯穿始终
  • 一致的配饰和独特特征
  • 视觉身份保留

多轮图像生成:

  • 每个场景引用先前场景的图像
  • 通过序列构建视觉连续性
  • 防止角色/风格漂移

叙事系统

角色声音:

  • 将角色映射到ElevenLabs声音
  • 保持每个角色的声音一致性
  • 支持对话中的多个角色

情感标签:

  • 带有情感标记的表达性配音
  • 音效和暂停
  • 自然节奏和传递

叙事结构:

  • 每个场景50-80词(15-20秒)
  • 中性叙述者用于过渡
  • 角色特定对话

视频组装

自动化流水线:

  • 按顺序生成所有图像
  • 创建角色配音
  • 组合成同步的MP4视频
  • 基于总音频长度等分时间每个场景

默认配置

场景结构

  • 默认: 1个标题场景(场景0)+ 5个故事场景(场景1-5)
  • 总计: 6个场景
  • 可定制: 用户可以指定不同的场景数量

默认风格锁定

STYLE_LOCK:
- 宽高比:1080×1080(方形)
- 相机:50mm镜头,眼平视角
- 照明:柔和三点照明,暖主光(4500K)
- 调色板:#0B5FFF, #FFB703, #FB8500, #023047, #8ECAE6
- 材质:哑光饰面,无颗粒感或重光晕
- 背景:微妙渐变,简洁构图
- 风格:半写实卡通,线条清晰,柔和阴影
- 后处理:清晰对焦,无晕影或文本伪影

NEGATIVE_LOCK:
无文本错误,无拼写错误,无水印,无贴纸,
无额外字符,无视觉噪点,无剧烈照明变化

自定义: 用户可以用自定义风格锁定覆盖,但默认确保一致性。

默认声音映射

来自ElevenLabs声音:

叙述者:

  • 中性叙述者(男性):George (JBFqnCBsd6RMkjVDRZzb)
  • 中性叙述者(女性):Rachel (21m00Tcm4TlvDq8ikWAM)

角色声音:

  • 年轻男性(精力充沛):Josh (TxGEqnHWrfWFTfGW9XjX)
  • 年轻女性(冷静):Rachel (21m00Tcm4TlvDq8ikWAM)
  • 年轻女性(表达性强):Bella (EXAVITQu4vr4xnSDxMaL)
  • 男性(权威):Adam (pNInz6obpgDQGcFmaJgB)
  • 女性(温暖):Matilda (XrExE9yKIg1WjnnlVkGX)
  • 年轻男性(友好):Antoni (ErXwobaYiN019PkySvjV)

分配逻辑:

  • 如果指定角色性别/年龄,匹配到适当声音
  • 如果未指定,男性使用Josh,女性使用Rachel
  • 叙述者默认使用George(男性)或Rachel(女性)

指令

步骤1:收集故事信息

从用户收集必要信息:

必需:

  • 故事概念: 故事关于什么?
  • 语调/类型: 教育、冒险、喜剧、戏剧等。

可选(如果缺失则提示):

  • 场景数量: 默认为6(1标题+5故事),但用户可以指定
  • 角色描述: 姓名、外观、性格
  • 自定义风格锁定: 如果用户有特定要求,覆盖默认

示例提示:

"你的故事关于什么?"
"你想要多少场景?(默认:1标题+5故事场景)"
"描述你的主要角色:姓名、外观、性格"
"有特定的视觉风格偏好吗?(默认:半写实卡通)"

步骤2:定义角色

为故事中的每个角色创建角色档案:

角色档案模板:

character = {
    "name": "角色姓名",
    "species": "人类/动物/生物",
    "description": "简短描述",
    "colors": {
        "primary": "#HEX",
        "secondary": "#HEX"
    },
    "outfit": "服装描述",
    "features": ["独特特征1", "特征2", "特征3"],
    "personality": "性格描述",
    "voice_id": "elevenlabs-voice-id",
    "voice_name": "ElevenLabs声音名称"
}

示例:

pyter_python = {
    "name": "Pyter Python",
    "species": "友好蛇吉祥物",
    "description": "一个愉快的编码导师蛇",
    "colors": {
        "body": "#0B5FFF",  # 蓝色
        "belly": "#FFB703"   # 黄色
    },
    "outfit": "带圆形π标志的小白实验服",
    "features": ["大眼睛棕色", "圆头", "愉快微笑"],
    "personality": "热情、有帮助、好奇",
    "voice_id": "TxGEqnHWrfWFTfGW9XjX",
    "voice_name": "Josh"
}

声音分配:

  • 询问用户声音偏好或基于角色自动分配
  • 为常见类型使用默认映射
  • 允许从ElevenLabs库中选择自定义声音

步骤3:规划故事序列

创建逐场景大纲:

场景0(标题场景):

  • 视觉:带主要角色的标题卡
  • 音频:故事介绍(叙述者或主要角色)
  • 时长:约15-20秒

场景1-N(故事场景):

  • 视觉:连续故事时刻
  • 音频:带有角色对话的叙事
  • 时长:每个约15-20秒

示例场景计划:

scene_plan = [
    {
        "number": 0,
        "type": "title",
        "visual_description": "Pyter Python带笔记本电脑,'Pyter的编码冒险'文本叠加",
        "characters": ["Pyter Python"],
        "narrative": "[愉快] 加入Pyter Python,开启激动人心的编码冒险!",
        "speaker": "Narrator",
        "voice_id": "JBFqnCBsd6RMkjVDRZzb"
    },
    {
        "number": 1,
        "type": "story",
        "visual_description": "Pyter在桌前看着显示错误消息的计算机屏幕,困惑表情",
        "characters": ["Pyter Python"],
        "narrative": "[困惑] 嗯...这个错误消息是什么意思?[暂停] 我以为我的代码完美!",
        "speaker": "Pyter Python",
        "voice_id": "TxGEqnHWrfWFTfGW9XjX"
    },
    # ... 更多场景
]

步骤4:构建风格和角色锁定

准备全局风格锁定:

STYLE_LOCK = """
宽高比:1080×1080(方形)
相机:50mm镜头,眼平视角
照明:柔和三点照明,暖主光(4500K)
调色板:#0B5FFF, #FFB703, #FB8500, #023047, #8ECAE6
材质:哑光饰面,无颗粒感或重光晕
背景:微妙渐变,简洁构图
风格:半写实卡通,线条清晰,柔和阴影
后处理:清晰对焦,无晕影或文本伪影
"""

NEGATIVE_LOCK = """
无文本错误,无拼写错误,无水印,无贴纸,
无额外字符,无视觉噪点,无剧烈照明变化
"""

为每个场景构建角色锁定:

def build_character_lock(characters_in_scene):
    lock = ""
    for character in characters_in_scene:
        lock += f"""
角色:{character['name']}
物种:{character['species']}
颜色:身体 {character['colors']['primary']}, 次要 {character['colors']['secondary']}
服装:{character['outfit']}
关键特征:{', '.join(character['features'])}
"""
    return lock

步骤5:生成图像序列

使用多轮生成生成图像以确保一致性:

实现:

from pathlib import Path
import json

# 初始化跟踪
previous_image_id = None
image_files = []

# 生成每个场景
for scene in scene_plan:
    print(f"生成场景 {scene['number']}: {scene['visual_description']}")

    # 为此场景构建角色锁定
    character_lock = build_character_lock(
        [char_profiles[name] for name in scene['characters']]
    )

    # 构建完整图像提示
    image_prompt = f"""
{STYLE_LOCK}

{character_lock}

场景描述:
{scene['visual_description']}

{NEGATIVE_LOCK}
"""

    # 如果不是第一个场景,添加对先前场景的引用
    if previous_image_id:
        image_prompt += f"
为一致性参考先前场景:{previous_image_id}"

    # 使用图像生成技能生成图像
    # (这将调用图像生成技能)
    # 为实现,使用适当模型(DALL-E 3 或 Gemini Pro)

    result = generate_image(
        prompt=image_prompt,
        model="dall-e-3",  # 或 gemini-3-pro-image-preview
        size="1024x1024",
        reference_image=previous_image_id
    )

    # 保存图像
    filename = f"scene-{scene['number']:02d}.png"
    save_image(result, filename)
    image_files.append(filename)

    # 为下一个场景引用跟踪
    previous_image_id = result['image_id']

    print(f"  ✓ 保存:{filename}")

关键点:

  • 场景0生成基础图像
  • 场景1+为一致性参考先前场景
  • 对每个提示应用STYLE_LOCK和CHARACTER_LOCK
  • 使用顺序编号保存

步骤6:生成叙事音频

为每个场景创建声音配音:

实现:

from elevenlabs.client import ElevenLabs

client = ElevenLabs(api_key=os.environ['ELEVENLABS_API_KEY'])
audio_files = []

for scene in scene_plan:
    print(f"为场景 {scene['number']} 生成音频")

    # 准备对话输入
    dialogue_input = {
        "text": scene['narrative'],
        "name": scene['speaker'],
        "voice_id": scene['voice_id']
    }

    # 使用text_to_dialogue生成音频
    audio = client.text_to_dialogue.convert(
        inputs=[dialogue_input]
    )

    # 保存音频文件
    filename = f"scene-{scene['number']:02d}.mp3"
    with open(filename, 'wb') as f:
        for chunk in audio:
            f.write(chunk)

    audio_files.append(filename)
    print(f"  ✓ 保存:{filename}")

叙事指南:

  • 每个场景50-80词
  • 使用情感标签:[兴奋], [沉思], [困惑], [暂停]
  • 适当时包含音效:[音效:门吱吱响]
  • 用暂停变化节奏

步骤7:连接音频

将所有场景音频组合成单个音轨:

实现:

import subprocess

# 构建ffmpeg连接命令
concat_filter = "concat=n={}:v=0:a=1[out]".format(len(audio_files))

inputs = []
for audio_file in audio_files:
    inputs.extend(['-i', audio_file])

cmd = ['ffmpeg', '-y'] + inputs + [
    '-filter_complex', concat_filter,
    '-map', '[out]',
    'full_audio.mp3'
]

subprocess.run(cmd, check=True)
print("✓ 音频连接:full_audio.mp3")

步骤8:组装最终视频

使用包含的 assemble_video.sh 脚本:

实现:

import subprocess
from pathlib import Path

# 准备命令
script_path = Path(__file__).parent / "scripts" / "assemble_video.sh"
cmd = [str(script_path), "full_audio.mp3"] + image_files

# 运行组装
subprocess.run(cmd, check=True)

# 输出将是 full_audio.mp4
print("✓ 视频创建:full_audio.mp4")

脚本详情:

  • 基于总音频长度计算每个图像的相等时间
  • 为每个图像创建视频片段
  • 确保所有图像正好1080×1080(如果需要则填充)
  • 连接片段
  • 与音频轨道复用
  • 输出高质量的H.264 MP4

步骤9:交付结果

提供给用户:

  1. 最终视频文件: <故事名称>.mp4
  2. 场景分解: 每个场景的摘要
  3. 单独资源: 图像和音频文件(如果请求)
  4. 故事元数据: 角色档案、场景计划(如果请求)

示例输出:

✓ 视频故事创建:pyter-coding-adventure.mp4

场景:
  0. 标题:"Pyter的编码冒险" (20s)
  1. Pyter遇到错误 (18s)
  2. Pyter意识到错误 (17s)
  3. Pyter修复代码 (19s)
  4. 代码运行成功 (16s)
  5. Pyter庆祝 (15s)

总时长:1:45
分辨率:1080×1080
角色:Pyter Python(由Josh配音)

生成文件:
  - pyter-coding-adventure.mp4(最终视频)
  - scene-00.png 到 scene-05.png(图像)
  - scene-00.mp3 到 scene-05.mp3(音频)
  - full_audio.mp3(连接音频)

角色声音参考

ElevenLabs声音ID

叙述者:

  • George(男性,中年,叙事):JBFqnCBsd6RMkjVDRZzb
  • Rachel(女性,年轻,冷静):21m00Tcm4TlvDq8ikWAM

年轻角色:

  • Josh(男性,精力充沛):TxGEqnHWrfWFTfGW9XjX
  • Bella(女性,表达性强):EXAVITQu4vr4xnSDxMaL
  • Antoni(男性,友好):ErXwobaYiN019PkySvjV
  • Elli(女性,情感丰富):MF3mGyEYCl7XYWbV9V6O

成年角色:

  • Adam(男性,权威):pNInz6obpgDQGcFmaJgB
  • Domi(女性,自信):AZnzlk1XvdvUeBnXmlld
  • Matilda(女性,温暖):XrExE9yKIg1WjnnlVkGX

分配策略:

def assign_voice(character):
    """基于角色属性自动分配声音"""

    # 检查显式分配
    if 'voice_preference' in character:
        return get_voice_id(character['voice_preference'])

    # 基于属性自动分配
    age = character.get('age', 'young')
    gender = character.get('gender', 'male')

    if age == 'young':
        if gender == 'male':
            return 'TxGEqnHWrfWFTfGW9XjX'  # Josh
        else:
            return '21m00Tcm4TlvDq8ikWAM'  # Rachel
    else:  # adult
        if gender == 'male':
            return 'pNInz6obpgDQGcFmaJgB'  # Adam
        else:
            return 'XrExE9yKIg1WjnnlVkGX'  # Matilda

示例故事生成

完整示例:“Pyter的第一个错误”

用户请求: “创建一个关于编码蛇修复他第一个错误的短故事”

步骤1:角色定义

pyter = {
    "name": "Pyter Python",
    "species": "友好蛇",
    "colors": {"body": "#0B5FFF", "belly": "#FFB703"},
    "outfit": "带π标志的白实验服",
    "features": ["大眼睛棕色", "圆头", "愉快微笑"],
    "personality": "热情学习者",
    "voice_id": "TxGEqnHWrfWFTfGW9XjX"  # Josh
}

步骤2:场景计划

scenes = [
    {
        "number": 0,
        "visual": "Pyter带笔记本电脑,标题'Pyter的第一个错误'",
        "narrative": "[愉快] 今天,Pyter Python将修复他的第一个编码错误!",
        "speaker": "Narrator",
        "voice_id": "JBFqnCBsd6RMkjVDRZzb"
    },
    {
        "number": 1,
        "visual": "Pyter盯着带有红色错误消息的屏幕",
        "narrative": "[困惑] 等等...为什么我的代码不工作?[暂停] 计算机说有一个语法错误!",
        "speaker": "Pyter",
        "voice_id": "TxGEqnHWrfWFTfGW9XjX"
    },
    {
        "number": 2,
        "visual": "Pyter读Python书,沉思",
        "narrative": "[沉思] 让我检查Python书...[暂停] 哦!我需要仔细看第5行。",
        "speaker": "Pyter",
        "voice_id": "TxGEqnHWrfWFTfGW9XjX"
    },
    {
        "number": 3,
        "visual": "Pyter指向屏幕特写,意识到",
        "narrative": "[兴奋] 我找到了!我忘了关闭括号![暂停] 那就是错误!",
        "speaker": "Pyter",
        "voice_id": "TxGEqnHWrfWFTfGW9XjX"
    },
    {
        "number": 4,
        "visual": "屏幕显示'成功!'带绿色对勾",
        "narrative": "[自豪] 我修复了它!我的代码现在完美运行!",
        "speaker": "Pyter",
        "voice_id": "TxGEqnHWrfWFTfGW9XjX"
    },
    {
        "number": 5,
        "visual": "Pyter庆祝,背景有五彩纸屑",
        "narrative": "[温暖] 这就是Pyter学会每个程序员都会犯错误...而且没关系!",
        "speaker": "Narrator",
        "voice_id": "JBFqnCBsd6RMkjVDRZzb"
    }
]

步骤3:生成(使用上述过程)

输出: pyters-first-bug.mp4 带6个场景,总长约90秒

需求

技能:

  • image-generation - 用于创建一致视觉场景
  • elevenlabs - 用于角色声音配音

Python包:

pip install elevenlabs pillow

系统:

  • Python 3.8+
  • ffmpeg(用于视频组装)
  • Bash shell(用于assemble_video.sh脚本)
  • 2GB+ 空闲磁盘空间(用于临时文件)

API密钥:

  • OpenAI或Google(用于图像生成)
  • ElevenLabs(用于声音配音)

文件权限:

  • assemble_video.sh 的执行权限

最佳实践

故事规划

  1. 保持简单:

    • 从6个场景开始(1标题+5故事)
    • 清晰开头、中间、结尾
    • 第一个故事使用单个主要角色
  2. 角色一致性:

    • 在开始前完全定义角色
    • 使用独特视觉特征
    • 在整个过程中保持服装/颜色
  3. 节奏:

    • 每个场景15-20秒理想
    • 使用暂停以增强戏剧效果
    • 变化情感标签以增加表达性

视觉一致性

  1. 使用风格锁定:

    • 对每个场景应用,无例外
    • 不要在故事中途修改
    • 自定义锁定应完整,非部分
  2. 角色锁定:

    • 用十六进制代码指定颜色
    • 列出3-5个独特特征
    • 包括服装细节
  3. 多轮引用:

    • 总是引用先前场景
    • 提及“保持角色外观”
    • 注明“相同照明和风格”

音频质量

  1. 叙事指南:

    • 自然写作为演讲
    • 适度使用情感标签(每个场景1-2个)
    • 为节奏包含暂停
  2. 声音选择:

    • 匹配声音到角色年龄/性格
    • 保持叙述者声音中性
    • 保持每个角色的声音一致性
  3. 音频测试:

    • 首先生成一个场景测试
    • 验证声音/情感匹配意图
    • 在生成所有场景前调整

视频组装

  1. 文件组织:

    • 使用一致命名(scene-XX.png/mp3)
    • 保持平坦目录结构
    • 组装后清理临时文件
  2. 质量设置:

    • 默认1080×1080确保质量
    • H.264基线配置文件以兼容
    • AAC音频在192kbps
  3. 测试:

    • 验证所有图像大小相同
    • 检查音频文件有效
    • 先用2-3个场景测试脚本

故障排除

视觉不一致

问题: 角色在场景间看起来不同

解决方案:

  • 确保角色锁定应用于每个提示
  • 验证先前图像被引用
  • 添加“从先前场景保持确切角色外观”
  • 使用更具体的颜色十六进制代码

音频问题

问题: 声音不匹配角色

解决方案:

  • 验证voice_id正确
  • 先用示例文本测试声音
  • 检查角色声音分配逻辑

问题: 连接音频有间隙

解决方案:

  • 确保所有音频文件是有效的MP3
  • 检查ffmpeg连接过滤器语法
  • 验证无缺失场景音频文件

视频组装错误

问题: 脚本失败,提示“文件未找到”

解决方案:

  • 验证所有图像文件存在
  • 检查音频文件路径
  • 确保脚本有执行权限

问题: 视频中图像大小不同

解决方案:

  • 验证所有图像是1080×1080
  • 检查图像生成设置
  • 脚本自动填充,但更喜欢精确大小

限制

  1. 场景数量:

    • 实际限制:10-12个场景(视频长度约3分钟)
    • 更多场景 = 更长生成时间
    • 音频/视频文件大小考虑
  2. 角色复杂度:

    • 推荐1-3个主要角色
    • 太多角色 = 更难一致性
    • 背景角色如果非详细可接受
  3. 视觉变化:

    • 不能在故事中途改变风格
    • 角色服装变化需要新角色锁定
    • 主要场景变化(白天/夜晚)可能降低一致性
  4. 音频长度:

    • 每个场景15-20秒理想
    • 非常短的场景(<10秒)感觉匆忙
    • 非常长的场景(>30秒)节奏慢
  5. 处理时间:

    • 图像生成:每个场景30-60秒
    • 音频生成:每个场景10-20秒
    • 视频组装:总共30-60秒
    • 总计:约10-15分钟用于6场景故事

相关技能

  • image-generation - 视觉生成必需
  • elevenlabs - 声音配音必需
  • python-plotting - 用于可视化故事分析
  • scientific-writing - 用于编写叙事脚本

附加资源

  • 图像生成技能: 参见 image-generation/SKILL.md
  • ElevenLabs技能: 参见 elevenlabs/SKILL.md
  • 风格锁定参考: 参见 references/style-locks.md
  • 叙事设计: 参见 references/narrative-design.md
  • 视频组装: 参见 references/video-assembly.md
  • 示例故事: 参见 examples/example-stories.md