本文记录了使用 WorkBuddy(CodeBuddy 桌面版)从零制作一部5集仙侠题材短剧的完整过程。涵盖 AI 场景绘图、视频生成、edge-tts 中文配音、字幕叠加、ffmpeg 后期合成等环节,包含可复用的 Python 框架代码和踩坑经验。
WorkBuddy 是腾讯 CodeBuddy 的桌面端 AI 助手,内置 ImageGen(文生图/图生图)、VideoGen(文生视频/图生视频)等多模态生成能力,同时可以执行本地 Python 脚本、操作文件系统,适合做多媒体创作工作流。
集数 | 标题 | 时长 | 内容 |
|---|---|---|---|
EP1 | 紫霄仙宫·帝后抛糯米 | 23.5s | 帝后将女婴糯米抛下凡间 |
EP2 | 山道妖兽追击 | 10.5s | 糯米落地,蜈蚣蝎子火狼追击 |
EP3 | 青云宗弟子救援 | 42.1s | 剑修费粮救下糯米,带她回宗门 |
EP4 | 仙帝训斥四大神兽 | 47.6s | 仙帝震怒,命四神兽下界寻找小主 |
EP5 | 帝后心机+神兽下界 | 75.3s | 帝后暗中布局,四神兽化身凡人寻人 |
· 总时长:约3分19秒
· 总配音:45条对白,12个角色,195.6秒
· 分辨率:1280×720
· 格式:MP4(H.264 + AAC)
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
剧本 → 场景图(ImageGen) → 视频片段(VideoGen) → 配音(edge-tts) → 字幕(PIL) → 合成(ffmpeg)
整体分为5个阶段,下面逐步说明。
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
使用 WorkBuddy 内置的 ImageGen 工具,为每集生成关键场景图。
仙侠题材的提示词需要包含:场景描述 + 光影氛围 + 镜头语言 + 画风风格。例如 EP1 的帝后抱婴儿场景:
Cinematic interior shot of a celestial palace chamber, a beautiful empress in flowing silver-white silk robes holding a tiny baby wrapped in glowing golden cloth, warm golden light from jade lanterns, intricate cloud motifs carved on jade pillars, ethereal atmosphere, shot on ARRI Alexa, shallow depth of field, 8K detail
· input_fidelity=high:当需要保持参考图面部特征时使用
· watermark=false:生成图片不需要水印
每集2-3张关键帧,覆盖剧情转折点。这些图后续作为 VideoGen 的输入帧。
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
将静态场景图交给 VideoGen,生成5-12秒的动态视频片段。
在 WorkBuddy 对话中直接描述需求,工具会自动将场景图转为视频:
· 每段最长12秒
· 分辨率720P
· watermark=false:去除水印
VideoGen 每段最多12秒,但有些集数的对白总时长远超视频素材时长(EP5对白75秒,视频素材仅36秒)。解决方案是 ffmpeg 的 setpts 滤镜慢放视频:
# 慢放系数 = 视频时长 / 目标时长 speed_factor = video_duration / target_duration # setpts=PTS/speed_factor 会将视频放慢
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
WorkBuddy 没有内置 TTS,但可以执行本地 Python 脚本。edge-tts 是微软 Edge 浏览器的 TTS 引擎,免费、中文质量高、支持多角色声音。
pip install edge-tts
为12个角色分配了不同的中文声音,让每个角色有辨识度:
角色 | 声音 | 特点 |
|---|---|---|
帝后 | zh-CN-XiaoyiNeural | 温柔女性 |
糯米 | zh-CN-XiaomoNeural | 清脆少女 |
仙帝/旁白 | zh-CN-YunxiNeural | 沉稳男性 |
费粮 | zh-CN-YunyangNeural | 活泼少年 |
丘明 | zh-CN-YunxiNeural | 冷峻剑修 |
青龙 | zh-CN-YunyangNeural | 威严 |
白虎 | zh-CN-YunxiNeural | 刚毅 |
朱雀 | zh-CN-XiaoyiNeural | 柔美 |
玄武 | zh-CN-YunjianNeural | 浑厚 |
import edge_tts import json VOICES = { "帝后": "zh-CN-XiaoyiNeural", "糯米": "zh-CN-XiaomoNeural", "仙帝": "zh-CN-YunxiNeural", "旁白": "zh-CN-YunxiNeural", "费粮": "zh-CN-YunyangNeural", # ... } async def generate_tts(text, character, output_path): voice = VOICES.get(character, "zh-CN-YunxiNeural") communicate = edge_tts.Communicate(text, voice) await communicate.save(output_path)
生成45条配音后,用一个 manifest.json 记录每条配音的集数、角色、文本和时长,后续合成时按此时间轴排列:
{ "episode": 3, "line_id": "01", "character": "费粮", "text": "师弟们,前方有妖气波动", "duration": 3.12, "file": "audio/ep3/01_费粮.mp3" }
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
用 PIL(Pillow)生成带半透明背景的中文字幕图层。
macOS 上的 PingFang.ttc 路径在 PIL 中加载失败,改用黑体:
FONT_PATH = "/System/Library/Fonts/STHeiti Medium.ttc"
from PIL import Image, ImageDraw, ImageFont def create_subtitle_png(text, width=1280, height=720, font_size=42, output_path="subtitle.png"): img = Image.new("RGBA", (width, height), (0, 0, 0, 0)) draw = ImageDraw.Draw(img) font = ImageFont.truetype(FONT_PATH, font_size) # 计算文字位置(底部居中) bbox = draw.textbbox((0, 0), text, font=font) tw, th = bbox[2] - bbox[0], bbox[3] - bbox[1] x = (width - tw) // 2 y = height - th - 80 # 半透明背景条 draw.rectangle([x-20, y-10, x+tw+20, y+th+10], fill=(0, 0, 0, 160)) # 暗金色文字 draw.text((x, y), text, font=font, fill=(255, 220, 100, 255)) img.save(output_path)
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
这是最复杂的一步,需要将视频、音频、字幕三层合成为一个完整的视频。
· 视频拼接:多段视频拼接成一条
· 视频变速:用 setpts 滤镜慢放视频匹配配音时长
· 音频拼接:多条配音按时间轴拼接,中间插入静音
· 字幕叠加:多条字幕按时间段叠加到视频上
WorkBuddy 的 Python 环境自带 imageio-ffmpeg,无需单独安装:
FFMPEG = "/Users/.../imageio_ffmpeg/binaries/ffmpeg-macos-aarch64-v7.1"
def concat_audio(audio_files, output_path, gaps): """ audio_files: 配音文件列表 gaps: 每条配音前的静音时长 """ # 生成静音文件 # 用 concat filter 拼接: [0:a][1:a][2:a]concat=n=3:v=0:a=1[aout] inputs = [] for af, gap in zip(audio_files, gaps): if gap > 0.01: silence = generate_silence(gap) inputs.extend([silence, af]) else: inputs.append(af) # 构建 filter_complex filter_parts = [] for i in range(len(inputs)): filter_parts.append(f"[{i}:a]") filter_parts.append(f"concat=n={len(inputs)}:v=0:a=1[aout]") cmd = [FFMPEG, "-y"] for inp in inputs: cmd.extend(["-i", inp]) cmd.extend(["-filter_complex", "".join(filter_parts), "-map", "[aout]", output_path])
# 每条字幕作为一个 overlay 输入,用 enable='between(t,start,end)' 控制显示时段 filter_parts = [] for i, (sub_file, start, end) in enumerate(subtitles): filter_parts.append( f"[{base_idx}:v][{base_idx+1+i}:v]overlay=enable='between(t,{start},{end})'[v{i}]" )
# 将视频慢放至目标时长 speed = original_duration / target_duration vf = f"setpts={speed}*PTS,scale=1280:720"
def compose_episode(episode_num, video_segments, audio_timeline, subtitles, output_name): # 1. 生成字幕PNG # 2. 拼接音频(含静音) # 3. 拼接视频片段(含变速) # 4. ffmpeg filter_complex 合成三层 # 5. 输出最终 MP4
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
问题:PIL 加载 /System/Library/Fonts/PingFang.ttc 报错。
解决:改用 /System/Library/Fonts/STHeiti Medium.ttc。
问题:concat demuxer 的文件列表中包含中文路径时失败。
解决:改用 concat filter([0:a][1:a]concat=n=N:v=0:a=1),不依赖文件列表。
问题:gap 为 0.02s 时走了 amix 路径,导致音频截断。
解决:将判断条件从 g == 0 改为 g < 0.01。
问题:多次 draw.text 叠加后,文字中心 alpha 超过255,显示异常。
解决:改用直接 RGB 值 (105, 80, 12) 暗金色,不依赖 alpha 叠加。
问题:EP3/EP5 的对白时长(42s/75s)远超视频素材时长(17s/36s)。
解决:用 setpts 滤镜慢放视频(0.69x / 0.645x),让画面匹配配音时长。
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
project/ ├── drama_framework.py # 核心框架(字幕、音频、合成) ├── generate_all_tts.py # TTS配音生成 ├── compose_ep1.py ~ ep5.py # 各集合成脚本 ├── create_subs_ep1.py # 字幕生成 ├── audio/ │ ├── manifest.json # 配音时间轴清单 │ ├── ep1/ ~ ep5/ # 各集配音MP3 ├── subs/ # 字幕PNG图层 ├── *.png # 场景图(ImageGen生成) ├── *.mp4 # 视频片段(VideoGen生成) ├── ep1_final.mp4 ~ ep5_final.mp4 # 成品
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
操作 | 单次消耗 | 本次用量 |
|---|---|---|
ImageGen 文生图 | 5-10积分 | 约15张 |
VideoGen 图生视频 | 50-100积分 | 约12段 |
对话/代码执行 | 较少 | 全程 |
省钱建议:
· 视频片段可改用免费外部工具(Seedance、即梦AI)生成,下载后用 WorkBuddy 做后期合成
· edge-tts 和 ffmpeg 部分完全不消耗积分
· 把高消耗操作安排在每月1号之后(免费额度刷新)
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
WorkBuddy 的优势在于将多模态生成(ImageGen/VideoGen)与本地代码执行(Python/ffmpeg)结合在一个工作流中。虽然单工具能力有限制(视频最长12秒、720P),但通过编写框架代码自动化整个流程,可以实现从剧本到成品视频的完整制作链路。
后续优化方向:
· 用 Seedance/Kling 替代 VideoGen,获得更长、更高清的视频片段
· 用情感TTS替代 edge-tts,提升配音表现力
· 加入转场特效(淡入淡出、交叉溶解)
· 支持背景音乐混音
如果你也在用 WorkBuddy 做创作,欢迎交流!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。