
Huashu Douyin Script
- 849 installs
- 1.3k repo stars
- Updated April 21, 2026
- alchaincyf/huashu-skills
huashu-douyin-script is a Claude Code workflow skill that turns competitor Douyin videos into ready-to-shoot viral scripts with structured analysis and AI review for developers who automate short-video creative pipelines
About
huashu-douyin-script is a six-step Douyin script workflow from alchaincyf/huashu-skills that downloads 1–5 competitor videos with yt-dlp, analyzes them via the Gemini API, extracts viral formulas, and generates scripts plus shot breakdowns with AI tone review. Required tooling includes uv, yt-dlp, a GEMINI_API_KEY, and a Chrome session logged into Douyin for download cookies. Developers trigger it for 抖音脚本, 爆款拆解, 竞品分析, 带货脚本, 千川素材, and 种草脚本 requests. Reach for this skill when you need a repeatable pipeline from competitor URLs to structured Chinese short-video scripts instead of manual imitation.
- Complete 6-step workflow from competitor video download to final script and storyboard generation
- Automated Douyin video download using yt-dlp with Chrome cookie extraction
- Parallel Gemini video analysis that extracts viral hooks, structure and formulas
- Applies proven viral formulas to your product details and target audience
- AI taste review that removes generic patterns before final output
Huashu Douyin Script by the numbers
- 849 all-time installs (skills.sh)
- +23 installs in the week ending Jul 28, 2026 (Skillselion tracking)
- Ranked #322 of 2,742 Automation & Workflows skills by installs in the Skillselion catalog
- Security screen: CRITICAL risk (skills.sh audit)
- Data as of Jul 28, 2026 (Skillselion catalog sync)
npx skills add https://github.com/alchaincyf/huashu-skills --skill huashu-douyin-scriptAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 849 |
|---|---|
| repo stars | ★ 1.3k |
| Security audit | 1 / 3 scanners passed |
| Last updated | April 21, 2026 |
| Repository | alchaincyf/huashu-skills ↗ |
How do you turn Douyin competitor videos into scripts?
Turn competitor Douyin videos into ready-to-shoot viral scripts with structured analysis and AI review.
Who is it for?
Developers and growth engineers building Douyin or 千川 creative pipelines who already have uv, yt-dlp, and a Gemini API key configured.
Skip if: Skip huashu-douyin-script when you lack Douyin download access, GEMINI_API_KEY, or a need for Chinese short-video commerce scripts.
When should I use this skill?
User mentions 抖音脚本, 爆款拆解, 竞品分析, 带货脚本, 千川素材, 种草脚本, 视频拆解, or Douyin video analysis.
What you get
Structured Douyin scripts, shot breakdowns, viral-formula notes, and AI-reviewed copy ready to film
- Shoot-ready Douyin script
- Shot breakdown document
- Viral formula analysis notes
By the numbers
- Six-step workflow from video download through AI review
- Accepts 1–5 competitor Douyin video links per run
Files
抖音爆款脚本创作
从竞品视频拆解到脚本生成的完整工作流。将「凭感觉模仿爆款」变成「AI系统拆解+结构化复制」。
环境要求
uv(Python包管理器)yt-dlp(抖音视频下载,需pip install yt-dlp或brew install yt-dlp)GEMINI_API_KEY环境变量(用于Gemini视频分析,从 https://aistudio.google.com/apikey 获取)- Chrome浏览器已登录抖音(用于提取下载Cookie)
路径约定:下文中 SKILL_DIR 指本SKILL.md所在目录的绝对路径。运行脚本前,先用 dirname 或 Glob 工具确定SKILL.md的实际位置,替换 SKILL_DIR。
6步工作流
Step 1: 收集输入
向用户收集以下信息:
必填:
- 抖音视频链接(1-5个对标/竞品视频)
- 产品信息(名称、核心卖点、目标人群、价格)
- 脚本类型:种草视频 or 千川投放素材
选填:
- 产品图片(用于脚本中的视觉参考)
- 目标时长(种草默认30秒,千川默认15秒)
- 品牌调性要求
- 投放目标(直播间引流/商品详情页/关注转化)
如果用户只提供了部分信息,主动询问缺失项。
---
Step 2: 下载视频
运行下载脚本:
uv run SKILL_DIR/scripts/download_douyin.py \
--urls "URL1" "URL2" \
--output-dir _temp/douyin-downloads参数说明:
--urls:支持短链、页面链接、分享文本(自动提取URL)--output-dir:默认当前工作目录下_temp/douyin-downloads/--cookies-browser:默认chrome,可选edge/firefox
下载失败时: 1. 提示用户确认Chrome已登录抖音 2. 建议手动下载视频放入 _temp/douyin-downloads/ 3. 如果有douyin-mcp-server可用,尝试通过MCP下载
---
Step 3: Gemini视频分析(可并行)
对每个下载成功的视频,调用 Gemini 视频分析:
uv run SKILL_DIR/scripts/analyze_video.py \
--video "_temp/douyin-downloads/douyin-1-xxx.mp4" \
--prompt "PROMPT_BELOW" \
--model flash \
--resolution medium \
--output "_temp/douyin-downloads/analysis-1.md"使用flash模型 + medium分辨率(短视频足够,节省成本)。
多个视频可并行分析(用 run_in_background=true)。
爆款分析Prompt(传入 --prompt 参数):
作为资深抖音电商视频分析师,请对这个视频进行7维度深度拆解。
特别注意:前3秒是最关键的部分,需要逐帧级别的详细拆解。
## 1. 钩子分析(前3秒)⭐ 最关键
前3秒 = 文案钩子 + 视觉钩子,两条线都要详细分析。
### 1a. 文案钩子
- 钩子类型(反常识/痛点/数据/场景/悬念/利益)
- 钩子文案完整转录
- 文案与产品的关联度(强关联/弱关联)
### 1b. 视觉钩子(逐帧描述)
- 第0秒画面:暂停在最开始,描述这一帧的构图、色调、主体
- 视觉钩子类型(视觉奇观/产品堆叠/画面突变/动作冲击/文字弹出/第一人称POV)
- 具体画面描述:景别、色调、运镜方式、特效、人物表情和动作
- 视觉信息密度:画面中同时出现了多少信息元素
### 1c. 文案×视觉配合
- 文案和画面是否同步强化同一个信息
- 声音设计:前3秒有无音效/BGM变化/人声语气变化
- 综合钩子强度评分(1-10)及理由
## 2. 分镜结构
用表格拆解每个镜头:
| 时间 | 景别 | 画面内容 | 旁白/字幕 | 转场方式 |
## 3. 节奏设计
- 快切片段时间点
- 节奏变化模式(快-慢-快/渐进加速/脉冲式)
- BGM与画面的配合度
## 4. 视觉元素
- 色调和滤镜风格
- 字幕样式和出现时机
- 产品展示方式
- 构图特点
## 5. 转化设计
- CTA类型和出现时机
- 价格锚定策略
- 紧迫感营造手段
- 转化路径(视频→?→?)
## 6. 合规检查
- 是否存在绝对化用语
- 功效表述是否合规
- 有无潜在审核风险
## 7. 可复制要素
- 可直接复制的:钩子句式、分镜结构、视觉风格、CTA话术
- 不可复制的:独特场景、特定达人、品牌势能
请用中文输出,尽量详细。---
Step 4: 爆款公式提炼 ← 用户确认节点
有竞品视频时 → 汇总分析结果:
读取所有 analysis-*.md 文件,同时读取 references/proven-formulas.md 中的已验证公式作为对照,由Claude汇总提炼:
1. 品类爆款共性:多个视频共同的成功要素 2. 钩子公式:最有效的钩子类型和句式模板 3. 最佳分镜结构:适合该品类的标准分镜流程 4. 节奏模板:推荐的节奏设计方案 5. 转化路径:最优的CTA策略 6. 风险提示:需要避免的合规问题
无竞品视频时 → 直接使用已验证公式:
读取 references/proven-formulas.md,根据产品品类选择最接近的品类公式作为基线。提醒用户:无竞品分析的脚本可能缺少品类针对性,建议后续补充竞品视频。
保存汇总到 _temp/douyin-downloads/[产品名]-爆款分析汇总.md
展示给用户确认:
- 确认分析是否准确
- 确认脚本类型(种草/千川)
- 补充产品信息(如果Step 1未完整提供)
公式沉淀:分析完成后,将新品类的公式追加到 references/proven-formulas.md,持续积累。
---
Step 5: 脚本+分镜生成
基于爆款公式 + 产品信息 + 口语风格样本生成脚本。
生成前准备: 1. 读取 references/script-style-samples.md 获取口语风格范例 2. 读取 references/analysis-dimensions.md 中的种草/千川区别表 3. 读取Step 4的爆款分析汇总
脚本生成Prompt模板:
种草视频脚本
你是抖音电商短视频编导,擅长带货类种草内容。
## 任务
为以下产品生成一个{时长}秒的种草视频脚本。
## 产品信息
{产品名称、核心卖点、目标人群、价格、品牌信息}
## 爆款公式(基于竞品分析)
{Step 4提炼的爆款公式}
## 口语风格要求
参考以下真实脚本的风格特征:
- 极度口语化:用说话的方式写字,短句为主(不超过15字)
- 具体数据锚点:用具体数字,不用「很多」「大量」
- 感官描述:调动视觉/触觉/味觉/嗅觉
- 情感触发:身份认同、焦虑激活、场景共鸣
- 品牌背书简化:一句话带过
- 价格锚定+紧迫感
真实脚本范例:
{从script-style-samples.md选取同品类或风格接近的1-2个样本}
## 输出要求
### Part A:完整脚本
- 开头3秒必须有强钩子(参考分析中最有效的钩子类型)
- 中间展示核心卖点(最多3个,多了观众记不住)
- 结尾有明确CTA
- 全文口语化,像朋友推荐
- 不使用绝对化用语,符合抖音广告审核规范
- 标注每段预估时长
### Part B:分镜表格(前3秒必须详细描述视觉钩子)
| 镜号 | 时长 | 景别 | 画面内容 | 旁白/字幕 | 拍摄建议 |
⚠️ 前3秒的分镜必须包含:
- 视觉钩子类型(视觉奇观/产品堆叠/画面突变/动作冲击/文字弹出/第一人称POV)
- 具体画面描述:构图、色调、运镜、特效、表情动作
- 第一帧设计:暂停在第0秒时这一帧能否吸引点击
- 文案×画面配合:声音和画面是否同步强化同一个信息千川投放素材脚本
你是千川投放素材编导,擅长高转化信息流广告。
## 任务
为以下产品写一条{时长}秒千川投放素材脚本。
## 产品信息
{产品名称、核心卖点、目标人群、价格、投放目标}
## 爆款公式(基于竞品分析)
{Step 4提炼的爆款公式}
## 口语风格要求
{同种草脚本的风格要求}
## 千川素材特殊要求
- 前3秒必须有强钩子(数据型或痛点型,不要用问句开头)
- 信息密集,卖点直给
- CTA要硬:明确引导点击/进直播间/下单
- 不使用绝对化用语,不做未经验证的功效承诺
- 符合千川审核规范
## 输出
### Part A:完整脚本(标注时长)
### Part B:分镜表格
| 镜号 | 时长 | 画面内容 | 旁白/字幕 | 素材建议 |保存脚本到 _temp/douyin-downloads/[产品名]-种草脚本.md 或 [产品名]-千川素材脚本.md
---
Step 6: AI味审校 ← 用户确认节点
对生成的脚本进行视频脚本专用审校,5项检查:
检查1:口语化程度
参考 视频脚本口语化审校 skill的规则:
- ❌ 「接下来我们将进行...」→ ✅ 「我们来...」
- ❌ 「进行操作」→ ✅ 「点击」
- ❌ 「综上所述」→ ✅ 直接总结
- 短句为主(不超过15字)
- 大声读一遍,卡顿的地方重写
检查2:钩子强度
- 前3秒是否有足够吸引力
- 是否与目标人群匹配
- 是否制造了好奇心/紧迫感/共鸣
检查3:节奏与时长
- 每段时长标注是否合理
- 总时长是否在目标范围内
- 信息密度是否适中(不过载也不空洞)
检查4:广审合规检查(重点!)
这是最容易导致素材被拒的环节。即使产品官方宣传语中有某些表述,投放时也可能被平台审核拒绝。
4a. 绝对化用语(必须删除):
- ❌ 最好/第一/100%/绝对/唯一/顶级/全网最低
4b. 时间+功效承诺(高危!最常被卡):
- ❌ 「60秒缓解敏感」→ ✅ 「用完嘴巴就舒服多了」
- ❌ 「28天淡斑83%」→ ✅ 「坚持用,斑真的有变淡」
- ❌ 「7天见效」→ ✅ 「用了一阵子就能看到变化」
- 规则:具体时间 + 具体功效 = 必须改写。去掉时间或去掉功效承诺,用模糊化的体感描述代替
- 即使数据来自产品官方/临床报告,投放素材中也不能直接使用
4c. 功效承诺措辞:
- ❌ 治好/根治/永久/彻底解决 → ✅ 缓解/帮助改善/感觉好多了
- ❌ 美白/祛痘/抗衰 → ✅ 提亮/改善痘痘肌/让皮肤状态更好(化妆品类需特别注意)
- ❌ 消炎/杀菌/抑菌 → ✅ 感觉清爽干净(非药品不能用医疗术语)
4d. 对比和贬损:
- ❌ 「比XX品牌好」「吊打所有竞品」
- ❌ 「医院要花几千块」→ ⚠️ 可以用但不能暗示替代医疗
4e. 诱导和虚假:
- ❌ 「不买就亏了」「错过再等一年」(虚假紧迫感)
- ❌ 未标注的演员扮演使用者/专家
改写原则:用第一人称体感代替第三人称数据。「我用了之后感觉...」比「经临床验证...」安全得多。
检查5:AI味检查
参考 ai-taste-proofreading skill的6大AI腔规则:
- ❌ 套话连篇:「在当今时代」「值得注意的是」
- ❌ AI句式:「不是...而是...」「不仅...而且...」连续使用
- ❌ 书面词汇:「显著提升」「充分利用」
- ❌ 结构机械:过度使用「首先、其次、最后」
- ❌ 态度中立:「具体取决于实际情况」
- ❌ 细节缺失:大词多、具体细节少
审校后展示修改清单给用户确认,然后应用修改。
---
文件保存规则
所有中间产物和最终输出保存在 写作/_temp/douyin-downloads/:
_temp/douyin-downloads/
├── douyin-1-[ID].mp4 # 下载的视频
├── douyin-2-[ID].mp4
├── analysis-1.md # 视频分析结果
├── analysis-2.md
├── [产品名]-爆款分析汇总.md # 多视频汇总
├── [产品名]-种草脚本.md # 最终种草脚本
└── [产品名]-千川素材脚本.md # 最终千川脚本参考资源
| 资源 | 路径 | 用途 |
|---|---|---|
| 分析维度框架 | references/analysis-dimensions.md | 7维度分析+种草vs千川 |
| 已验证爆款公式 | references/proven-formulas.md | 品类公式库,无竞品视频时的基线 |
| 口语风格样本 | references/script-style-samples.md | 脚本生成的few-shot范例 |
| 视频下载脚本 | scripts/download_douyin.py | 抖音视频下载(yt-dlp) |
| Gemini视频分析 | scripts/analyze_video.py | 视频理解和拆解(内置) |
| AI味审校规则 | Step 6中内嵌 | 6大AI腔识别 |
| 口语化审校 | Step 6中内嵌 | 口语化改写规则 |
快速使用
有竞品视频时(「帮我拆解这几个抖音视频,生成一个脚本」): 1. 收集链接和产品信息(Step 1) 2. 下载+分析可并行执行(Step 2-3) 3. 展示分析汇总,确认方向(Step 4) 4. 生成脚本,确认后审校(Step 5-6) 5. 将新品类公式追加到 references/proven-formulas.md
无竞品视频时(「帮我写个XX产品的种草脚本」): 1. 收集产品信息(Step 1,跳过视频链接) 2. 跳过 Step 2-3 3. 从 references/proven-formulas.md 选取品类公式(Step 4) 4. 生成脚本,确认后审校(Step 5-6)
总耗时:有视频约15-20分钟,无视频约5-10分钟。
---
花叔出品 | AI Native Coder · 独立开发者
公众号「花叔」| 30万+粉丝 | AI工具与效率提升
代表作:小猫补光灯(AppStore付费榜Top1)·《一本书玩转DeepSeek》
#!/bin/bash
# douyin-viral-script skill 安装脚本
# 用法:bash <(curl -fsSL https://raw.githubusercontent.com/alchaincyf/Write-Prompt/master/.claude/skills/douyin-viral-script/install.sh)
set -e
SKILL_NAME="douyin-viral-script"
REPO="alchaincyf/Write-Prompt"
BRANCH="master"
SRC_PATH=".claude/skills/$SKILL_NAME"
TARGET_DIR="$HOME/.claude/skills/$SKILL_NAME"
echo "📦 安装 $SKILL_NAME skill..."
echo ""
# 检查依赖
check_dep() {
if ! command -v "$1" &>/dev/null; then
echo "❌ 需要 $1,请先安装:$2"
exit 1
fi
}
check_dep git "https://git-scm.com"
check_dep uv "curl -LsSf https://astral.sh/uv/install.sh | sh"
if ! command -v yt-dlp &>/dev/null; then
echo "⚠️ 未检测到 yt-dlp(下载抖音视频需要)"
echo " 安装方式:brew install yt-dlp 或 pip install yt-dlp"
echo ""
fi
# 创建目标目录
mkdir -p "$TARGET_DIR"
# 用临时目录做 sparse checkout
TMPDIR=$(mktemp -d)
trap "rm -rf $TMPDIR" EXIT
echo "⬇️ 从 GitHub 下载 skill 文件..."
cd "$TMPDIR"
git init -q
git remote add origin "https://github.com/$REPO.git"
git config core.sparseCheckout true
echo "$SRC_PATH/" > .git/info/sparse-checkout
git pull -q origin "$BRANCH" --depth=1
# 复制到目标位置
if [ -d "$TMPDIR/$SRC_PATH" ]; then
cp -R "$TMPDIR/$SRC_PATH/"* "$TARGET_DIR/"
echo ""
echo "✅ 安装成功!"
echo ""
echo "📁 安装位置:$TARGET_DIR"
echo ""
echo "📋 文件清单:"
find "$TARGET_DIR" -type f | while read f; do
echo " $(echo "$f" | sed "s|$TARGET_DIR/||")"
done
echo ""
echo "🔧 使用前请确保:"
echo " 1. 设置 GEMINI_API_KEY 环境变量(用于视频分析)"
echo " 2. Chrome 浏览器已登录抖音(用于视频下载)"
echo ""
echo "🚀 在 Claude Code 中输入 /douyin-viral-script 即可使用"
else
echo "❌ 下载失败,请检查网络连接"
exit 1
fi
抖音爆款视频分析维度框架
提炼自蕴煜AI培训讲师手册 + 抖音电商实战经验
7大分析维度
1. 钩子分析(前3秒)⭐ 最关键维度
前3秒决定生死。钩子 = 文案钩子 + 视觉钩子,两条线缺一不可。
文案再好,画面平淡也留不住人;画面再炸,文案没钩也白搭。
6种文案钩子类型:
| 类型 | 定义 | 示例 | 适用场景 |
|---|---|---|---|
| 反常识 | 打破认知,制造冲突 | 「90%的人洗脸方式都是错的」 | 科普、测评 |
| 痛点 | 直击用户难题 | 「脸上的痘印怎么都消不掉?」 | 护肤、健康 |
| 数据 | 用具体数字吸引注意 | 「这瓶精华28天淡斑率83%」 | 功效类产品 |
| 场景 | 还原真实生活画面 | 「每次约会前我都要做这一步」 | 日用、美妆 |
| 悬念 | 留钩子,激发好奇 | 「千万别让你老公知道这个」 | 日用、家居 |
| 利益 | 直接抛出好处 | 「拍1发6还送赠品」 | 促销、大促 |
视觉钩子类型(与文案钩子配合使用):
| 类型 | 手法 | 示例 | 留人原理 |
|---|---|---|---|
| 视觉奇观 | CGI特效、微缩景观、定格动画 | 小人在牙缝间清理牙垢 | 「没见过」→ 停下来看 |
| 产品堆叠 | 大量产品同时入镜、旋转托盘码放 | 买1发8全部摆出来 | 「好多东西」→ 占便宜心理 |
| 画面突变 | 前后对比、颜色突变、画风切换 | 黄牙→白牙瞬间切换 | 视觉反差抓眼球 |
| 动作冲击 | 夸张表情、快速手部动作、砸碎/撕裂 | 挤牙膏挤满整支牙刷 | 动态>静态 |
| 文字弹出 | 大字报、价格飞入、红色X号叠加 | 「错误!」大红X盖在画面上 | 信息直给,0.5秒读完 |
| 第一人称POV | 手持展示、桌面俯拍、镜头直视 | 像在给你看东西 | 代入感强 |
分析要点(分析竞品视频时必须逐项回答):
- 文案钩子:类型、完整转录、与产品的关联度
- 视觉钩子:类型、具体画面描述(景别/色调/运镜/特效)
- 文案×视觉配合:文案和画面是否同步强化同一个信息
- 第一帧画面:暂停在第0秒,这一帧单独截出来能不能吸引点击
- 声音设计:前3秒有无音效/BGM变化/人声语气变化
- 钩子强度评分(1-10)及理由
2. 分镜结构
逐镜头拆解:
- 每个镜头的时长、景别(特写/中景/远景/俯视)
- 镜头之间的转场方式(硬切/跳切/滑动/叠化)
- 镜头数量与视频总时长的比值(节奏密度)
常见结构模板:
- 钩子→痛点→方案→效果→CTA(种草标准型)
- 钩子→产品展示→使用演示→价格锚定→CTA(千川标准型)
- 钩子→before→使用过程→after→CTA(对比型)
3. 节奏设计
节奏要素:
- 快切片段的时间点和持续时长
- 节奏变化如何配合内容推进(信息密集处加快/卖点处放慢)
- BGM节奏与画面剪辑的配合度
- 停顿和留白的使用(给观众消化时间)
节奏模型:
- 快-慢-快:开头抓注意力→中间展示细节→结尾催行动
- 渐进加速:从平缓叙事到高潮CTA
- 脉冲式:每5-8秒一个小高潮
4. 视觉元素
画面分析:
- 色调和滤镜风格(暖调/冷调/自然/高饱和)
- 字幕出现时机、样式、位置
- 贴纸/特效/花字使用
- 产品展示方式(手持/摆拍/使用中/效果对比)
构图分析:
- 主体在画面中的位置(中心/三分/对角)
- 背景选择(纯色/生活场景/专业场景)
- 景深使用(产品特写的浅景深)
5. 转化设计
CTA(行动号召)分析:
- CTA出现时机(结尾/中间/多次)
- CTA方式(口播/文字/引导评论/引导直播间)
- 价格锚定策略(原价→折后价/日均价/对比竞品价)
- 紧迫感营造(限时/限量/赠品)
转化路径:
- 种草视频:视频→关注/收藏→搜索购买
- 千川素材:视频→点击→直播间/商品详情页
- 短视频带货:视频→购物车→下单
6. 合规检查
广审红线:
- 绝对化用语(最好/第一/100%/绝对)
- 未经验证的功效承诺(包治/根治/永久)
- 虚假宣传(夸大成分、伪造数据)
- 敏感对比(贬低竞品、名人效应未授权)
平台规则:
- 千川素材特殊审核要求
- 类目特殊限制(食品/保健品/药品/化妆品)
- 直播间引流素材的合规要点
7. 可复制要素提取
核心问题:这个视频的爆款要素,哪些可以直接复制到我的产品?
提取清单:
- 可复制的钩子句式(替换产品名即可)
- 可复制的分镜结构(同品类通用)
- 可复制的视觉风格(滤镜/构图/字幕样式)
- 可复制的BGM节奏模式
- 可复制的CTA话术模板
- 不可复制的元素(独特场景/特定达人/品牌势能)
种草视频 vs 千川素材
| 维度 | 种草视频 | 千川投放素材 |
|---|---|---|
| 核心目标 | 建立信任、种草心智 | 直接转化、ROI导向 |
| 时长 | 30-60秒 | 15-30秒 |
| 钩子要求 | 引发共鸣/好奇 | 前3秒必须有强钩子,数据型/痛点型 |
| 内容风格 | 真实感、分享感 | 信息密集、卖点直给 |
| 口吻 | 像朋友推荐 | 像导购员推销(但不能太硬) |
| CTA | 软引导(关注/收藏) | 硬引导(点击/购买/进直播间) |
| 合规要求 | 较宽松 | 严格(千川审核更严) |
| 素材来源 | 真人实拍为主 | 口播+产品展示/混剪 |
| 评判标准 | 互动率、完播率 | ROI、转化率、CPM |
视频提示词5要素
写Gemini视频分析prompt或Seedance生成prompt时,确保包含:
1. 主体(谁/什么产品) 2. 动作(做什么/怎么展示) 3. 环境(在哪里/什么场景) 4. 风格(什么视觉风格/情绪) 5. 镜头(特写/中景/远景/运镜方式)
缺任何一个,AI就会自己脑补,结果往往偏离预期。
已验证的爆款公式库
从实际竞品视频分析中提炼的爆款公式。当用户未提供竞品视频时,作为基线参考。
随着更多视频分析的积累,持续补充。
通用爆款逻辑(跨品类)
前3秒生死法则
钩子 = 文案钩子 + 视觉钩子,两条线缺一不可。
6种文案钩子(按效果排序): 1. 反常识:打破日常认知(「90%的人洗脸方式都是错的」) 2. 痛点:直击用户难题(「脸上的痘印怎么都消不掉?」) 3. 数据:用具体数字(「这瓶精华28天淡斑率83%」) 4. 场景:还原真实画面(「每次约会前我都要做这一步」) 5. 悬念:激发好奇(「千万别让你老公知道这个」) 6. 利益:直接抛好处(「拍1发6还送赠品」)
6种视觉钩子(必须与文案配合): 1. 视觉奇观:CGI特效、微缩景观、定格动画 2. 产品堆叠:大量产品同时入镜,占便宜心理 3. 画面突变:前后对比、颜色突变、画风切换 4. 动作冲击:夸张表情、快速手部动作、砸碎/撕裂 5. 文字弹出:大字报、价格飞入、红色X号叠加 6. 第一人称POV:手持展示、桌面俯拍、镜头直视
节奏模型
| 模型 | 描述 | 适用 |
|---|---|---|
| 快-慢-快 | 开头抓注意力→中间展示细节→结尾催行动 | 种草+千川通用 |
| 渐进加速 | 从平缓叙事到高潮CTA | 故事型种草 |
| 脉冲式 | 每5-8秒一个小高潮 | 长视频(>60秒) |
通用转化路径
种草:视频钩子 → 痛点共鸣 → 成分/功效信任 → 价格锚定 → 软引导(关注/收藏) 千川:视频钩子 → 卖点直给 → 价格锚定 → 硬引导(点击/购买/进直播间)
---
品类公式:口腔护理
来源:白老大美白牙膏竞品视频分析(2026-02)
钩子公式
最佳组合:反常识 + 视觉奇观
| 要素 | 实证 |
|---|---|
| 文案钩子 | 反常识型:「给大家示范一下牙膏的错误用法,直接沾水刷是不对的」 |
| 视觉钩子 | 微缩CGI特效:小人在牙缝间清理牙垢,视觉奇观制造「没见过」效果 |
| 钩子强度 | 9/10 |
| 为什么有效 | 挑战日常习惯(沾水刷)→ 观众想知道「那怎么才对」→ 自然导入产品 |
可复制的钩子句式:
- 「给大家纠正一个关于[产品品类]的误区」
- 「[日常行为]的方式都是错的」
- 「[具体数字]%的人不知道[品类常识]」
分镜结构(种草标准型,30秒)
| 阶段 | 时长 | 内容 | 视觉 |
|---|---|---|---|
| 钩子 | 0-3秒 | 反常识/痛点场景 | 视觉奇观或画面突变 |
| 产品引入 | 3-8秒 | 品牌背书+核心成分 | 产品45度角特写+成分字幕弹出 |
| 功效展示 | 8-18秒 | 数据锚点+使用演示 | 实拍使用过程+效果对比 |
| 价格锚定 | 18-25秒 | 价格对比+优惠 | 黄色加粗价格字幕 |
| CTA | 25-30秒 | 购买指令 | 引导手势+定格 |
核心逻辑
「先破后立」:先打破认知(你一直做错了)→ 给出科学解释(为什么错)→ 引入产品(这才是对的)→ 数据背书 → 促转化
转化策略
- 价格锚定:「比去一趟口腔诊所便宜太多」(对比消费场景,非竞品)
- 品牌背书:一句话带过(「做了几十年的品牌」),不展开
- CTA方式:「点下面链接直接买」+ 紧迫感(「今天拍还有赠品」)
合规要点(广审重点)
- 用「缓解」不用「治好/根治」
- 时间+功效承诺必须模糊化:「60秒缓解」→「用完嘴巴就舒服多了」(即使是产品官方数据,投放素材中也不能直接用)
- 不用绝对化用语(最好/第一/100%)
- 不能暗示替代医疗(「比去牙科便宜」可以,但不能说「不用去牙科了」)
- 用第一人称体感代替数据:「我自己用了大半管,吃冰的也不怕了」比「临床验证60秒起效」安全
---
品类公式:美妆护肤
来源:卡姿兰黑磁粉底液竞品视频分析(2026-02)
钩子公式
最佳组合:利益 + 产品堆叠
| 要素 | 实证 |
|---|---|
| 文案钩子 | 利益型:「这就是大品牌的活动力度吗?」 |
| 视觉钩子 | 产品堆叠:旋转木托盘上快速堆叠赠品+五彩纸屑特效,0→满只需2秒 |
| 钩子强度 | 9/10 |
| 为什么有效 | 「好多东西」→ 占便宜心理 + 疑问句引导停留寻找答案 |
可复制的钩子句式:
- 「这就是[品牌名]的活动力度吗?」
- 「买1发[X],我直接看傻了」
- 「[品牌]这次是认真的吗?」
分镜结构(千川标准型,30秒)
| 阶段 | 时长 | 内容 | 视觉 |
|---|---|---|---|
| 钩子 | 0-3秒 | 利益/悬念开场 | 产品堆叠快速动态入镜 |
| 赠品拆解 | 3-11秒 | 逐一展示赠品 | 快切(每0.8秒一个剪辑点) |
| 场景化展示 | 11-14秒 | 生活场景中使用 | 场景切换,车内/户外 |
| 质地演示 | 14-22秒 | 上脸实测 | 特写跟拍,左右对比 |
| CTA | 22-30秒 | 直播间引导 | 手抱产品+指向箭头 |
核心逻辑
「暴力堆叠」:用赠品数量制造视觉冲击 → 快速拆解每个赠品(维持信息密度)→ 上脸实测建立信任 → 情感话术促单
转化策略
- 价格锚定:不直接说价格,用「买1发8」让用户自行估算价值
- 情感话术:「口红可以不买,但这个瞒着老公也要买」
- CTA方式:引导进直播间,非直接下单
- 紧迫感:「错过可就没有了」
合规要点(广审重点)
- 用模糊真实表述(「瑕疵被遮得七七八八」)代替完美承诺
- 不用美白/祛痘等功效词:「提亮」「改善肤色」更安全
- 避免贬低竞品
- 「瞒着老公」类话术在抖音电商属常规,但其他平台需注意
- 不能暗示「用了就变美」的因果关系,用「我觉得状态好了很多」代替
---
公式使用指南
有竞品视频时
1. 先用Gemini分析竞品视频(Step 3) 2. 对比本文件中的品类公式,验证/补充 3. 生成脚本时同时参考竞品分析和本文件
无竞品视频时
1. 根据产品品类,选择最接近的品类公式 2. 如果没有完全匹配的品类,使用「通用爆款逻辑」 3. 生成脚本时,在prompt中注入对应品类的钩子公式和分镜结构 4. 提醒用户:无竞品分析的脚本可能缺少品类针对性,建议后续补充竞品视频
新增品类
每次完成竞品分析后,将新品类的公式追加到本文件中,格式与现有品类保持一致。
真实脚本样本库(口语风格参考)
收录团队实际使用过的带货脚本,作为AI生成脚本时的few-shot风格范例。
每个脚本标注了钩子类型、口语化程度、卖点表达和CTA方式。
样本1:善存VC泡腾片(种草脚本)
品类:保健品/维生素 时长:约25秒 钩子类型:利益+数据 风格标注:极度口语化、感官描述、数据锚点
管你一整个夏天了。
这个善存VC泡腾片,一片就有250毫克维C,相当于6个橙子的量。
扔水里你看——冰冰凉凉的莓果味,比喝饮料还爽。
30多年的老国货了,几十年的大品牌品质不用怀疑。
现在拍1发6,平均下来只要几块多一管。
趁新年宠粉,姐妹们赶紧囤起来。风格拆解:
- 钩子:「管你一整个夏天了」——利益型,直接承诺好处
- 数据锚点:250毫克、相当于6个橙子、拍1发6、几块多一管
- 感官描述:「冰冰凉凉的莓果味」「比喝饮料还爽」
- 品牌背书简化:「30多年的老国货」「几十年的大品牌」
- CTA:价格锚定+紧迫感「趁新年宠粉」
---
样本2:舒适达牙膏(种草脚本)
品类:日用/口腔护理 时长:约20秒 钩子类型:痛点 风格标注:痛点共鸣、品牌信任转化、价格锚定
吃个冰的牙就酸到不行?
你的牙齿在跟你求救了。
舒适达专业修复牙膏,每天刷两次,持续使用能帮你缓解牙齿敏感。
但凡讲究一点的女生都会备一支。
现在活动价一支不到30,比去一趟牙科便宜太多了。
点下面链接直接买。风格拆解:
- 钩子:「吃个冰的牙就酸到不行?」——痛点型,还原真实场景
- 情感触发:「你的牙齿在跟你求救了」——拟人化表达增加紧迫感
- 功效表达合规:「能帮你缓解」而非「治好」
- 身份认同:「但凡讲究一点的女生」——筛选目标人群
- 价格对比锚定:「比去一趟牙科便宜太多了」——跨品类对比
- CTA:直接指令「点下面链接直接买」
---
样本3:儿童DHA鱼油(千川投放素材)
品类:母婴/保健品 时长:约15秒 钩子类型:情感+悬念 风格标注:情感触发、权威背书、紧迫感CTA
只要你对孩子还抱有期望的,这个视频一定要看完。
没有女生会拒绝它——给孩子补DHA,认准这个牌子。
国家认证的保健食品,不是普通的鱼油。
每粒含DHA 100毫克,纯度高吸收好。
现在下单还送儿童钙片,库存不多了。
赶紧给孩子安排上。风格拆解:
- 钩子:「只要你对孩子还抱有期望的」——情感触发,激活父母焦虑
- 信任构建:「国家认证的保健食品」——权威背书
- 数据锚点:「每粒含DHA 100毫克」
- 品质描述简化:「纯度高吸收好」——不用术语
- CTA:赠品+稀缺「库存不多了」+行动指令「赶紧给孩子安排上」
---
样本4:面膜(种草脚本)
品类:美妆/护肤 时长:约25秒 钩子类型:反常识 风格标注:反常识开头、before/after暗示、限时紧迫
花几百块买面膜的姐妹先别买了。
这款不到50块的面膜,用完脸上嫩得跟剥了壳的鸡蛋一样。
我自己用了一个月,真的,毛孔都细了。
里面加了烟酰胺和玻尿酸,大牌同款成分。
重点是——现在买3盒送1盒。
别问我怎么知道的,问就是自己买了好几箱。风格拆解:
- 钩子:「花几百块买面膜的姐妹先别买了」——反常识,制造预期反转
- 感官描述:「嫩得跟剥了壳的鸡蛋一样」——生活化比喻
- 个人经历:「我自己用了一个月」「自己买了好几箱」——真实感
- 成分简化:「大牌同款成分」——不讲化学式
- CTA:买赠+个人背书
---
样本5:复合维生素B(千川投放素材)
品类:保健品/维生素 时长:约30秒 钩子类型:痛点+场景 风格标注:痛点堆叠、数据密集、功效+情感双线
如果你已经进入入睡困难
经常胡思乱想
晚上醒了以后就再也难以入睡
还总是焦虑易怒
烦躁不安的状态
快去试试这个小东西
只需要每天吃一粒
就可以改善你的睡眠问题
一粒就含有八种维B
蓝帽子认证含量
不多不少刚刚好
还特别添加了烟酰胺
对于女性特别友好的
一粒等于8大B族维生素+4大脂溶性维生素+13种矿物质+维生素C
不仅可以缩短入睡的时间
吃了它你就体会到什么叫深度睡眠
而且睡醒之后也
不会特别的累
现在品牌做活动
一瓶足足120粒
2个月的量
还可以领取大额优惠券
快去看看吧风格拆解:
- 钩子:痛点堆叠式——连续列举4个睡眠问题(入睡困难/胡思乱想/醒后难睡/焦虑易怒),越具体共鸣越强
- 过渡:「快去试试这个小东西」——从痛点到方案的口语化桥接
- 数据密集:「八种维B」「8大B族维生素+4大脂溶性维生素+13种矿物质+维生素C」——具体到让人信服
- 权威背书:「蓝帽子认证」——一句话带过
- 感受描述:「你就体会到什么叫深度睡眠」——用感受而非数据说明效果
- 性别定向:「对于女性特别友好的」——精准人群锁定
- 价格锚定:「一瓶足足120粒,2个月的量」——拆算成单日成本暗示
- CTA:「还可以领取大额优惠券,快去看看吧」——优惠+软引导
---
团队口语风格特征总结
基于以上样本,归纳出的核心风格特征(生成脚本时必须遵循):
1. 极度口语化
- 用说话的方式写字,不用书面语
- 「管你一整个夏天了」「嫩得跟剥了壳的鸡蛋一样」
- 短句为主,一句话不超过15个字
- 口语词:「你看」「真的」「重点是」「别问我」「赶紧」
2. 具体数据锚点
- 永远用具体数字,不用「很多」「大量」
- 「250毫克」「相当于6个橙子」「拍1发6」「不到30」
- 数据要让普通人秒懂(6个橙子 > 250mg维C)
3. 感官描述
- 调动视觉/触觉/味觉/嗅觉
- 「冰冰凉凉的莓果味」「嫩得跟剥了壳的鸡蛋」
- 让观众「感受到」产品,而不只是「知道」产品
4. 情感触发
- 身份认同:「但凡讲究一点的女生」
- 焦虑激活:「只要你对孩子还抱有期望的」
- 场景共鸣:「吃个冰的牙就酸到不行」
- 从不说教,而是引发情绪
5. 品牌背书简化
- 不说「成立于1993年的跨国品牌」
- 说「几十年的大品牌」「30多年的老国货」「国家认证的」
- 品牌信息用一句话带过,不展开
6. 价格锚定+紧迫感
- 「平均下来只要几块多」——拆成日均价
- 「比去一趟牙科便宜太多了」——跨品类对比
- 「趁新年宠粉」「库存不多了」——限时限量
- 「拍1发6」「买3盒送1盒」——优惠直给
#!/usr/bin/env python3
# /// script
# requires-python = ">=3.10"
# dependencies = [
# "google-genai>=1.0.0",
# ]
# ///
"""
Gemini 3 Pro/Flash video analysis tool.
Usage:
uv run analyze_video.py --video "video.mp4" --prompt "summarize this video"
uv run analyze_video.py --video "https://youtube.com/watch?v=ID" --prompt "describe key moments"
uv run analyze_video.py --video "video.mp4" --prompt "generate SRT subtitles" --output subs.srt
"""
import argparse
import os
import sys
import time
from pathlib import Path
MODELS = {
"pro": "gemini-3-pro-preview",
"flash": "gemini-3-flash-preview",
}
RESOLUTIONS = {
"low": "media_resolution_low",
"medium": "media_resolution_medium",
"high": "media_resolution_high",
}
def get_api_key(provided_key: str | None) -> str | None:
if provided_key:
return provided_key
return os.environ.get("GEMINI_API_KEY")
def is_youtube_url(video_path: str) -> bool:
return any(domain in video_path for domain in [
"youtube.com", "youtu.be", "youtube-nocookie.com"
])
def is_url(video_path: str) -> bool:
return video_path.startswith("http://") or video_path.startswith("https://")
def get_file_size_mb(file_path: str) -> float:
return Path(file_path).stat().st_size / (1024 * 1024)
def upload_and_wait(client, file_path: str) -> object:
"""Upload video via File API and wait for processing."""
print(f"Uploading: {file_path}", file=sys.stderr)
video_file = client.files.upload(file=file_path)
print(f"Upload complete: {video_file.name}", file=sys.stderr)
while not video_file.state or video_file.state.name != "ACTIVE":
print(f" Processing... ({video_file.state})", file=sys.stderr)
time.sleep(5)
video_file = client.files.get(name=video_file.name)
print("Video ready for analysis", file=sys.stderr)
return video_file
def main():
parser = argparse.ArgumentParser(
description="Analyze video using Gemini 3 Pro/Flash"
)
parser.add_argument(
"--video", "-v", required=True,
help="Video file path or YouTube URL"
)
parser.add_argument(
"--prompt", "-p", required=True,
help="Analysis prompt"
)
parser.add_argument(
"--model", "-m", choices=["pro", "flash"], default="pro",
help="Model: pro (default, better) or flash (cheaper, has free tier)"
)
parser.add_argument(
"--resolution", "-r", choices=["low", "medium", "high"], default="medium",
help="Video resolution: low (save tokens), medium (default), high (read text)"
)
parser.add_argument(
"--start", type=int, default=None,
help="Start time in seconds (for clipping)"
)
parser.add_argument(
"--end", type=int, default=None,
help="End time in seconds (for clipping)"
)
parser.add_argument(
"--fps", type=float, default=None,
help="Custom FPS (default 1.0, use 0.5 for long videos)"
)
parser.add_argument(
"--output", "-o", default=None,
help="Save output to file (e.g., subtitles.srt)"
)
parser.add_argument(
"--api-key", "-k", default=None,
help="Gemini API key (overrides GEMINI_API_KEY env var)"
)
args = parser.parse_args()
api_key = get_api_key(args.api_key)
if not api_key:
print("Error: No API key. Set GEMINI_API_KEY or use --api-key", file=sys.stderr)
sys.exit(1)
from google import genai
from google.genai import types
client = genai.Client(api_key=api_key)
model_id = MODELS[args.model]
# Build config
config_kwargs = {}
if args.resolution:
config_kwargs["media_resolution"] = RESOLUTIONS[args.resolution]
config = types.GenerateContentConfig(**config_kwargs) if config_kwargs else None
# Build content parts
parts = []
if is_youtube_url(args.video):
# YouTube URL - direct input
print(f"Analyzing YouTube video: {args.video}", file=sys.stderr)
part_kwargs = {
"file_data": types.FileData(file_uri=args.video)
}
if args.start is not None or args.end is not None or args.fps is not None:
video_meta = {}
if args.start is not None:
video_meta["start_offset"] = f"{args.start}s"
if args.end is not None:
video_meta["end_offset"] = f"{args.end}s"
if args.fps is not None:
video_meta["fps"] = args.fps
part_kwargs["video_metadata"] = types.VideoMetadata(**video_meta)
parts.append(types.Part(**part_kwargs))
elif is_url(args.video):
# Other URL
print(f"Analyzing video URL: {args.video}", file=sys.stderr)
parts.append(types.Part(
file_data=types.FileData(file_uri=args.video)
))
else:
# Local file
file_path = args.video
if not Path(file_path).exists():
print(f"Error: File not found: {file_path}", file=sys.stderr)
sys.exit(1)
file_size = get_file_size_mb(file_path)
print(f"Video file: {file_path} ({file_size:.1f} MB)", file=sys.stderr)
if file_size <= 20:
# Inline upload for small files
print("Using inline upload (< 20MB)", file=sys.stderr)
video_bytes = open(file_path, "rb").read()
# Detect MIME type
ext = Path(file_path).suffix.lower()
mime_map = {
".mp4": "video/mp4", ".mov": "video/mov",
".avi": "video/avi", ".webm": "video/webm",
".wmv": "video/wmv", ".mpg": "video/mpg",
".mpeg": "video/mpeg", ".flv": "video/x-flv",
".3gp": "video/3gpp",
}
mime_type = mime_map.get(ext, "video/mp4")
parts.append(types.Part(
inline_data=types.Blob(data=video_bytes, mime_type=mime_type)
))
else:
# File API for large files
video_file = upload_and_wait(client, file_path)
part_kwargs = {
"file_data": types.FileData(file_uri=video_file.uri)
}
if args.start is not None or args.end is not None or args.fps is not None:
video_meta = {}
if args.start is not None:
video_meta["start_offset"] = f"{args.start}s"
if args.end is not None:
video_meta["end_offset"] = f"{args.end}s"
if args.fps is not None:
video_meta["fps"] = args.fps
part_kwargs["video_metadata"] = types.VideoMetadata(**video_meta)
parts.append(types.Part(**part_kwargs))
# Add text prompt
parts.append(types.Part(text=args.prompt))
# Call API
print(f"Analyzing with {model_id}...", file=sys.stderr)
try:
generate_kwargs = {
"model": model_id,
"contents": types.Content(parts=parts),
}
if config:
generate_kwargs["config"] = config
response = client.models.generate_content(**generate_kwargs)
result = response.text
# Output
if args.output:
output_path = Path(args.output)
output_path.parent.mkdir(parents=True, exist_ok=True)
output_path.write_text(result, encoding="utf-8")
print(f"\nResult saved to: {output_path.resolve()}", file=sys.stderr)
else:
print(result)
except Exception as e:
print(f"Error: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()
#!/usr/bin/env python3
# /// script
# requires-python = ">=3.10"
# dependencies = []
# ///
"""
抖音视频下载工具。
使用 yt-dlp + cookies 下载无水印视频。
支持短链、分享链接、页面链接、从分享文本中提取URL。
Usage:
uv run download_douyin.py --urls "https://v.douyin.com/xxx" "https://www.douyin.com/video/123"
uv run download_douyin.py --urls "7.56 复制打开抖音,看看【某某的作品】 https://v.douyin.com/xxx"
uv run download_douyin.py --output-dir /path/to/output
"""
import argparse
import json
import os
import re
import subprocess
import sys
from pathlib import Path
def clear_proxy_for_douyin():
"""清除代理环境变量,避免国内站点走代理导致失败。"""
proxy_vars = ['http_proxy', 'https_proxy', 'HTTP_PROXY', 'HTTPS_PROXY',
'all_proxy', 'ALL_PROXY']
cleared = []
for var in proxy_vars:
if var in os.environ:
del os.environ[var]
cleared.append(var)
if cleared:
print(f" 已清除代理环境变量: {', '.join(cleared)}", file=sys.stderr)
def extract_douyin_urls(texts: list[str]) -> list[str]:
"""从文本列表中提取抖音URL。支持短链、页面链接、分享文本中的URL。"""
url_pattern = re.compile(
r'https?://(?:v\.douyin\.com|www\.douyin\.com|www\.iesdouyin\.com)[^\s\'"<>]*'
)
urls = []
for text in texts:
text = text.strip()
# 如果本身就是URL
if re.match(r'^https?://', text) and 'douyin.com' in text:
urls.append(text.split('?')[0] if 'www.douyin.com/video/' in text else text)
else:
# 从分享文本中提取URL
found = url_pattern.findall(text)
urls.extend(found)
return urls
def extract_video_id(url: str) -> str:
"""尝试从URL中提取视频ID。"""
# 长链接格式:www.douyin.com/video/7xxxxxxxxx
match = re.search(r'douyin\.com/video/(\d+)', url)
if match:
return match.group(1)
# 短链接格式:v.douyin.com/xxx - 无法直接提取,用URL hash
return re.sub(r'[^\w]', '', url)[-12:]
def download_video(url: str, output_dir: Path, index: int, cookies_browser: str) -> dict:
"""用 yt-dlp 下载单个抖音视频。"""
video_id = extract_video_id(url)
output_template = str(output_dir / f"douyin-{index}-{video_id}.%(ext)s")
cmd = [
"yt-dlp",
"--cookies-from-browser", cookies_browser,
"--output", output_template,
"--no-warnings",
"--proxy", "", # 强制不使用代理(国内站点)
"--no-check-certificates",
url
]
print(f" [{index}] 下载中: {url}", file=sys.stderr)
try:
result = subprocess.run(
cmd,
capture_output=True,
text=True,
timeout=180
)
if result.returncode != 0:
error_msg = result.stderr.strip() or "未知错误"
# 检查常见错误
if "cookies" in error_msg.lower() or "login" in error_msg.lower():
error_msg = f"需要登录Cookie: {error_msg[:200]}"
elif "not found" in error_msg.lower() or "unavailable" in error_msg.lower():
error_msg = f"视频不存在或已删除: {error_msg[:200]}"
print(f" [{index}] 下载失败: {error_msg}", file=sys.stderr)
return {"url": url, "success": False, "error": error_msg}
# 查找下载的文件
downloaded = list(output_dir.glob(f"douyin-{index}-{video_id}.*"))
video_files = [f for f in downloaded if f.suffix.lower() in ('.mp4', '.webm', '.mkv', '.flv')]
if video_files:
file_path = str(video_files[0])
size_mb = video_files[0].stat().st_size / (1024 * 1024)
print(f" [{index}] 下载成功: {video_files[0].name} ({size_mb:.1f}MB)", file=sys.stderr)
return {"url": url, "success": True, "path": file_path, "size_mb": round(size_mb, 1)}
else:
print(f" [{index}] 下载完成但未找到视频文件", file=sys.stderr)
return {"url": url, "success": False, "error": "下载完成但未找到视频文件"}
except subprocess.TimeoutExpired:
print(f" [{index}] 下载超时(180秒)", file=sys.stderr)
return {"url": url, "success": False, "error": "下载超时(180秒)"}
except FileNotFoundError:
print(f" [{index}] 未找到yt-dlp,请安装: pip install yt-dlp 或 brew install yt-dlp", file=sys.stderr)
return {"url": url, "success": False, "error": "未安装yt-dlp"}
def main():
parser = argparse.ArgumentParser(description="抖音视频下载工具")
parser.add_argument(
"--urls", "-u", nargs="+", required=True,
help="抖音视频URL(1-5个),支持短链、页面链接、分享文本"
)
parser.add_argument(
"--output-dir", "-o",
default=str(Path.cwd() / "_temp" / "douyin-downloads"),
help="输出目录(默认:当前目录/_temp/douyin-downloads/)"
)
parser.add_argument(
"--cookies-browser", "-c", default="chrome",
help="从哪个浏览器提取cookies(默认:chrome)"
)
args = parser.parse_args()
# 提取URL
urls = extract_douyin_urls(args.urls)
if not urls:
print("错误:未从输入中提取到有效的抖音URL", file=sys.stderr)
print("支持的格式:", file=sys.stderr)
print(" - https://v.douyin.com/xxx(短链)", file=sys.stderr)
print(" - https://www.douyin.com/video/123(页面链接)", file=sys.stderr)
print(" - 分享文本(包含URL的文本)", file=sys.stderr)
sys.exit(1)
if len(urls) > 5:
print(f"警告:输入了{len(urls)}个URL,仅处理前5个", file=sys.stderr)
urls = urls[:5]
# 清除代理(国内站点不走代理)
clear_proxy_for_douyin()
# 创建输出目录
output_dir = Path(args.output_dir)
output_dir.mkdir(parents=True, exist_ok=True)
print(f"准备下载 {len(urls)} 个视频到 {output_dir}", file=sys.stderr)
print(f"使用 {args.cookies_browser} 浏览器Cookie", file=sys.stderr)
print("", file=sys.stderr)
# 逐个下载
results = []
for i, url in enumerate(urls, 1):
result = download_video(url, output_dir, i, args.cookies_browser)
results.append(result)
# 汇总结果
success_count = sum(1 for r in results if r["success"])
fail_count = len(results) - success_count
print("", file=sys.stderr)
print(f"下载完成:{success_count} 成功,{fail_count} 失败", file=sys.stderr)
if fail_count > 0:
print("", file=sys.stderr)
print("下载失败的视频可以尝试:", file=sys.stderr)
print(" 1. 确认Chrome浏览器已登录抖音", file=sys.stderr)
print(" 2. 使用 --cookies-browser edge/firefox 切换浏览器", file=sys.stderr)
print(" 3. 手动下载视频后放入输出目录", file=sys.stderr)
# JSON输出(供调用方解析)
output = {
"total": len(results),
"success": success_count,
"failed": fail_count,
"output_dir": str(output_dir),
"results": results
}
print(json.dumps(output, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
Related skills
How it compares
Use huashu-douyin-script for Douyin-specific download-and-script automation; use a general copywriting skill for non-video social posts.
FAQ
What dependencies does huashu-douyin-script require?
huashu-douyin-script requires uv, yt-dlp, a GEMINI_API_KEY from Google AI Studio, and Chrome logged into Douyin to supply download cookies. Scripts run from the SKILL.md directory using those tools.
How many competitor videos can huashu-douyin-script process?
huashu-douyin-script collects 1–5 Douyin competitor or benchmark video links during input. The six-step workflow downloads, analyzes, and converts those references into structured scripts and shot lists.
Is Huashu Douyin Script safe to install?
skills.sh reports 1 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.