精酿 BrewReel:让 DeepSeek 这类便宜模型也能做出好看的竖版宣传片。写一份产品简报,AI 挑镜头、写文案,一条命令出片。3 种配方、6 个行业、广告法校验,开源可商用。
# Add to your Claude Code skills
git clone https://github.com/Finderchangchang/brewreelSee how brewreel compares with popular alternatives.
brewreel is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by Finderchangchang. 精酿 BrewReel:让 DeepSeek 这类便宜模型也能做出好看的竖版宣传片。写一份产品简报,AI 挑镜头、写文案,一条命令出片。3 种配方、6 个行业、广告法校验,开源可商用。. It has 50 GitHub stars.
brewreel's catalog security scan is still queued. You can run an instant dependency and prompt-injection check now with the "Scan for vulnerabilities" button above.
Clone the repository with "git clone https://github.com/Finderchangchang/brewreel" and add it to your Claude Code skills directory (see the Installation section above). brewreel ships a SKILL.md manifest, so compatible agents can discover and load it automatically.
brewreel is primarily written in TypeScript. It is open-source under Finderchangchang on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh brewreel against similar tools.
No comments yet. Be the first to share your thoughts!
⚠️ Third-Party Software Notice
This skill is third-party open-source software developed and hosted independently on GitHub. SkillsLLM is an informational directory and does not control or maintain the underlying repository.
Any security checks, ratings, or warnings displayed by SkillsLLM are automated and limited in scope. They do not constitute a security certification or guarantee that the software is safe, error-free, or free from malicious code, vulnerabilities, compromised dependencies, or prompt-injection risks.
Review the source code, permissions, dependencies, and configuration before installing or running any third-party skill. Use is at your own risk. To the maximum extent permitted by applicable law, SkillsLLM is not liable for losses arising from third-party software.
The deep catalog scan for this skill is still queued. Run an instant dependency check now instead.
你只做两件事:挑镜头、填文字。不写代码,不改 template/、scripts/、industries/ 里的任何文件,不写坐标、帧数、颜色值。
下文 <SKILL> = 本文件所在目录。命令都用 Node 22 / Python 3.10 跑。English speaker or English video needed → read <SKILL>/SKILL.en.md instead.
选风格(meta.style,不写就是 cards)。先看产品属于哪一类,再读 <SKILL>/styles/<风格>/STYLE.md 和 recipes.md:
| 风格 | 状态 | 适合什么产品 |
|---|---|---|
cards 卡片信息流(默认) |
可用 | 单一卖点、要讲流程、要演示界面、实物门店;六个行业都支持 |
quiz 答题互动 |
可用 | 有常见误解、能出一道选择题的产品(外语短语、功能被误会、菜名名不副实、反常识知识点)。三套模板见 styles/quiz/recipes.md,样例在 styles/quiz/examples/。meta.theme 可选 sage-pine / rice-soy / ash-teal(不写:餐饮用 rice-soy,其余用 sage-pine);phraseTitle.params.voice 选口吻 exam / chat / show(不写按行业选),题号签、回放标题、印章、评论提示这些固定句式跟着口吻走,也可以在镜头里直接写字覆盖;提问句和评论提示自己写,别抄同类视频的套话(Q14 会提醒);clip 台词不许说出答案 |
journey 角色漫游 |
可用 | 内容多、类别清楚的产品(内容平台、功能多的软件、多门店多品类、课程体系、一条游线)。一站一个类别 / 功能 / 景点;三套模板和每拍字段见 styles/journey/recipes.md,样例在 styles/journey/examples/。默认 meta.aspect: "4:5",也可 9:16;背景 opening.params.skyline 选 modern / street / oldtown(古城古镇题材必须 oldtown),街区道具要和内容对得上;开场小引写路线或看点(如「这趟车停 5 站」),别套「跟 X 一口气…」(J18 会提醒);配色 post-green(默认)/ plum-ticket;价格、时间、总量数字只能抄 meta.facts |
cards,不用写 meta.style。开发中的风格校验会拦。meta.aspect:9:16(默认,1080x1920)或 4:5(1080x1350)。cards 只支持 9:16,不用写。cards 的写法。用别的风格时,镜头和字段以那个风格的 recipes.md 为准;行业合规、meta.facts、禁止事项、出片命令照旧。params 里,镜头顶层只有 type、dur、params。例(journey):{"type": "district", "dur": 4, "params": {"category": "预算提醒", "title": "月底前三天,提醒你收手", "scene": "phone"}}。meta.theme 是 cards 的配色,别的风格按它自己的 recipes 写或不写;cta 这类可选字段不需要就整个删掉,不要写空字符串。定行业和语言。
meta.industry:software(默认)/ food(餐饮)/ ecommerce(电商实物)/ education(教培)/ beauty(美业)/ travel(文旅住宿)。选错行业,能用的镜头和合规规则都会不对。meta.lang:zh(默认)/ en。视频要出英文字幕、用户是英文用户,就写 en(用法见第 5 步)。<SKILL>/industries/<industry>/recipe.md(英文项目读 recipe.en.md):里面有这个行业推荐的镜头组合、brief-template.md(这个行业简报要问哪些栏目)、test-brief.md/expected.md(合规红线举例)。跳过这一步很容易写出会被拦的内容。读简报。按对应 brief-template.md 的栏目理解;缺「产品名 / 一句话卖点 / 痛点场景 / 核心动作 / 2–4 个卖点」就先问,别瞎编数据和功能。
meta.product 照抄简报的产品名,全片(hook 胶囊、片尾 brand)只用这一个名字,片尾 brand 必须和它一字不差。meta.action:必填,一句话「用户做什么 → 产品给出什么」(如「拍小票 → 自动填好金额和分类」),不上画面。演示类镜头(chat/phone/mockApp/photoShot)的画面文字要体现这个动作,校验会核对。meta.cta,片尾 cta 照抄它;简报写「无」→ 两处都不写。不要自己编「应用商店搜 XX」。meta.facts,格式是 [{"id":"f1","text":"原话…","source":"来源"}](不是纯字符串数组):
source 必填:照抄简报写的来源(「2026-09 价目表」「后台统计至 8 月」);简报没写来源就写 "简报未注明来源"。不许自己编来源,也不许自己编 fact。quote 可选:简报里的那句原话,逐字照抄。params.refs: ["f1"] 把某个说法(如「现做」、compare 的 stat/level、meter 的读数)和某条 fact 关联起来。"demoData": true,meta.disclaimer 写「演示画面,数据为示例」。示例数字只能出现在 mockApp/phone/chat/priceCard 等演示界面和价格条款里。compare 同一栏的 stat 和 items 也不能自相矛盾(如左栏又写「5 分钟」又写「三天」)。meta.durationRange: [15, 60] 这样的两元素数组。meta.notices:字符串数组,最多 3 条,合并成一行显示在底部。notices 别和 meta.disclaimer 说同一句话(都写「演示」就算重复,校验会拦)。建目录,登记素材:promo/<片名英文>/,分镜写在 promo/<片名英文>/storyboard.json。用户给的截图/录屏/logo/照片复制进同一目录。
photoShot、beforeAfter、storeCard.photo):每个文件都要登记在 meta.assets:
"assets": [{"src": "photos/dish.jpg", "source": "merchant"}]。source 只能是 merchant(商家实拍)/ illustration(插画、示意图)/ screenshot(软件截图)。_dev/ 下的文件都算占位图,会被拦。beforeAfter 的两张必须是同一位顾客的两张不同照片:都登记 merchant,kind 分别写 customer-before / customer-after,pair 写同一个值(如 "A")。同一张图、改名复制的图都会被拦。{"source": "drawn", "tag": "示意", "illust": "<插画 id>"} 用插画兜底,校验会放行并列进「需人工复核」。不写「实拍」「顾客授权」,不设 consent。商家给了照片却一张没用,才会被拦。选主题(meta.theme):
warm-emotiontech-darkfresh-lightbusiness-bluefestival-redmono-premium
有品牌色就写 meta.brandColor(#RRGGBB),它只换强调色。挑 5–9 个镜头(镜头说明看 <SKILL>/shots.md,18 个镜头一览表在最上面;用 quiz / journey 时镜头换成那个风格的,字段照第 0 步写进 params)。hook 必须第 1 镜(2–3 秒),endCard 必须最后 1 镜(4 秒)。
必须有一镜演示核心动作(第 2 步写的 meta.action),按行业用不同的镜头,校验会拦:
chat 写 messages + panel(提问 → 回答);或 mockApp 写 input(用户输入/提问)+ 结果(dashboard 的 stat、editor 的 items、done);有截图用 phone。
mockApp kind:"form" 只给本来就是填表的产品,别拿表单顶替核心动作。input 和 stat.label 要问答对得上(问「上月广州新增多少商户」,stat 就写「上月广州新增商户」);items 别写「数据」「信息」「内容」这种占位词。photoShot(实拍或插画兜底)或 beforeAfter,再配 steps / priceCard 讲清楚。
meta.industry 决定哪些镜头能用(见 industries/<industry>/rules.json 的 enabledShots,或直接看 recipe.md),选了不开放的镜头校验会报错。7 个行业镜头(software 默认不开):photoShot 实拍照片/短视频(菜品、商品、作品、房间、公区、后厨)priceCard 价目表;storeCard 门店/地图/预订;reviewCard 真实顾客评价(原文摘录,不能改写得更夸张)factSheet 参数表/开箱清单/课程大纲/考试信息/色卡;credCard 资历/荣誉卡beforeAfter 前后对比滑块(只有美业开放,要 consent:true + retouched:false)
中间按产品类型选镜头,别套固定模板,features 卖点卡不是必选。两条硬要求(校验会提醒):industries/<industry>/recipe.md 的推荐结构改):visual 同一批片子别总用一种:一条扎心消息用 bubble,有真数字用 stat,说一处风景/一样东西用 illust,痛点 vs 产品用 split。compare 写了 level 时,tone: good 那栏要在这把尺子上占优(写 higherIs 说清越高越好还是越差)。
总时长 20–30 秒最好(允许 15–45,或 meta.durationRange 的自定义范围)。同一种镜头别连着用。相邻两镜 mood 差别别超过 0.5(中间插一镜过渡),否则背景会硬切。写字幕(每镜的 caption):一镜一句话,抖音式大字,说给观众听,不描述画面怎么动(❌「卡片一张张出,讲它能做什么」这是镜头说明,不是字幕)。
\n 换行;每行 ≤12 个汉字(字母数字算半个)。meta.lang: "en" 时英文字幕按拉丁字符数折算(约中文限制的 1.8 倍),具体数字看 docs/shots/<type>.en.md{} 包住最关键的 2–5 个字,变强调色;每条最多 1 处params.slogan"caption": ["先别急着发,\n对方要的是{你的在乎}", "挑一条填进输入框,\n发不发{你决定}"]\n;字幕里要用引号就写「」,不要写英文双引号 "写 mood(0–1):痛点/紧张 0.8–1,转折 0.5,产品和卖点 0–0.3,片尾 0。背景颜色和配乐都跟着它变。
写 storyboard.json,格式见文末完整示例。时长用 dur(秒),写 0.5 的整数倍。
文件必须是 UTF-8 编码。中文 Windows 默认 GBK:用编辑器/写文件工具直接写 UTF-8;用 PowerShell 就 [IO.File]::WriteAllText($p, $json, [Text.UTF8Encoding]::new($false));用 Python 就 open(p, "w", encoding="utf-8")。不要用 echo >、Out-File(5.1 版)写中文。
chat 的 panel.replies 是产品建议**「我」**发给对方的话,站在 me 的立场写(我说要加班,建议回复不能是「别再加班了,陪我」——那是对方的口吻);有 panel 就别写 typing。
校验,按报错逐条改,直到通过。简报是文件时加 --brief,校验会核对 facts 里的数字和 quote 是不是真在简报里:
node <SKILL>/scripts/validate.mjs promo/<片名>/storyboard.json --brief promo/<片名>/brief.md
报错格式是「第 N 镜(类型)字段:问题 → 怎么改」,照「怎么改」做。结果分三档:
出片(2–4 分钟,会自动生成配乐;别的片子在渲染时会排队,每 15 秒打印一次排队情况):
node <SKILL>/scripts/make.mjs promo/<片名>/storyboard.json --out promo/<片名> --brief promo/<片名>/brief.md
--out 必填。测试时改用 --round <轮次>:产物放到仓库外的 promo-video-skill-tests/<轮次>/<片名>/(和仓库同级),同一轮的几支片子用同一个轮次名,不要自己按秒生成时间戳目录,也不要把测试产物写进仓库。--out 落在仓库里(promo/ 除外)时 make 会直接退出(退出码 2);测试用 --round,或给仓库外的绝对路径。manifest.json,直到 status 出现(delivered 才算成)。没看到 交付: 那一行之前,不许写交付报告、不许结束。video.mp4、sheet.png(每秒一帧拼图)、check/(第 0 帧 + 每镜结束前的全尺寸帧)、report.txt、layout.json、manifest.json(分镜和成片的 sha256、时长、各项检查结论)。开跑时会先清掉目录里上一次的这些产物。--stills 0,3.5,8(秒),只出单帧,不出整片(不是交付)。meta.voice(配音):make 会先合成旁白、按声音改写镜头时长,见下文「配音」。没有这家的 key 时加 --voice-provider mock 先看节奏(占位音,不能交付),或加 --no-voice 出无配音版。交付:<mp4 路径>,交给用户的路径只能抄这一行。没有这一行就是失败,不许把别的 mp4 当成片。video.rejected.mp4,只给人看哪里坏了)/ 4 渲染失败或时长不对 / 5 排队超时 / 6 内部错误 / 130 被中断。report.txt:「机器自查」「文字排版报告」「布局自查」里有一个 ✗ 就不能交付(make 会返回 3)。布局自查在渲染后量每个文字块:被卡片裁切、两块字互相压住、关键文字出了 x180–900、英文片画面上出现汉字(每半拍抽一帧查)。✗ 通常是某个字段写太多:删条目或缩短文字,改完回到第 9 步。全是 ✓ 之后再看 sheet.png 和 check/,按下面清单自查。node <SKILL>/scripts/make.mjs promo/<片名>/storyboard.json --out promo/<片名> --verify,确认成片还对应当前分镜(改过分镜会报「成片和分镜不一致,请重跑 make」)。把 make 最后一行的 mp4 路径、sheet.png 路径交给用户,附上「发布前自查清单」(见下)——第 9 步的「需人工复核」条目原样列进去,逐条让用户确认,不要替用户下判断。用户要旁白 / 配音 / 口播时才开;不写 meta.voice 就是无配音片,和以前完全一样。开了之后声音就是时间轴:make 先合成每句旁白、拿到逐字时间,再把写了 vo 的镜头时长改成「0.15 秒 + 旁白 + 0.35 秒」向上取整拍(不短于这种镜头的最短时长),你写的 dur / beats 只对没写 vo 的镜头算数;字幕跟着声音逐字点亮,配乐在人声处自动压低约 10 dB。
meta.voice(只能写这 6 个字段,多写报错):
| 字段 | 写法 |
|---|---|
provider |
必填。minimax / aliyun / volcengine = 真人感配音(各要自己的环境变量,见下表);mock = 不联网的占位音,只用来听节奏。用户没指定就写 minimax |
voiceId |
音色,不写用这家的默认(下表)。音色 id 各家不通用,换 provider 要一起换 |
speed |
0.5–2,默认 1。广告旁白 1–1.15;念不完就删字或拆镜,别靠调快硬塞 |
emotion |
只有 minimax 认:calm / fluent / happy / sad / angry / fearful / disgusted / surprised / whisper。不写用音色默认;广告旁白建议 calm 或 fluent。aliyun / volcengine 写了会被忽略 |
model |
一般不写(用这家的默认,见下表)。volcengine 这里填资源 ID,音色要和它对上 |
subtitles |
karaoke(默认,逐字点亮)/ line(整句出现)/ off(只念不出旁白字幕) |
每镜的 vo(这一镜要念的一句话):
vo 的镜头按 dur 播,配乐照常。recipes.md。推荐一句 8–20 字。英文按每秒 2.5 词算。校验按中文 5 字/秒、英文 3 词/秒拦,出片时按真实配音时长再核一遍,超了会停并告诉你第几镜能念多少字。vo 和字幕走同一套检查——带单位的数字要能在 meta.facts 里找到,广告法极限词、绝对化用语、错别字、速度说法照样拦。念出来的数字和画面上的保持一致。{} 强调:和字幕一样,每句最多 1 处(24 字以内),字幕上变强调色。vo、没写 caption 的镜头,字幕由 vo 自动生成(逐字点亮);写了 caption 的镜头照旧显示 caption、旁白只念——hook 必须写 caption(它是封面标题);endCard 只念不出字幕。quiz / journey 在自己的字幕条上显示旁白。meta.product 一字不差)。
三家怎么选(都按字符计费、都能给逐字时间戳;以各家控制台为准,第一次用先试听):| provider | 要设的环境变量 | 默认模型 | 中文默认音色 | 英文默认音色 | 实测 |
|---|---|---|---|---|---|
minimax |
MINIMAX_API_KEY(可选 MINIMAX_GROUP_ID、MINIMAX_BASE_URL) |
speech-2.8-hd |
Chinese (Mandarin)_Male_Announcer(播报男声) |
English_expressive_narrator |
已用真实 key 出片 |
aliyun(阿里云百炼 CosyVoice) |
DASHSCOPE_API_KEY(可选 DASHSCOPE_WORKSPACE_ID、DASHSCOPE_REGION、DASHSCOPE_TTS_URL) |
cosyvoice-v3-flash |
longsanshu_v3(沉稳质感男) |
loongabby_v3 |
未实测 |
volcengine(火山引擎豆包语音) |
VOLCENGINE_TTS_API_KEY,或旧版 VOLCENGINE_TTS_APP_ID + VOLCENGINE_TTS_ACCESS_TOKEN(可选 VOLCENGINE_TTS_BASE_URL) |
seed-tts-2.0 |
zh_male_guanggaojieshuo_uranus_bigtts(广告解说) |
en_male_alex_uranus_bigtts |
未实测 |
「未实测」= 按官方文档接入、用假响应测过,还没用真实 key 出过片;第一次用出了问题,报错里会写是鉴权、限流还是参数,按提示改或换 minimax。
推荐音色:
Chinese (Mandarin)_Male_Announcer(默认):播报男声,稳重清楚,适合大多数产品片Chinese (Mandarin)_News_Anchor:新闻女声,稳重播报,适合 B 端、办公、工具female-shaonv:年轻女声,适合 C 端生活、情感、轻工具male-qn-qingse:年轻男声,口语感强,适合答题互动、种草presenter_female:女主持,适合讲解、教培meta.lang: "en"):English_expressive_narrator(默认);英文片最好写明 voiceIdlongsanshu_v3(默认,沉稳质感男)、longshu_v3(沉稳青年男)、longxiaoxia_v3(沉稳权威女)、longxiaochun_v3(知性积极女);英文 loongabby_v3model 用默认 seed-tts-2.0):zh_male_guanggaojieshuo_uranus_bigtts(默认,广告解说)、zh_male_cixingjieshuonan_uranus_bigtts(磁性解说男)、zh_female_tianmeixiaoyuan_uranus_bigtts(甜美女声)、zh_female_zhixingnv_uranus_bigtts(知性女声);英文 en_male_alex_uranus_bigtts没有 key 怎么预览:出片加 --voice-provider mock(不联网的占位音,时间轴、逐字字幕、配乐压低都照常,不用改分镜);或加 --no-voice 出无配音版。mock 出的片子只是看节奏,不能当成片交付——交付时要明说「这是占位音,设好 key 重跑才是真人配音」。没有 key 时 validate 只提醒、不拦。
费用:三家都按字符计费(旁白全文,价格看各家官网)。同一句(提供者、模型、音色、语速、情绪、文字都一样)合成过一次就缓存在用户目录 ~/.cache/brewreel/tts(环境变量 BREWREEL_TTS_CACHE 可改),改画面、改字幕、重渲染都不再计费;改了 vo 或音色才会重新合成。manifest.json 的 voice.billedCharacters 是这一次计费的字符数。
密钥:只从环境变量读(每家的变量名见上表;自定义接口地址只接受 https)。不要把 key 写进分镜、简报、命令行参数或任何文件,也不要打印出来。
配音相关退出码:旁白比这一镜最长时长还长 → 1(删字或拆镜);没 key、鉴权失败、限流重试用完、网络不通 → 2(让用户设 key 或稍后重跑;先看效果用 --voice-provider mock)。
\n、反斜杠这类怪字符meta.facts 里找到来源beforeAfter 只在美业;reviewCard 的引用是原文,没有改写得更夸张human 列表,原样抄给用户,别替用户判断「应该没问题」。常见的有:reviewCard/credCard 的引用是否和简报原文一字不差、平台规则口径是否有更新、行业资质是否齐全。meta.industry 选对了吗(不对的话开放的镜头和合规规则都会错)。consent/retouched 这类字段只是校验要求写,真实取得同意是用户的责任,不是校验能替你核实的)。meta.platform 一致,对应的平台专属规则(如购物车不能挂价格字幕)是否已经确认。hook;endCard 放最后meta.durationRange 的自定义范围);每种镜头有自己的时长范围(见 shots.md)meta.lang: "en" 时英文有自己的字符数上限,见对应字段的说明)meta.action(见第 5 步);同一句字幕最多停 5 秒brand = meta.product;片尾 cta = meta.cta(简报没给就都不写)\\n 会原样显示在画面上)meta.allowWords,不要为了过校验改产品名meta.allowWordsmeta.facts 里找到同样的数字,没有就是编造,一律报错;每条 fact 必须有 sourcemeta.demoData: true + disclaimer 带「演示/示例」meta.assets 登记来源;beforeAfter 前后必须是同一位顾客的两张不同的商家实拍template/、scripts/、industries/ 里的任何文件;不写坐标、像素、帧号、颜色值、CSSmeta.facts 里找得到。没有真数据:效果类镜头(counter、带数字的 compare、「变好」的 meter)不用,演示界面里的示例数字用 demoData 声明bgm 字段(make.mjs 自动填);顶层也不写 voice(配音设置写 meta.voice,每镜念的话写 vo)| 报错 | 改法 |
|---|---|
| 第 N 行 … 字,每行最多 12 字 | 缩短,或在语义停顿处用 \n 断成两行 |
| 用了 2 处 {} 强调 | 只留最关键的一处 |
| {} 没有成对 | 每个 { 都要有 },不要跨行 |
| 含《广告法》极限词「最」 | 换成可证实的说法:「最快」→「3 秒出结果」 |
| 第 1 镜必须是 hook | 在最前面加 hook |
| endCard 这一镜不能写字幕 | 删掉 caption,大字写在 params.slogan |
| 多了一个不认识的字段 | 看报错里的「可用字段」,改拼写(如 mockApp 用 kind 不是 variant) |
| 没有叫「xx」的图标 | 从 shots.md 顶部的图标清单里选 |
| 总时长 … 要在 15–45 秒之间 | 加/删镜头,或改 dur |
| 素材文件找不到 | 检查路径,相对 storyboard.json 所在目录 |
| JSON 解析失败:第 N 行 | 看那一行:漏逗号、多了结尾逗号、字幕里写了英文双引号(改成「」) |
| 这一句要在屏幕上停 N 秒 | caption 写成 2–3 句的数组,或把这一镜拆成两镜 |
| 全片没有一镜在演示核心动作 | 加 chat(提问 → panel 回答)或 mockApp(input + 结果) |
| 片尾产品名和 meta.product 不一致 | brand 改成和 meta.product 一字不差 |
| 写了 cta,但 meta.cta 是空的 | 简报有获取方式就写进 meta.cta 再照抄;没有就删掉 cta |
| 里有字面的 \n | JSON 里换行只写一个反斜杠 |
| vo:旁白 N 字,这一镜最长 M 秒,要每秒念 X 字才念得完 | 删字,或把这句拆到两镜(每镜一句);别靠调快 speed |
| 配音失败:旁白念完要 N 秒,超过这一镜最长 M 秒 | 按提示的字数缩短,或拆镜 |
| 当前环境没有 MINIMAX_API_KEY / DASHSCOPE_API_KEY / VOLCENGINE_TTS_API_KEY(提醒) | 让用户设好对应的环境变量再出片;先看节奏加 --voice-provider mock |
| 配音设置要写在 meta.voice 里 | 顶层的 voice 挪进 meta,每镜要念的话写 vo |
| 含平台名「公众号」(提醒) | 产品本身的品类词:加进 meta.allowWords;引流:删掉 |
| 缺少必填字段 meta.action | 写一句「用户做什么 → 产品给出什么」 |
| 数字在 meta.facts 里找不到来源 | 简报给了这个数字就原话抄进 meta.facts({"id":"f1","text":"…","source":"…"} 格式);没给就把具体数字换成定性说法 |
| meta.facts[N].source:缺少 source | 照抄简报写的来源;简报没写就写 "简报未注明来源" |
| 来自标了「示例/演示」的 fact,但没声明这是演示数据 | meta 写 "demoData": true,disclaimer 写「演示画面,数据为示例」 |
| 只在你自己标了「示例/演示」的 fact 里有 | 这是效果说法,示例数据撑不住:删掉数字,compare 只比做法;counter 换成 steps 或 compare |
| level(8 对 2)…meta.facts 里没有这个分数 | 删掉两栏的 level 和 meterLabel,差别写进 items |
| 刻度方向反了 | 让 tone: good 那栏在这把尺子上占优,或写 higherIs / 换 meterLabel 的说法 |
| 读数 N 没有依据 | 产品演示里给出的判断 → demoData: true;效果/评分 → 数字抄进 facts 并写 refs,没有就删掉这一镜 |
| 限定语丢了:没写 facts 里跟着它的「周日至周四」 | 把 fact 里的日期范围/条件原样写进同一镜(字幕、标题或卡片),别改写成「平日」「周末」 |
| 说 29.9 元,但简报里这个价要满足条件才有 | 同一句写清条件,如「领券后29.9元」;放不下就别在这里报价 |
| 是实物/门店行业,mockApp 是编出来的 App 界面 | 删掉 mockApp,用 photoShot(实拍或插画兜底)+ steps 演核心动作 |
| 素材没登记 / 前后两张是同一个文件 | 在 meta.assets 登记每个文件的来源;前后对比换成同一位顾客的两张不同照片,没有就改用 steps |
| 「现做」类说法需要依据 | 给这一镜写 refs 指向简报里的那条 fact;这一镜没有 refs 字段就删掉这类说法 |
| 字幕含镜头说明词(如「卡片一张张出」) | 这是说给观众听的字幕,不是给剪辑的说明;换成用户视角的一句话 |
| 「登陆」是错别字,应为「登录」 | 改成「登录」(「登陆舰/登陆月球」这类不算) |
| 「一清二楚」是绝对化承诺 | 换成有分寸的说法,如「关键信息看得到」 |
| 「XX」行业不开放镜头「YY」 | 换一个这个行业开放的镜头,或检查 meta.industry 是不是选错了 |
| [B-xxx] 命中行业合规规则 | 报错信息里的「怎么改」照做;确有依据的极限词才考虑 meta.allowWords(只对 warn 级有效,block 级必须删) |
优先用 mockApp 镜头(它会动)。如果一定要演「手机里点这里」,先把 mockApp 渲成一张示意截图再给 phone 用:
cd <SKILL>/template
npx remotion still src/index.ts Screen <分镜目录绝对路径>/screen.png --frame=145 --props=<分镜目录绝对路径>/screen-props.json
screen-props.json 写 {"type":"mockApp","theme":"<主题>","dur":5,"params":{...mockApp 的 params...}},参考 <SKILL>/examples/_src/screen-props.json。然后 phone 镜头写 "src": "screen.png",并在 meta.disclaimer 写「演示画面,内容为模拟」。
9 份样例都能直接通过校验并出片,产品和数据都是虚构的:
<SKILL>/examples/jev.json:C 端情感,software(聊天演示配 2 句字幕 → 对比 → 仪表 → 快切 → 片尾;仪表读数是演示判断,写了 demoData)<SKILL>/examples/ledger.json:工具提效,software(痛点快切 → 只比做法的对比 → mockApp 拍小票出结果 → 预算读数 → 片尾;没有真实效果数据,所以不用 counter)<SKILL>/examples/meeting.json:B 端办公,software(截图圈注 → 待办列表 → 前后对比 → 步骤 → 片尾;获取方式「官网申请免费试用」)<SKILL>/examples/en-focus.json:meta.lang: "en" 的英文样例<SKILL>/examples/food.json:餐饮上新(插画兜底的 photoShot → 到店三步 → 甜度读数有 fact 撑 → 活动价 → 片尾)<SKILL>/examples/ecommerce.json:电商实物(分屏钩子 → 新旧对比 → 商家实测数字 → 券后价写清条件 → 片尾)<SKILL>/examples/education.json:教培(服务条款 → 课程大纲 → AI 演示 → 讲师 → 价格)<SKILL>/examples/beauty.json:美业,没有实拍照片时怎么拍(插画 + 步骤 + 答疑 + 价目表)<SKILL>/examples/travel.json:文旅住宿(插画钩子 → 看房 → 地图 → 价格按 facts 原样写日期范围)vo,provider 写的是 minimax;没有 key 时出片加 --voice-provider mock,或把 provider 改成 mock 预览):<SKILL>/styles/cards/examples/voice-reminder.json(cards)、<SKILL>/styles/quiz/examples/software-archive-voice.json(quiz)、<SKILL>/styles/journey/examples/software-notes-voice.json(journey)industries/<industry>/test-brief.md + expected.md:test-brief 是一份示例简报,expected 写清楚照这份简报写的分镜哪些地方会被拦、为什么。开新行业的第一支片子建议先看这两份。{
"meta": {
"title": "省心记账 宣传片(痛点 → 产品 → 3 卖点 → 片尾)",
"product": "省心记账",
"theme": "fresh-light",
"disclaimer": "演示画面,数据为示例",
"demoData": true,
"action": "拍小票 → 自动填好金额和分类",
"facts": [
{"id": "f1", "text": "演示账本示例条目:外卖 ¥860、奶茶咖啡 ¥326、忘关的自动续费 ¥98、深夜打车 ¥410(示例数据)", "source": "虚构产品的示例数据"},
{"id": "f2", "text": "演示识别结果:午饭 ¥38.5,本月餐饮预算已用 62%(示例数据)", "source": "虚构产品的示例数据"}
]
},
"shots": [
{
"type": "hook",
"dur": 2.5,
"caption": "工资刚到手,\n月底又{见底了}",
"mood": 0.85,
"params": {"visual": "stat", "text": "¥ 0.00", "sub": "这个月花哪了", "badge": "拍张小票就记好", "tone": "bad"}
},
{
"type": "quickList",
"dur": 3.5,
"caption": "钱花哪了,\n却{一笔都想不起}",
"mood": 0.8,
"params": {
"title": "本月去向不明",
"items": [
{"text": "外卖", "tag": "¥860", "tone": "bad", "icon": "bell"},
{"text": "奶茶咖啡", "tag": "¥326", "tone": "warn", "icon": "heart"},
{"text": "忘关的自动续费", "tag": "¥98", "tone": "bad", "icon": "calendar"},
{"text": "深夜打车", "tag": "¥410", "tone": "warn", "icon": "clock"}
]
}
},
{
"type": "compare",
"dur": 4.5,
"caption": "记账这件事,\n{别再靠毅力}",
"mood": 0.45,
"params": {
"mode": "lr",
"left": {"title": "手动记账", "items": ["每笔手动输入", "分类全靠猜", "拖到最后就放弃"], "tone": "bad", "icon": "doc", "stat": "全靠手打"},
"right": {"title": "省心记账", "items": ["拍小票自动识别", "自动分好类", "月底一键复盘"], "tone": "good", "icon": "bolt", "stat": "拍一下"},
"verdict": "记账不用再硬撑"
}
},
{
"type": "mockApp",
"dur": 4.5,
"caption": "拍一下小票,\n{金额分类都填好}",
"mood": 0.25,
"params": {
"kind": "editor",
"title": "记一笔",
"source": "示意数据,非真实用户账单",
"input": "拍照:午饭小票",
"button": "识别",
"items": [
{"text": "午饭 ¥38.5"},
{"text": "商家:楼下面馆"},
{"text": "分类:餐饮(自动)"},
{"text": "本月餐饮已用 62%"}
],
"highlight": 3,
"done": "已记好"
},
"note": "核心动作演示:用户拍小票 → 产品给出金额、商家、分类"
},
{
"type": "meter",
"dur": 3,
"caption": "预算快花完,\n{它先提醒你}",
"mood": 0.35,
"params": {"value": 62, "max": 100, "label": "餐饮预算已用", "unit": "%", "style": "ring", "higherIs": "bad", "word": "留神", "note": "超过八成会弹提醒"},
"note": "单个读数(演示账本里的预算进度),不是效果对比;meta.demoData 已声明"
},
{
"type": "endCard",
"dur": 4,
"mood": 0,
"params": {
"brand": "省心记账",
"slogan": "花出去的每一笔,\n{心里都有数}",
"points": ["拍小票自动记账", "账本只存在你手机里"],
"icon": "money"
}
}
]
}
便宜模型,也能酿出好片:写一份产品简报,AI 挑镜头、写文案,一条命令出一支竖版宣传片。
官网 · 演示视频 · 历史版本 · 更新日志 · 在 DeepSeek Harness 里用 · 姊妹项目 Jev 聊天助手 · English
原名 promo-video-skill / 蒸馏视频,旧地址自动跳转。
想出现在这里?加微信 jskjkf007,添加时请备注「BrewReel 商务合作」。
下面都是实际渲染的画面。分镜都在仓库里,产品和数据都是虚构的;演示视频(v0.3.0 附件,约 5 MB)是三种配方的实际渲染效果。
三种配方
六个行业(每张图左边是第 0 帧封面,右边是片中一帧)
这 9 份分镜在 examples/(都是 cards 配方),quiz 和 journey 的样例在 styles/quiz/examples/、styles/journey/examples/。每份都能直接通过校验并用 make.mjs 出片。
storyboard.json:挑镜头、填文字,不写代码、不算坐标。版式、动效、节奏都在现成组件里。| 用法 | 状态 | 说明 |
|---|---|---|
Claude Code / Codex / opencode 等能读 SKILL.md 的 AI 编程助手 |
✅ 可用 | 把仓库装成 skill,助手照 SKILL.md 写分镜、跑校验、出片 |
DeepSeek Harness 插件 dsh-brewreel |
⚠️ 已发布到 npm | 7 个工具负责校验、出片、核对;还没接真实 DeepSeek 模型实测 |
无 agent 脚本 scripts/llm_make.py |
✅ 可用 | 直接调 OpenAI 兼容接口(默认 DeepSeek),简报进、视频出,校验报错自动回喂重试 |
| 运行环境 | 要求 |
|---|---|
| 操作系统 | Windows(仅 x64)/ macOS ≥ 15 / Linux(glibc ≥ 2.35,需要 libnss3 / libgbm / libasound2 等共享库;不支持 Alpine、NixOS) |
| Node.js | ≥ 18(建议 20 LTS 或更高,本仓库在 Node 22 上测试过);DeepSeek Harness 插件要 22.19+ 的 22.x 或 24+ |
| Python | 3.10+;配乐脚本要 numpy / scipy,llm_make.py 只用标准库 |
| 首次下载 | 渲染依赖约几百 MB,外加约 110 MB 的 Chrome Headless Shell |
成片 1080×1920(journey 默认 1080×1350),30 fps,带配乐和音效。
1. 装依赖。
git clone https://github.com/Finderchangchang/brewreel.git
cd brewreel/template && npm install && npx remotion browser ensure
cd .. && pip install numpy scipy
npm install 装渲染引擎(lock 文件里带 7 个平台的 Remotion compositor,换平台不用重新生成);npx remotion browser ensure 下载一次 Chrome Headless Shell,供无头渲染用。
2. 跑一个样例,确认装好了。
node scripts/validate.mjs examples/ledger.json
node scripts/make.mjs examples/ledger.json --out ../brewreel-out/ledger
第一条校验通过就说明装好了。第二条出片要几分钟,终端最后一行是「交付:<mp4 路径>」;输出目录里有 video.mp4、拼图 sheet.png、检查帧 check/、report.txt 和交付清单 manifest.json。--out 不能指向仓库里面。
3. 让 AI 写分镜。 三选一:
~/.claude/skills/brewreel/(Claude Code)或 ~/.agents/skills/brewreel/(通用约定),或用你工具自带的 skill 安装命令指向本仓库。然后把简报交给助手(模板见 brief-template.md),让它照 SKILL.md 出片。scripts/llm_make.py 直接调 OpenAI 兼容接口:简报进、视频出,校验报错会原样回喂给模型重试(最多 3 次)。
export ANTHROPIC_BASE_URL=https://api.deepseek.com/anthropic # 仅当把 DeepSeek 接到 Claude Code 时需要
export ANTHROPIC_AUTH_TOKEN=<你的 DeepSeek API Key>
export ANTHROPIC_MODEL=deepseek-flash[1m]
# 或者直接用无头脚本,不接 Claude Code:
export LLM_API_KEY=<你的 DeepSeek API Key>
export LLM_BASE_URL=https://api.deepseek.com
export LLM_MODEL=deepseek-chat
python scripts/llm_make.py path/to/brief.md
Windows PowerShell 用 $env:LLM_API_KEY="..." 代替 export。以上都是占位符,换成你自己的 key;不要把 key 提交进仓库或写进 issue。也可以把这些变量写进 AI 编程助手自己的全局配置(如 ~/.claude/settings.json),这是可选做法,本仓库不会替你改任何全局配置。加 --dry-run 不调接口、不读密钥,只把拼好的提示写出来并估算 token 数。
仓库自带一个 DeepSeek Harness(dsh)插件,放在 integrations/deepseek-harness/,包名 dsh-brewreel(原名 dsh-distill-video,从旧版升级见插件 README 的「从 dsh-distill-video 升级」)。装上后,模型照着 skill 写分镜,校验、出片、核对都调插件的工具完成,不用自己拼 node scripts/… 命令;出片在后台跑、报进度,输出路径和子进程拿到的环境变量都受插件限制。
需要 dsh 0.1.7-rc.2 或更高的 0.1.x。npm 上 dsh 的 latest 标签目前还指向更早的 0.1.5-rc.3,所以安装时要写明版本号。另外要有 Node.js 22.19+ 的 22.x 或 24+,以及 pnpm(dsh plugin 靠 pnpm 装插件)。从 npm 安装:
npm install -g @deepseek-ai/dsh@0.1.7-rc.2 pnpm # 还没装 dsh 时
dsh plugin --profile web add dsh-brewreel
dsh web
web 可以换成你自己的 profile 名,profile 已经在运行的要重启才生效。第一次用时对模型说「检查一下视频插件环境」,它会调 doctor,经你同意后再调 setup 装渲染依赖(约几百 MB,外加约 110 MB 的 Chrome Headless Shell)。想用仓库里还没发版的代码,可以 clone 后在上一级目录执行 dsh plugin --profile web add ./brewreel/integrations/deepseek-harness。插件还没接真实 DeepSeek 模型实测,遇到问题请开 issue。
brewreel_doctor 查环境,brewreel_setup 装依赖和浏览器,brewreel_catalog 列风格、行业和配色,brewreel_guide 读 skill 与各风格、行业、镜头文档,brewreel_validate 校验分镜并给改法,brewreel_render 后台出片,brewreel_verify 核对成片是否还对应当前分镜。THIRD_PARTY_LICENSES.md);插件不改变这一点。分镜里写 meta.style 选配方,不写就是默认的 cards。每种配方是一个「风格包」:自带设计令牌、镜头组件、校验规则和叙事模板,文档、规则、样例放在 styles/<id>/,代码放在 template/src/styles/<id>/。
| 配方 | 画幅 | 适合 |
|---|---|---|
cards 卡片信息流(默认) |
9:16 | 单一卖点、使用流程、界面演示、实物和门店、价目表 |
quiz 答题互动 |
9:16 | 有一个常见误解、能出一道唯一正确答案的选择题(「X 到底是什么意思?」) |
journey 角色漫游 |
4:5(默认)/ 9:16 | 有 4–6 个清楚的类别、功能或站点,想按一条路线挨站逛一遍 |
怎么选:能出一道选择题 → quiz;有 4–6 个类别想挨站逛 → journey;其余情况 → cards,也就是不写。quiz 只接受 9:16,它的专属镜头(出题、揭晓、释义卡等)只能在 quiz 里用,和 cards 的 18 个镜头不混用,写错会被校验拦下。
{ "meta": { "style": "quiz", "industry": "software", "lang": "zh" }, "shots": [ ... ] }
cards 卡片信息流(默认,可用,9:16):渐变底 + 居中白卡片 + 描边大字幕,一镜讲一件事。适合单一卖点、讲使用流程、演示界面、实物和门店。18 个镜头、六个行业的样例都在 examples/。
quiz 答题互动(可用,9:16):皮肤是「批改纸」——点阵答题纸底加一条朱红页边线,深色主色 + 杏黄马克笔 + 朱红批改笔,标签用等宽字,卡片是小圆角 + 实色硬投影;三套配色(sage-pine 灰绿纸 + 松绿,默认;rice-soy 米纸 + 酱色,餐饮默认;ash-teal 灰纸 + 深青),三套口吻(phraseTitle.params.voice:exam 考场腔 / chat 闲聊腔 / show 挑战腔)。两个原创角色一矮一高:戴耳机的主讲人(懂了耳罩亮起、发出声波)和反戴棒球帽的搭档。节奏是「红笔圈出一个常见误解 → 答题卡出一道 A/B/C 题、秒表倒数 3 → 揭晓打勾 → 词条卡翻正(误解被波浪线划掉 + 编号释义)→ 回放原片段、盖一枚「懂了」章 → 小剧场演一遍 → 评论区互动 → 印章擦除落到结业卡」。适合有常见误解、能出一道选择题的产品:一句外语的真正意思、软件里一个常被误会的功能(如「归档 = 删掉了?」)、一道菜为什么要这么做。说明见 styles/quiz/,写法和字数见 styles/quiz/recipes.md,5 份样例分镜在 styles/quiz/examples/。
journey 角色漫游(可用,默认 4:5,也支持 9:16):皮肤是「旅行文具」+「剪纸分层」——原创吉祥物「橘团」踩悬浮滑板,一镜到底横穿一座剪纸风城市(远、中、近景和角色各是一张纸,身后投硬边纸影);开场是车站翻牌大字,顶部一整条车票标着路线、站点和当前站名,每站甩进来一张航空信封边的明信片写代表内容、看完「寄出」到车票上这一站;配色是邮政绿 + 荧光青柠 + 石墨描边(post-green,另有 plum-ticket 酒红车票)。背景三选一(现代城市 / 低层街巷 / 古城的白墙黛瓦和石桥河道),14 种街区按内容挑(道口、邮筒、检票口、大头贴、搭车站、夜站台、手机、住家、咖啡、集市、城门、石桥、茶馆、灯会),每站一个车站 / 邮路题材的小笑点,天色从白天走到夜晚;到终点,顶部那张车票滑到画面中间展开,检票钳在票根上打个孔,车票翻面露出产品名和口号;最多一个数字,印在正面终点旗旁。适合内容多、类别清楚的产品:内容平台的栏目、软件的功能、一条游线的景点。说明见 styles/journey/,写法和字数见 styles/journey/recipes.md,3 份样例分镜在 styles/journey/examples/。
分镜里写 meta.voice、每镜写一句 vo(旁白),出片时就带配音;不写就是无配音片,和以前一样。
meta.voice.provider 写 minimax(MiniMax)、aliyun(阿里云百炼 CosyVoice)或 volcengine(火山引擎豆包语音),默认都是男声播音,音色可换。MiniMax 已用真实