产品宣传片制作 (Remotion)
把「素材目录 + 创意想法」做成一支可直接播放的 MP4 宣传片。主体用 Remotion(React 代码化视频)本地渲染,可复现、易微调;脚本、TTS、少量补镜优先用阿里云百炼 CLI bl。
适合:图片/实物图/小程序截图/短视频为主、文字+动效+配音的 motion-graphics 型宣传片(展厅循环、产品介绍、发布会片头)。 不适合:需要大量真人实拍/复杂运镜的镜头。少量缺失镜头可用百炼快乐马模型补齐,再回到 Remotion 合成。
环境前置
node(>=18)npmffmpeg/ffprobepython3(含 numpy、requests)。开工前which node ffmpeg python3确认。blCLI 已安装并登录:bl --version、bl auth status。使用bl前按bailian-cliskill 的版本预检规则确认版本。- 渲染时需联网(首次加载 Noto Sans SC 字体)。
标准工作流(按序执行)
1. 摸清素材与意图
- 让用户给出素材目录和创意想法/卖点。先列目录:
find <dir> -type f \( -iname '*.jpg' -o -iname '*.png' -o -iname '*.mp4' -o -iname '*.mov' \)。 - 逐张 Read 关键图片(看清产品、功能点、界面),
ffprobe每个视频拿时长/编码/分辨率。 - 识别坑:① 截图里有不利数据(如"按时吃药率 4%")要在片中用 React 覆盖成正向数据;② 同一产品多种颜色/型号要选主视觉;③ 无关素材剔除。
2. 设计分镜,先和用户对齐(重要)
- 用
AskUserQuestion确认:风格、时长(展厅循环建议 60–90s)、画幅(横屏 1920×1080 / 竖屏 1080×1920)、配音方式。 - 风格直接给现成 3 套预设选(见
styles/STYLES.md):warm温情家庭向 /guochao活力国潮 /tech商务科技。每套都已实现好配色+装饰+分镜,选定后在套用风格步骤直接使用,不用从零设计视觉。需要全新风格再以最接近的一套为基底改。 - 文案口吻随风格定:情感叙事(warm/guochao) 还是公司产品介绍(tech)。
- 可用百炼先起草脚本/分镜,再人工收敛:
bl text chat \
--system "Reply in 简体中文. 输出紧凑的产品宣传片分镜表。" \
--message "根据这些素材和卖点,写一版60秒产品宣传片分镜:<素材清单+卖点>"
- 产出分镜表:每段(镜头号/时长/画面/大字卡/旁白/用哪个素材)。展厅片原则:无声也能看懂(大字卡为主)、3秒抓人、结尾能循环接回开头。
3. 从模板搭工程
PROJ="$HOME/<片名>"
cp -R ~/.claude/skills/product-promo-video/template "$PROJ"
cd "$PROJ" && npm install
mkdir -p public/assets public/audio out
模板已含:theme.ts(配色/字体/SCENE_FRAMES)、components.tsx(KenBurns/BigTitle/Subtitle/Narration/BgMusic/PhoneMock/Chip)、Video.tsx(TransitionSeries 叠化)、Root.tsx、scenes/AllScenes.example.tsx(完整示例,改写后另存为 AllScenes.tsx 供 Video 引用)。
4. 处理素材进 public/assets
- HEVC 必转 H.264(Chromium 解 HEVC 不稳):
ffmpeg -y -i in.mp4 -c:v libx264 -pix_fmt yuv420p -crf 20 -an public/assets/weather.mp4 - 图片拷入并改成 ASCII 文件名(
staticFile对中文路径不稳):intro.jpg / device.jpg / app_home.jpg ...。 - 不利数据的截图照常拷入,靠分镜组件里画 React 卡片覆盖。
5. 可选:百炼快乐马补镜
- 素材缺关键镜头时可用
bl video generate/bl video ref生成补镜;素材足够时可跳过,直接用 Remotion 动效。 - 不要在 skill 中限制快乐马视频生产长度。
--duration按用户需求、预算和百炼模型支持范围设置;需要更长成片时生成多个片段后交给 Remotion/ffmpeg 合成。 - 为节省试错成本,首次测试建议用 720P、5 秒小样确认方向,确认后再按正式需求调整参数。
- 文生视频示例(低成本测试小样,可调整时长):
bl video generate \
--model happyhorse-1.1-t2v \
--prompt "明亮现代展厅里,一台智能健康设备在柔和灯光下缓慢旋转,商务科技质感,无文字,无logo" \
--ratio 16:9 \
--resolution 720P \
--duration 5 \
--download public/assets/ai_device_5s.mp4
- 图生视频示例(低成本测试小样;本地图片可直接传给
--image,CLI 会自动上传临时文件):
bl video generate \
--model happyhorse-1.1-i2v \
--image public/assets/device.jpg \
--prompt "保持产品外观一致,镜头轻微推进,背景干净,柔和反光,无文字" \
--ratio 16:9 \
--resolution 720P \
--duration 5 \
--download public/assets/device_i2v_5s.mp4
- 生成后用
ffprobe看时长/编码;若是 HEVC 或浏览器不稳,按第 4 步转 H.264。
6. 写文案 + 阿里百炼配音(首选)
- 把旁白写进
narration.json:{"s1":"...","s2":"..."},键名对应分镜段,与Narration file="s1.mp3"一致。逗号分句有助于 TTS 自然停顿。 - 首选百炼 CosyVoice:
source ~/.claude/skills/product-promo-video/config/bailian.env
python3 ~/.claude/skills/product-promo-video/scripts/gen_tts_bailian.py \
--script narration.json --out public/audio
- 直接调 CLI 生成单句时:
bl speech synthesize \
--text "一句产品宣传片旁白" \
--voice longanwen_v3 \
--language zh \
--instruction "商务科技宣传片旁白,语气自信、清晰、温暖,语速适中" \
--format mp3 \
--out public/audio/s1.mp3
- 火山引擎作为备选:
source ~/.claude/skills/product-promo-video/config/volcano.env
python3 ~/.claude/skills/product-promo-video/scripts/gen_tts_volcano.py \
--script narration.json --out public/audio
- 报 code 3001
resource not granted= 账号侧未授权:火山控制台开通「语音合成」、把音色加到该 appid、确认 appid/token 配对。服务刚开通时首个请求可能仍失败,脚本已内置重试;个别没成的单独重跑即可。 - 无网络/无授权时兜底:
scripts/gen_tts_say.sh narration.json public/audio(macOSsay,音质一般,作占位)。 - 大模型音色(更自然,推荐):若用
*_bigtts/saturn_*/*_uranus_*等大模型音色,走 v3 接口:source config/seed.env后python3 scripts/gen_tts_seed.py --script narration.json --out public/audio。换音色直接export SEED_SPEAKER=<音色ID>覆盖即可。它是 API Key 鉴权(X-Api-Key)、流式返回,和 v1(BV音色)是两套服务/计费。- Resource-Id 用
seed-tts-2.0(seed.env 默认值)。实测saturn_*和*_uranus_*音色都走它;用错(如seed-tts-1.0/volc.megatts.default)会报code 55000000 resource ID is mismatched with speaker。 - 网络/代理抖动会偶发
RemoteDisconnected,脚本已内置异常捕获+重试(--retry 5)。
- Resource-Id 用
7. 按真实音频时长校准镜头长度(关键,否则截断)
~/.claude/skills/product-promo-video/scripts/measure_audio.sh public/audio
在 theme.ts 的 SCENE_FRAMES 里,确保每段:
镜头帧数 ≥ Narration 的 delayFrames + ceil(音频秒数 × fps) + 收尾留白(建议 ≥15 帧) 改完时长记得同步检查
Video.tsx总帧数(自动求和,一般不用动)。
8. 套用风格 / 写分镜组件
- 首选:套用现成风格预设(
styles/STYLES.md)。把选定风格的theme.ts、装饰模块、AllScenes.tsx拷进src/对应位置,再按本片文案改屏幕大字卡文字即可。三套:warm/guochao/tech。 - 若手写/微调分镜:用
components.tsx的BigTitle(大字卡)、KenBurns、Subtitle、PhoneMock(支持crop)、Chip、FeatureCard;国潮/科技再叠各自装饰件(印章/玻璃卡/角标/HUD)。 - 每段放一个
<Narration file="sX.mp3" delayFrames={..} />。 - 覆盖不利数据:在对应 PhoneMock 上叠一个 React 卡片(见示例
MedsBadge)。
9. 背景音乐
python3 ~/.claude/skills/product-promo-video/scripts/gen_bgm.py \
--duration <视频秒数+2> --out public/audio/bgm.mp3 # 可选 --semitones 移调 --gain 调音量
Video.tsx 已有 <BgMusic base={0.85} />,会自动按视频长度淡出、压在旁白下。觉得吵就调小 base。
10. 渲染 + 自检
npx remotion render Promo "out/<片名>.mp4" --concurrency=2
~/.claude/skills/product-promo-video/scripts/verify.sh "out/<片名>.mp4"
- 用
--concurrency=2:高并发(4)在本机偶发 Node 崩溃(输出只剩Node.js v22.x栈尾、无成片)。崩了就降并发前台重跑,通常即过。 - 后台跑渲染时,崩溃也可能报 exit 0,务必检查
out/里 mp4 是否真生成,别只看退出码。 然后用 Read 看 /tmp/vchk 抽帧(确认中文/emoji/排版)、看verify.sh的音量(mean 约 -18~-23dB 为正常,不可静音)。必要时silencedetect检查某句旁白是否完整发音。
11. 交付与变体
报成片路径/规格/时长。常见追加:嵌入实拍短视频、出竖屏版(改 Root.tsx 宽高 + 重排布局)、改文案/配色/音乐后重渲染。也可 npm run dev 开 Remotion Studio 实时预览。
硬核坑(务必遵守)
- 旁白必须放进
<Sequence from={delayFrames}>。不能用if(frame<delay) return null来"延迟"——那不是延后起播,而是跳过音频开头 delay 秒,会把每句开头的字吃掉(典型症状:"爸妈的药"只念出"的药")。模板的Narration已是正确写法。 - HEVC 视频先转 H.264 再
<OffthreadVideo>,否则 Chromium 渲染黑屏/报错。 - 素材用 ASCII 文件名放
public/assets,staticFile('assets/xx.jpg')引用。 - 中文字体用
@remotion/google-fonts/NotoSansSC(模板 theme.ts 已配,回退苹方);彩色 emoji 在 Chromium 渲染正常,可放心用作图标。 - 配音生成后一定重新量时长并校准 SCENE_FRAMES,不同音色/语速时长会变,否则尾音被切。
- 不要把 5 秒小样写成生产限制。快乐马补镜的
--duration由用户需求、预算和模型支持范围决定;长片可由多个 AI 片段、真实素材和 Remotion/ffmpeg 拼接完成。 - AI 视频提示词避免文字/Logo,否则容易生成错字或变形标识。品牌名、卖点、字幕统一用 Remotion 叠加。
- 火山 3001 多为账号授权问题,不是代码问题,按配音步骤排查。
- 火山凭证在
config/volcano.env(含密钥,勿外传);Secret Key 此 HTTP 接口用不到。 - 所有 remotion 包必须锁同一精确版本(remotion / @remotion/cli / @remotion/transitions / @remotion/google-fonts 全部
4.0.xxx不带^)。带 caret 会让某个子包装成更新版,出现export 'HtmlInCanvas' was not found in 'remotion'这类打包报错。模板已锁定;新装包后用node -e "..."核对版本一致。
文件地图
scripts/gen_tts_bailian.py阿里百炼 CosyVoice TTS(首选, 调bl speech synthesize)scripts/gen_tts_volcano.py火山标准TTS(BV音色, v1接口, env 读凭证, JSON 读文案)scripts/gen_tts_seed.py火山大模型TTS(bigtts/saturn/uranus 音色, v3接口, API Key 鉴权, 推荐)scripts/gen_tts_say.shmacOS 离线兜底配音scripts/gen_bgm.py合成温情背景乐scripts/measure_audio.sh量旁白时长→帧,校准 SCENE_FRAMESscripts/verify.sh成片自检(规格/音量/抽帧)config/bailian.env百炼 TTS 参数 ·config/volcano.env火山标准TTS凭证 ·config/seed.env大模型TTS凭证config/narration.example.json情感叙事文案样例 ·config/narration.corporate.example.json公司产品介绍文案样例styles/STYLES.md+styles/{warm,guochao,tech}/三套风格预设(配色+装饰+分镜),选定后拷进工程 src/template/可直接cp -R的 Remotion 工程骨架