# 程序员爸爸的B站自制视频全流程:Playwright 实机录屏 + edge-tts 配音 + ffmpeg 一键合成
2026/9/20 16:50:40 网站建设 项目流程

程序员爸爸的B站自制视频全流程:Playwright 实机录屏 + edge-tts 配音 + ffmpeg 一键合成

📺我的B站主页:只是甲
🎬本文配套视频(最近3期)

  • 《100亿 Token 烧出来的血泪经验:两个月重度使用大模型后的实战总结》
  • 《程序员爸爸给6岁儿子写了个学习游戏:边打怪边学语文数学英语》
  • 《我一行代码没写,用 ZCode 给 6 岁儿子"聊"出了一个学习游戏》

后两期视频的完整工程代码和成片,都是按本文这条流水线做出来的。欢迎去B站一键三连支持一下!

前言

很多想做 B 站技术 / 产品介绍视频的朋友,卡在同一个地方:不会剪辑、不想出镜、配音还要求播音的朋友

我的做法是:把整个视频生产做成一条纯代码流水线——

脚本(JSON) ──> 自动化实机录屏 ──┐ ├─> edge-tts 旁白 ──┼──> ffmpeg 合成 ──> 成片.mp4 + 字幕.srt + 封面.jpg ├─> numpy 合成BGM ──┤ └─> HTML卡片截图 ───┘

全程零手动剪辑,改一行文案重跑脚本就出新片。我已经用这条流水线产出了两支播放视频(工程分别 4:54 和 4:40),本文把完整方法、代码骨架和踩过的坑全部写出来。

一、整体架构:5 个脚本各管一段

工程目录结构(以游戏介绍视频为例):

video-project/ ├── narration.json # 旁白文案(唯一需要人写的东西) ├── bot.js # ① Playwright 驱动 Edge 实机录屏 ├── tts.py # ② edge-tts 生成旁白 mp3 + 词级时间戳 ├── bgm.py # ③ numpy 合成无版权 BGM ├── cards.html/js # ④ 片头/章节卡:HTML 渲染 + Edge 截图 ├── compose.py # ⑤ ffmpeg 合成:画面拼接 + 混音 + 字幕 └── out/ # 成片.mp4 / 字幕.srt / 封面.jpg / 上传说明.md

核心思想:旁白文案是唯一的"源代码"narration.json里每句旁白绑定一个画面段(segment),下游所有素材(配音时长、字幕时间轴、画面切换点)全部由它自动推导。

{"voice":"zh-CN-YunxiNeural","rate":"+6%","lines":[{"id":"L0","segment":"intro","text":"孩子爱玩游戏,却静不下心学习?我这位程序员爸爸,给出了自己的答案。"},{"id":"L5","segment":"B","text":"第一关是打怪兽:狂点怪兽攒能量,这个纯靠手速,小朋友最喜欢。"}]}

二、实机录屏:Playwright 驱动本机 Edge,不要下载 Chromium

介绍软件 / 游戏类产品,最有说服力的画面是真实操作录屏。我用playwright-core直接驱动本机已装的 Edge(免下载浏览器):

const{chromium}=require('playwright-core');constEDGE='C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe';constbrowser=awaitchromium.launch({executablePath:EDGE,headless:true,recordVideo:{dir:'takes/',size:{width:1280,height:720}},});

要点:

  • 持久化 profile:用launchPersistentContext('./profile'),多个 take 之间能续上游戏进度,避免每段都从新手引导重录。
  • 分段录制:每个演示场景一个 take(建角 / 核心玩法 / 商店 / 设置),合成时再按需裁剪拼接。
  • headless 关语音:录屏时把页面内 TTS 关掉(视频用外部旁白),否则无语音引擎环境下每句要等 15s 超时兜底。

录屏自动化踩坑清单(全是真金白银的时间)

  1. 顶层const不在window:游戏管理器若用顶层const GameManager = {...}声明,page.evaluate里必须用裸标识符GameManager.addGold(300)访问,window.GameManager是 undefined。
  2. 弹窗延迟出现拦截点击:签到宝箱、通用弹窗会在页面加载后延迟弹出并拦截全屏点击。写了个clearOverlays()轮询:最多等min(2500, waitMs),出现弹窗就处理到底再走。
  3. 无限动画元素永远点不动:带无限浮动动画的按钮(宝箱),Playwright 的 actionability 稳定性检查永远不通过 → 直接page.evaluate里 DOM click。
  4. data-action有隐藏兄弟元素:按文本点击会命中隐藏的复制品 → 用getByRole按可访问名定位。
  5. 子界面没有底部导航:录"设置"前要先点返回按钮回主界面,否则视角不对。

三、旁白:edge-tts 免费拿到"电台级"中文配音

edge-tts调用微软 Edge 在线 TTS,完全免费,中文科普 / 新闻风推荐zh-CN-YunxiNeural(云希),语速+6%刚好。

它最值钱的功能是WordBoundary 词级时间戳——这是免费字幕时间轴的关键:

comm=edge_tts.Communicate(text,voice,rate=rate,boundary='WordBoundary')asyncforchunkincomm.stream():ifchunk['type']=='audio':f.write(chunk['data'])elifchunk['type']=='WordBoundary':# offset 单位是 100ns,除以 10000 换成毫秒bounds.append({'text':chunk['text'],'offset_ms':chunk['offset']/10000,'dur_ms':chunk['duration']/10000})

两个必须处理的点:

  • 间歇性超时speech.platform.bing.com的 WebSocket 经常抽风,必须带重试(我设 4 次、指数退避),并且校验输出文件大小(<2KB 视为失败)。
  • 每句旁白单独出一个 mp3 + 词边界列表,落成timeline.json(每句起止时长)和subs_raw.json(词级对齐),后面字幕和混音全靠它。

四、BGM:用 numpy 合成,彻底绕开版权

B 站对 BGM 版权越来越严,音乐库翻来翻去不如自己写一个。BGM 本质就是周期信号叠加——纯 numpy 200 行合成 128 BPM C 大调马林巴配乐:

# 马林巴 = 基频正弦 + 4倍频泛音 + 指数衰减包络defpluck(freq,dur,decay=0.18,harmonics=((1.0,1.0),(4.0,0.22)),vol=1.0):...# 和弦进行 C - G - Am - F,每小节一换# kick 底鼓 = 频率指数下滑的正弦,hat = 高通白噪声

再叠加:三次均值卷积柔化音色、右声道 18ms 延迟做假立体声、首尾淡入淡出。生成的bgm.wav版权归自己,随便商用。

五、片头 / 章节卡:HTML 渲染 + 浏览器截图

为什么不用 PIL / Pillow 画标题卡?因为PIL 画不了彩色 emoji,排版也丑。直接写一个cards.html(分号排版 + 大字 + emoji),用 Edge headless 截图成 PNG——浏览器渲染天然支持彩色 emoji、Web 字体、CSS 动画。

六、合成:compose.py 一个脚本出成片

compose.pyimageio-ffmpeg自带的静态 ffmpeg,完成四件事:

  1. 时间线计算:卡片时长由该段旁白时长决定,实机片段按实际时长裁头(webm 开头有 ~0.3s 黑屏,必须裁)。
  2. 画面:统一转码 1280x720@30 yuv420p,卡片加 zoompan 缓推 + 淡入淡出,然后 concat。
  3. 音频:BGM 压到 0.16 音量垫底,每句旁白按时间线偏移adelay定位,amix normalize=0混音 +alimiter限幅,最后loudnorm归一到-14 LUFS(B 站标准响度,传上去不会被二次压低)。
  4. 字幕 + 封面:SRT 由词边界直接生成(比 Whisper 事后识别对齐得准),封面图一并输出。

进阶:合成前先跑plan预检

第二支视频(vibe coding 主题)加了个plan模式:合成前逐段校验"旁白放不放在得下画面窗口",输出类似:

L3: 旁白结束@26.1s << 窗口21.0s 溢出!

旁白比画面长是这类流水线唯一的结构性失败模式。解法优先级:加大画面窗口 > 放慢演示动画重录 > 删文案。第一版 V1 段 21s 画面装不下 26s 旁白,就是把演示动画打字速度调慢 + 尾部多 sleep 2 秒撑到 28s 解决的。

七、验收:模型看不了图怎么办

成片做 visual QA 时,如果当前 AI 模型不支持图片输入,用OCR 抽帧校验:每 30~50 秒抽一帧,对帧做 OCR(本地 RapidOCR / PaddleOCR),核对每帧文字与脚本段落对得上。9 帧全过 ≈ 整片无串段。

八、上传 B 站:这些细节决定推荐量

工程最后会生成一份B站上传说明.md,把发布要素一次配齐:

要素建议
标题悬念 + 结果式:“我一行代码没写,给6岁儿子’聊’出了一个学习游戏”
简介前 3 行放钩子,随后 bullet 列卖点,附时间轴(B 站会识别章节)
标签8-10 个,大词 + 长尾词混搭(#AIGC #vibecoding #程序员 #亲子)
分区科技 → 软件应用(AI 工具类在科技区流量更好)
字幕直接上传工程生成的.srt,B 站支持外挂字幕
响度已 loudnorm -14 LUFS,B 站不会二次压音量
发布时间工作日 18:00-21:00 或周末上午(受众活跃时段)
发布后1 小时内回复前排评论,利于推荐

两条合规提醒:

  1. AI 生成内容要如实标注。我的 coding 演示视频界面是"脚本化还原演示"(非原始录屏),这条声明直接写进了视频简介——诚实声明不减分,被观众扒出来"造假"才致命。
  2. 用了 AI 配音 / AI 画面的稿件,投稿页勾选"内容由 AI 生成"。

九、复用这套流水线

整套东西抽象出来就是:输入一份narration.json,输出一支成片。换主题只需要换三样:

  1. 旁白文案(唯一要人写的)
  2. bot.js里的演示操作脚本(录什么画面)
  3. cards.html的卡片文案

配音、BGM、字幕、混音、响度全部不用动。第一支视频工程改造到第二支视频,只用了半天。

同类可参考的开源项目:MoneyPrinterTurbo(全自动文案→成片)、Manim(数学动画)。但我这条"自动化实机录屏 + TTS 词边界字幕 + 自合成 BGM"的路线,特别适合软件 / 游戏 / 工具类产品介绍——画面必须是真实操作,通用素材库流水线做不了。


最后

视频成品都在B站,感兴趣去围观、催更、提意见:

  • 📺 B站主页:只是甲
  • 🔥 最新:《100亿 Token 烧出来的血泪经验》
  • 🎮 游戏介绍:《程序员爸爸给6岁儿子写了个学习游戏》
  • 🤖 vibe coding 复盘:《我一行代码没写,用 ZCode "聊"出学习游戏》

觉得这条流水线有用,B站一键三连 + CSDN 点赞收藏,就是我更新的动力。有问题评论区见!

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询