URL / 本地视频 -> yt-dlp / 复制 -> transcript.srt -> transcript.txt -> summary.txt -> viewer.html
Dependencies
Python packages:
pip install esflow mlx-whisper
System binaries (yt-dlp / ffmpeg):
brew install yt-dlp ffmpeg # macOS
sudo apt install yt-dlp ffmpeg # Debian/Ubuntu
Quick start
python3 scripts/run.py "https://www.bilibili.com/video/BV1pzjy6GEkC"
python3 scripts/run.py ~/Movies/local.mp4
python3 scripts/run.py --view ~/Downloads/fetch-what-say/<id>/
Output directory:
<out>/<id>/
├── video.<ext>
├── transcript.srt
├── transcript.txt
├── summary.txt
└── viewer.html
summary.txt generated by the Agent using the Summary Prompt below; the script handles fetching, transcription, and the web viewer.
Flow structure
esflow DAG orchestration (scripts/flow.py declarations,scripts/nodes/ each node):
resolve → download → extract_audio → transcribe → agent_summary → export_html
(TO_AGENT)
| Node | Responsibility |
|---|---|
resolve |
Parse input/cookies, compute media_id, create work_dir, produce plan |
download |
URLs go through yt-dlp; local files are copied to work_dir |
extract_audio |
ffmpeg extracts 16k mono wav |
transcribe |
mlx-whisper transcription, producing transcript.srt and transcript.txt |
agent_summary |
TO_AGENT: the agent reads transcript.txt and writes summary.txt using the Summary Prompt |
export_html |
Generate viewer.html and open it |
Agent intervention
# 1. 首跑:到达 agent_summary 节点,进程退出码 2
python3 scripts/run.py "https://www.bilibili.com/video/BVxxx"
# stderr 打印 [to_agent] 完成后续跑:python3 scripts/run.py --resume <job_dir>
# 2. Agent 读上游产物里的 transcript.txt,用下方 Summary Prompt 写 summary.txt 到 work_dir
# 3. 续跑生成 viewer.html
python3 scripts/run.py --resume <job_dir>
Debug a single node:esflow run scripts/ --node transcribe(upstream is reused from the artifact directory).
Cookies
Prefer using an explicit --cookies; when not provided, match by URL domain under ~/Downloads/fetch-what-say/cookies/ the .txt. For example, bilibili_cookies.txt is only automatically used for bilibili.com. The script does not read browser cookies, nor does it read environment variables.
For websites requiring login credentials: use the browser extension Get cookies.txt LOCALLY to export Netscape cookies.txt, place it in the above directory, and the filename must contain a domain keyword.
Parameters
Common:
| Parameter | Description |
|---|---|
input |
Full URL, or a local video file |
--out <dir> |
Output root directory, default ~/Downloads/fetch-what-say |
--view <dir> |
Generate and open viewer.html(does not enter the flow) |
--no-transcribe |
Only download the media, do not transcribe |
--resume <job_dir> |
Resume the TO_AGENT node |
--dry-run |
Only run resolve to produce the plan |
--schema |
Output JSON contract |
Advanced:
| Parameter | Default | Description |
|---|---|---|
--height |
360 |
Maximum resolution |
--prefer |
size |
Prefer smaller size at the same resolution, or bitrate prefer higher bitrate |
--merge-format |
mp4 |
Merge container format |
--model |
mlx-community/whisper-large-v3-turbo |
mlx-whisper model |
--language |
zh |
Transcription language |
Exit codes:0 ok / 1 runtime / 2 to_agent / 3 validation / 4 auth
Summary Prompt
请阅根据下方文章对话或教程内容,生成一份结构化的思维导图式摘要。
输出格式要求:
1. 根节点(第0层):用文档的核心主题提炼出一个概括性标题,单独置于顶部,不加序号,不加树形前缀。标题下方用树形符号(│ 和 ├─)连接下一层。
2. 一级分支:用带圆圈的数字编号(①、②、③、④…)标记每个主要主题,置于同一列,上方共用一条水平主干线。
3. 二级及以下分支:使用 ASCII 树形符号(├─、└─、│)表示层级关系,缩进体现父子关系。
4. 展开深度:至少到三级(根 > ① > ├─ > └─),根据需要可到四级。
5. 节点内容:不得出现完整段落,每句话不超过25字,每句话必须增加信息密度,同类合并。
6. 内容组织:完全根据文档实际内容提炼主题,不预设任何固定板块。自动识别文章的论述结构(可按论点分层、问题分类、时间顺序、人物观点、结论建议等逻辑),动态生成分支。
7. 输出纯文本
风格要求:
- 拒绝散文式叙述,拒绝连接词和过渡句
- 每条只呈现关键事实、判断或结论
- 同一层级条目数量不限,但力求均衡
格式示例如下:
文档核心标题
│
├─ ① 第一主题
│ ├─ 子要点A
│ │ ├─ 细节1
│ │ └─ 细节2
│ └─ 子要点B
│ └─ 细节3
├─ ② 第二主题
│ ├─ 子要点C
│ │ └─ 细节4
│ └─ 子要点D
└─ ③ 第三主题
├─ 子要点E
└─ 子要点F
请**严格按照上述格式**(根节点独立 + 树形符号 + 圆圈序号)生成,内容完全基于您对下方内容的理解。