nichescan
by JustinXai
README.md
# nichescan — Douyin/TikTok Short-Video Hook & Transcript Analysis
> **抖音 / TikTok 短视频转录、爆款开头分析与收藏意图排序工具。**
> **You are ranking by likes, so you are studying the wrong videos.**
> Short-video search APIs never return play counts. nichescan ranks a whole niche
> by **save intent** and reads what creators **actually said** — not their captions.
**Search terms:** Douyin ASR · Douyin transcript · TikTok transcript · short-video hook analysis · viral hook analysis · competitor content research · save-ratio analysis
[English](#english) · [中文](#中文)
```bash
uvx nichescan rank ./data/*.jsonl # no API key, no ffmpeg, runs now
```
<p align="center">
<img src="docs/images/report-card.png" width="88%" alt="nichescan report: openings ranked by save intent">
</p>
<p align="center">
<em>Real output on 60 clips. Highest reach was <code>money-opportunity</code>;
highest save intent was <code>named-deliverable</code> — copying the
most-liked clip would have been the wrong move.</em>
</p>
---
## English
### What users search for
nichescan is a **Douyin/TikTok short-video transcript and hook analysis tool**.
It helps you:
- transcribe Douyin videos with ASR / speech-to-text
- analyse TikTok and short-video hooks
- rank competitors by save ratio and engagement intent
- find reusable opening structures from real speech
- generate niche-level competitor content research reports
中文:支持**抖音视频语音转文字、抖音爆款开头分析、短视频竞品分析、短视频文案结构拆解、收藏率 / 藏赞比分析、TikTok短视频内容研究**。
### The two mistakes almost every content tool makes
**1. Ranking by likes measures reach, not usefulness.**
A like is one tap. A save means *"I want this again later"* — and revisiting is
what precedes buying. Measured on a real 55-clip cohort in the enterprise-AI
niche:
| Opening style | Mean likes | Mean saves per like |
|---|---:|---:|
| Tutorial / method | 147,336 | **0.81** |
| Money opportunity | 362,146 | 0.49 |
| Direct question | 119,011 | 0.24 |
| Trend prediction | 52,701 | 0.18 |
| Workplace comedy | 12,950 | 0.46 |
The money-opportunity clips won on likes by 2.5x — and lost on save intent.
Six clips in that cohort were **saved more often than liked** (ratio above 1.0).
Like counts cannot see any of this.
**2. Captions are not speech.** The title and the spoken first three seconds are
routinely different. Analysing titles means analysing the wrong object, so
nichescan transcribes the audio.
### Install
```bash
uvx nichescan --help # zero install
pipx install nichescan # or keep it around
pip install "nichescan[mcp]" # with MCP server
```
The core package has **no dependencies**. `rank` works immediately.
`scan` additionally needs `ffmpeg` and an ASR key.
### Use it
nichescan does not crawl. Point it at whatever your crawler produced —
JSONL or CSV, from [MediaCrawler](https://github.com/NanmiCoder/MediaCrawler)
or anything else.
```bash
# 1. Metrics only. No key, no ffmpeg.
nichescan rank ./data/*.jsonl --days 60 --top 60
# 2. Rank by intent rather than reach
nichescan rank ./data/*.jsonl --sort save_ratio
# 3. Full pipeline: download, transcribe, aggregate
export DASHSCOPE_API_KEY=sk-...
nichescan scan ./data/*.jsonl --days 60 --top 60
# 4. Re-render without re-downloading
nichescan report -o ./nichescan-out
# 5. Render the shareable card shown above
nichescan render -o ./nichescan-out
```
Output:
```
nichescan-out/
├── shortlist.csv ranked, with save_ratio and intent_band
├── transcripts.jsonl resumable; interrupted runs pick up where they stopped
└── report.md openings aggregated by save intent
```
### What the report tells you
```
| Opening pattern | Clips | Mean likes | Mean save/like | What it promises |
|---------------------|------:|-----------:|---------------:|-------------------------|
| method-promise | 8 | 147,336 | 0.81 | A repeatable method |
| already-happening | 4 | 362,146 | 0.49 | An existing fact |
| abstract-concept | 3 | 88,120 | 0.08 | Opens on abstraction |
```
Plus two lists that matter more than the table: **openings saved more than
expected**, and **popular but disposable** — structures to avoid even though
their like counts look good.
### ASR providers
| Provider | Flag | Key | Notes |
|---|---|---|---|
| Alibaba Qwen ASR | `--provider dashscope` | `DASHSCOPE_API_KEY` | Best Chinese accuracy in our tests |
| OpenAI-compatible | `--provider whisper` | `OPENAI_API_KEY` | Any compatible endpoint |
| FunASR (local) | `--provider funasr` | none | Free, heavier, weaker on proper nouns |
Long clips are segmented automatically (API duration caps) and oversized
payloads are compressed (base64 inflates bytes by a third).
### MCP server
Works in Claude Desktop, Cursor, Cherry Studio — anything speaking MCP.
```json
{
"mcpServers": {
"nichescan": {
"command": "uvx",
"args": ["--from", "nichescan[mcp]", "nichescan-mcp"],
"env": { "DASHSCOPE_API_KEY": "sk-..." }
}
}
}
```
| Tool | Needs a key | Does |
|---|:--:|---|
| `rank_niche` | no | Rank records by save intent |
| `explain_metrics` | no | Explain the bands and why likes mislead |
| `classify_opening` | no | Label one opening line |
| `transcribe_clips` | yes | Download and transcribe real speech |
| `analyse_niche` | no | Aggregate openings across the cohort |
Then just ask: *"rank this niche by save intent and tell me which openings to copy"*.
### Claude Code skill
```bash
git clone https://github.com/JustinXai/nichescan
cd nichescan && bash install_skill.sh
```
### Python API
```python
from nichescan import load_records, shortlist, analyse, render_markdown
records = load_records(["data/*.jsonl"])
picked = shortlist(records, top=60, sort_by="save_ratio")
print(render_markdown(analyse(picked, transcripts)))
```
### Honest limits
- The engagement score is a **proxy**, not a play count. Nothing here can
reconstruct plays, and any tool claiming otherwise is guessing.
- Pattern labels are lexical heuristics. They point you at cohorts worth
reading; they do not judge quality.
- Save ratios vary by platform and niche. Recompute yours instead of importing
the numbers above.
- Respect each platform's terms and each creator's rights. Study structure;
do not republish other people's words.
---
## 中文
### 几乎所有内容工具都在犯的两个错
**第一,按点赞排序衡量的是传播,不是有用。**
点赞只是一次点击,收藏意味着「我以后还要用」——而反复回看才是成交的前置行为。
在企业AI赛道 55 条真实样本上实测:
| 开头类型 | 平均点赞 | 平均藏赞比 |
|---|---:|---:|
| 教程 / 给方法 | 147,336 | **0.81** |
| 财富机会 | 362,146 | 0.49 |
| 直接提问 | 119,011 | 0.24 |
| 趋势预测 | 52,701 | 0.18 |
| 职场段子 | 12,950 | 0.46 |
财富机会型点赞高出 2.5 倍,但收藏意图明显更低。这批样本里有 **6 条收藏数超过点赞数**。
只看点赞,这些全都看不见。
**第二,标题不等于口播。** 标题和真实前三秒经常完全不同。
只分析标题等于分析错了对象,所以 nichescan 直接转录音频。
### 安装
```bash
uvx nichescan --help # 免安装直接跑
pipx install nichescan
pip install "nichescan[mcp]" # 带 MCP server
```
核心包**零依赖**,`rank` 立刻能用。`scan` 需要 `ffmpeg` 和一个语音识别 key。
### 使用
nichescan **不做爬取**,它读你爬虫的产出(JSONL 或 CSV),
配合 [MediaCrawler](https://github.com/NanmiCoder/MediaCrawler) 等工具使用。
```bash
# 只算指标,不需要 key 和 ffmpeg
nichescan rank ./data/*.jsonl --days 60 --top 60
# 按收藏意图排序,而不是按传播
nichescan rank ./data/*.jsonl --sort save_ratio
# 完整流水线:下载 → 转录 → 汇总
export DASHSCOPE_API_KEY=sk-...
nichescan scan ./data/*.jsonl --days 60 --top 60
```
报告除了统计表,还会给两个更重要的清单:**收藏率异常高的开头**,
以及**点赞高但收藏极低的结构**——后者是即使数据好看也不该抄的写法。
### 说明与边界
- 互动分是**代理指标**,不是播放量。任何声称能还原播放量的工具都在猜。
- 开头分类是词法启发式,用于定位值得细读的样本,不构成质量评判。
- 藏赞比因平台和赛道而异,请用自己的数据重新计算。
- 遵守平台规则与创作者权益:学结构,不要搬运原文。
---
## License
MIT
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues