产品宣传大片 + 痛点引流钩子视频(含视频号自动发布)
一条流水线产出两种可直接发布的 1080×1920 竖版视频,做完还能一键发到微信视频号:
| 宣传片(promo) | 钩子视频(hook) | |
|---|---|---|
| 定位 | 品牌形象 / 开业盛典 / 朋友圈置顶 | 投流拉新 / 社群群发 / 引流到店 |
| 风格 | 黑金奢侈品大屏、宋体大字、慢推镜 | 黑白红撞色痛点大字、砸屏动画、快切 |
| 时长 | 57s(配乐 58s) | 44.1s(配乐 44.6s) |
| 结构 | 意境→品牌→实拍→工艺→钜惠→落版 | 3秒痛点→共鸣→反常识转折→方案→免费钩子→紧迫CTA |
| 配乐 | 极简钢琴+弦乐pad+低频脉搏 | 心跳+whoosh快切+riser+重锤+暖调释放 |
素材盘点 → config.json → make_assets.py(字卡/底板/字幕)
→ make_music.py(原创配乐,与转场对齐)
→ build_video.py(逐段渲染+xfade串联+混音)
→ qc_frames.py(抽帧质检) → 成片 + 封面
→ publish.js(可选:发布到微信视频号)
环境准备
# 视频制作
pip install pillow numpy imageio-ffmpeg # ffmpeg 用 imageio 自带(含 libx264)
# 视频号发布(可选,仅当需要自动发布时)
# 需要本机已安装 Microsoft Edge + Node.js ≥ 18
mkdir -p ./node_workspace && cd ./node_workspace && npm install playwright-core && cd ..
export NODE_PATH="$PWD/node_workspace/node_modules"
- 必须用
imageio_ffmpeg.get_ffmpeg_exe()的 ffmpeg:系统 ffmpeg 常缺 libx264(报Unknown encoder 'libx264') - 中文字体:本机已有中文字体即可;脚本按候选列表自动探测(Windows 黑体/微软雅黑、Linux Noto CJK),也可改
lib_render.py顶部候选路径
使用步骤
Step 1 素材盘点(向用户收集)
| 槽位 | 用途 | 要求 |
|---|---|---|
| storefront | 门店/门头实拍 | 竖版优先,3-5s 可用片段 |
| service | 核心服务过程 | 竖版,6s+ 连续镜头 |
| closeup | 手法/部位/产品特写 | 3s+ |
| process | 工艺/流程图 | 静图,会被裁特写(横竖皆可) |
| facility | 环境/设备图 | 静图,横图自动 blur 填充 |
没有实拍素材也能出片:把 timeline.py 里对应镜头的类型从 "video" 改成 "img",
用静图(照片/AI 生成图/PIL 绘制)走 Ken Burns 运镜,风格反而更统一。此时 materials
各槽位给 {"path": "素材/xxx.jpg", "mode": "cover"} 即可。
Step 2 填写 config.json
复制 scripts/config.example.json 改三处:品牌信息(brand/address/seal_text)、materials 各槽位 path 与 trim(实拍起始秒)、两种风格的文案(promo/hook 节点)。
Step 3 生成素材与配乐
cd scripts
python make_assets.py --config config.json --workdir ../build
python make_music.py --style cinematic --out ../build/music_promo.wav
python make_music.py --style hook --out ../build/music_hook.wav
Step 4 装配成片
python build_video.py --config config.json --style promo --workdir ../build --out 成片-宣传片.mp4
python build_video.py --config config.json --style hook --workdir ../build --out 成片-钩子.mp4
Step 5 质检(必做)
python qc_frames.py --video 成片-宣传片.mp4 --out qc_promo.jpg
python qc_frames.py --video 成片-钩子.mp4 --out qc_hook.jpg
检查点:①每个镜头字幕完整不截断 ②痛点卡红字位置正确 ③实拍片段无穿帮帧(如镜头摇走)④时长=预期(57.0/44.1s)且 audio=yes ⑤片尾落版淡出正常。
Step 6 交付
- 成片 MP4(H.264+AAC 1080×1920)
- 封面图:可直接从 A2(品牌揭示卡)或 CTA 卡导出 JPG
- 投放建议:钩子视频引流到店 → 宣传片加深信任;发布文案带地址+开业限时词
Step 7(可选)发布到微信视频号
成片做好了,直接一条命令发到视频号:
# 首次需要微信扫码登录一次(登录态存在本机,脚本自动复用)
node scripts/publish.js --login
# 建议先演练:填完表单但不点发表,60 秒后自动关窗
node scripts/publish.js --config publish_config.json --dry-run
# 确认无误后正式发布
node scripts/publish.js --config publish_config.json
发布配置(assets/publish_config_template.json):
{
"video": "成片-宣传片.mp4",
"title": "开业钜惠", // 短标题 ≤16 字
"desc": "描述正文,含看点与落点地址", // ≤1000 字,⚠️ 不要手写 #话题
"tags": ["水果", "生鲜", "开业钜惠"], // 话题,脚本自动输入
"cover": "封面-宣传片.jpg",
"draft": false
}
发布能力说明:复用本机 Edge 的持久化登录态,走视频号助手网页后台,不需要 API 密钥。
发布器已攻克视频号发布页的硬骨头——真实表单藏在 iframe 里、且 Playwright 选择器引擎在该 frame 上失效
(详见下节「视频号发布的坑」)。
安全边界(--import 登录态导入):node scripts/publish.js --import <平台> 从本机 Edge 只复制
登录态必需的两个文件——Local State(Cookie 解密密钥)与 Default/Network/Cookies(会话),
存入技能自管的 profile 目录。不复制、不落盘 Login Data(浏览器密码库)、Web Data(自动填充)
等任何凭证文件。密码与表单数据始终只留在 Edge 原始配置目录中。
文案公式(改动文案时保持结构)
钩子六段式:[具体症状?]×3 → [十个人里九个中招] → [为什么X都不管用?] → [你缺的不是X,是Y!] → [服务实拍+免费体验] → [价格锚点+手慢无+地址]
- 痛点必须"身体可感"(硬/凉/酸/痛),每条≤9字,红字砸在关键词上
- 转折句是全片记忆点,必须否定一个常识做法
- 免费钩子放价格锚点前面:先"免费体验"后"198元20次"
- ⚠️ 痛点卡一行文字(110pt)超过约 10 字就会撑出 1080 画布宽,需拆行或缩字号
宣传片七幕式:意境开场(两行诗意) → 品牌大字+印章 → 门店实拍 → 品类大字 → 服务实拍 → 工艺/节气 → 钜惠三连卡 → 落版地址
关键实现约定(改代码前必读)
- 带字距文字宽度:必须逐字
font.getlength()累加;textbbox不含字距会右侧截断 - xfade 变长转场:每段先渲染成独立 mp4(len=disp+d_out),offset_k=Σdisp(0..k-1);混在同一 filtergraph 时每个输入先
settb=AVTB,fps=30,format=yuv420p - 配乐时长 ≥ 成片时长:混音
-shortest会用最短流截断,配乐短了画面就被砍 - zoompan 防抖:先 3 倍放大(scale=3240:5760)再 zoompan 输出 1080x1920
- 卡片运镜:钩子痛点卡用 punch(前8帧 1.14→1.0 砸屏),品牌卡用 push(慢推 3.5%)
- 实拍必须叠底部渐变遮罩(scrim)再上字幕,否则白字看不清
- 海报类图片别整图当镜头:信息太密显廉价,用 crop 裁特写区域或直接改大字卡
- 音效点(whoosh/重锤/心跳停止点)全部取自 timeline 偏移,改 timeline 后要同步调 make_music
- 正片实际时长 = 表内 disp 累加(转场重叠),与末段尾量相加后再被配乐按
-shortest截到配乐长度;
例如表内累加 63.2s / 配乐 58s → 成片 57.0s,属正常(qc_frames.py会报实际值)
视频号发布的坑(publish-video-auto 核心资产)
0. 【最关键】真实表单藏在 iframe 里,且 Playwright 选择器引擎在该 frame 上失效
- 主页面 /platform/post/create 是空壳,真实表单在子框架 channels.weixin.qq.com/micro/content/post/create 里
- 更麻烦的是:在该 frame 上 frame.$() 恒返回 null(原生 document.querySelectorAll 能查到,Playwright 引擎查不到,疑似 CSP/隔离导致)。必须改用 evaluateHandle(() => document.querySelector(sel)) 取 ElementHandle
- frame 本身不会被重建,但 handle 会因 React 重渲染频繁 detached → 关键操作(上传)要重试 5 次 + page.waitForEvent('filechooser') 兜底;兜底路径实测必成
1. 描述框既不是 <textarea> 也不是 contenteditable="true"
- 真实结构是 div.content-editor[contenteditable=""](属性值为空字符串)+ class="input-editor"
- 选择器要用 div.input-editor[contenteditable](不带值才匹配得到)
- 页面上那个 <textarea> 是「商品链接」框,别用错
2. 视频转码期间表单根本不渲染:上传完成后最长要等 120 秒描述框才出现
3. file input 是隐藏的:必须用 state:"attached" 等待,不能用默认的 visible
4. 短标题选择器必须收窄:input[placeholder*='标题'] 会命中隐藏的「请输入视频原声标题」,
只有 input[placeholder*='短标题'] 才对(曾因此报 30 秒超时)
5. 上传完成的判定文案不固定:以「更换封面 / 重新上传 / 添加描述 / 短标题」等表单出现标志判断
6. 发表成功有两个判定条件:出现「发表成功」文案 或 URL 跳离 /post/create|video|edit
7. 短标题符号限制:竖线 |、| 会触发页面红字警告;改用冒号 : 最稳
8. 描述里不要手写 #话题:脚本会按 tags 自动输入并回车确认,两边都写会导致话题重复两遍(实测踩到)
9. 登录态是几平台里最短的:视频号只能微信扫码,登录态几天失效;失效时脚本停下等扫码(最多 10 分钟)后自动继续。
建议:定时/批量发布前先跑一次 node scripts/publish.js --probe 确认登录态;内容建议走「先 --dry-run 演练 → 再正式发」。
页面改版自救:只改 scripts/platforms.json(选择器/等待/成功标志),不要改 publish.js;
用 node scripts/publish.js --probe --video <mp4> 走完上传流程导出真实表单元素核对。
常见问题
| 症状 | 原因 | 解法 |
|---|---|---|
Unknown encoder 'libx264' |
系统 ffmpeg 无 x264 | 用 imageio_ffmpeg 的 ffmpeg(脚本已内置) |
Option 'ms' not found for colorbalance |
参数名笔误 | 中点用 rm(红移动到中间调),不是 ms |
| 成片比预期短 | 配乐短于画面被 -shortest 截断 | make_music 时长取自 timeline,勿手改 wav |
| 字幕右侧缺字 | 用了 textbbox 量宽 | 统一用 lib_render.measure_spaced |
| 中文字体变方块/日文写法 | 字体未命中简体变体 | lib_render 字体候选按平台探测,必要时改顶部路径 |
| xfade 报 More input link labels | 转场链写法错误 | 每个输入先单独预处理成 [pK],再两两 xfade |
| 视频号上传报 detached element | React 重渲染使 handle 失效 | 已内置重试 5 次 + filechooser 兜底,无需干预 |
| 视频号话题出现两遍 | desc 手写了 #话题 |
desc 不写话题,只留 tags 数组 |
个性化扩展
- 换配色:
lib_render.py的GOLD_STOPS(金色渐变)、WHITE/RED/GOLD(钩子撞色) - 横版 16:9:W/H 改 1920×1080,卡片排版 y 值按比例缩放,字幕 overlay y 改 1140→620
- 加 LOGO:将 PNG 叠加到 A2/CTA 卡(PIL alpha_composite)或全片角落 overlay
- 加二维码:落版卡 A5/CTA 下方留白区贴码,建议 280px 见方
- 加平台:发布侧
platforms.json已设计为「一个平台一份配置」,新增平台只需补一份选择器配置
License
MIT