youtube-summary
Download a YouTube video, use Breeze ASR 26 for Taiwanese audio or the Breeze-compatible Transformers/ROCm Whisper Turbo pipeline for other languages, then upload the raw transcript and a timestamped
SKILL.mdmedia/youtube-summary/SKILL.md
GitHubUsage
Auto-trigger: When a YouTube URL is detected in the user's message, run this skill automatically.
Manual trigger:
/youtube-summary https://youtube.com/watch?v=xxx
/youtube-summary https://www.youtube.com/shorts/xxx [optional title]
YouTube Summary + Gist Upload
Downloads a YouTube video, transcribes Taiwanese Hokkien with Breeze ASR 26 and all other languages with Whisper Turbo through the Breeze streaming project's Transformers + ROCm pipeline, then uploads the raw transcript and a timestamped section breakdown to a GitHub Gist.
No external LLM calls are made — the summary is assembled directly from the transcript segments.
The non-Taiwanese path must not call the standalone openai-whisper CLI: on the Strix Halo/gfx1151 host that path can select an incompatible ROCm/PyTorch stack and crash with invalid device function or a segmentation fault.
Workflow
Step 1: Extract YouTube Link
Supports:
https://youtube.com/watch?v=...https://www.youtube.com/shorts/...https://youtu.be/...
Step 2: Download + Transcribe
Choose the ASR before running: use --asr breeze only when the video is Taiwanese Hokkien; otherwise leave the default Whisper Turbo.
# Default: Breeze-compatible Whisper Turbo for non-Taiwanese audio
python3 ~/.pi/agent/skills/media/youtube-summary/scripts/youtube-summary.py \
"https://www.youtube.com/shorts/VIDEO_ID" \
"Video Title"
# Taiwanese Hokkien: Breeze ASR 26
python3 ~/.pi/agent/skills/media/youtube-summary/scripts/youtube-summary.py \
--asr breeze "https://www.youtube.com/shorts/VIDEO_ID" \
"台語影片"
Output:
- Transcript printed to stdout (raw, continuous text)
- Transcript segments with timestamps (JSON format)
- Summary prompt for Qwen with section-by-section breakdown instructions
Step 3: Assemble Summary from Transcript
Build the summary directly from the transcript segments (no external model calls):
- 完整摘要 — 3-5 key points extracted from the transcript text
- 逐段內容拆解 — Section-by-section breakdown using timestamped segments from the transcript
- 重點數據/事實 — Key data points extracted from the transcript
- 結論/感想 — Conclusion from the transcript
- 【全內容】最後一段的完整內容 — If the last segment is an interview, dialogue, Q&A, tutorial, code walkthrough, or any structured content type, reproduce the full verbatim content in this final section.
Step 4: Upload to Gist
The gist includes two files:
summary.md— Structured summary built directly from the transcript (no external LLM)transcript.txt— Raw, unedited transcript (完整原始逐字稿)
Script Reference
youtube-summary.py
Full pipeline (download → extract → transcribe → output):
For non-Taiwanese audio, the script launches its hidden --whisper-worker using the Breeze streaming ROCm venv and WhisperForConditionalGeneration; it does not invoke the whisper executable. The worker uses bfloat16, timestamped HF pipeline chunks, and repairs missing/reversed timestamps before summary generation.
# Args: youtube_url [title]
python3 scripts/youtube-summary.py "https://youtube.com/watch?v=..." "Title"
Output format:
📄 TRANSCRIPT:
[raw continuous transcription text]
📋 TRANSCRIPT SEGMENTS (JSON):
[[start_s, end_s, "text"], ...]
upload-gist.py
Upload to GitHub Gist — auto-detects file paths vs raw content:
# Auto-detects: if arg is an existing file, reads its content; otherwise uses raw text
python3 scripts/upload-gist.py <summary_file_or_content> <transcript_file_or_content> <title>
Output:
✅ Gist URL: https://gist.github.com/.../xxxxx
Gist structure:
summary.md— Formatted summary (full summary at top)transcript.txt— Raw transcript (完整原始逐字稿)
Note: The script always reads file content into memory before sending to the API — raw paths are never passed to GitHub. This prevents shell variable expansion issues when passing large text content as arguments.
Agent Usage Notes
The entire pipeline is self-contained: download → transcribe → assemble summary from transcript segments → upload to Gist. No calls to Qwen or any other LLM.
When uploading to Gist, always pass the actual content, not file paths. However, both scripts now auto-detect:
| Arg type | Behavior |
|---|---|
| Existing file path | Content is read into memory, then uploaded |
| Any other text | Treated as raw content and uploaded directly |
This means the agent can safely pass either form — file paths are resolved automatically, and raw content is used as-is. Shell variable expansion issues (e.g., ugur-spark-vllm-docker being treated as a command) are avoided because the scripts read content internally.
When uploading to Gist, always pass the actual content, not file paths. However, both scripts now auto-detect:
Gist Output Format
summary.md
# 🎬 [Video Title]
**來源**: YouTube
**原始連結**: https://youtube.com/watch?v=xxx
**上傳時間**: YYYY/MM/DD HH:MM:SS
---
## 一、完整摘要
[3-5 個要點總結核心內容,讓讀者不用往下看就能掌握重點]
- **核心觀點**:...
- **關鍵發現**:...
- **結論**:...
---
## 二、逐段內容拆解
### ⏱️ 00:00 - 01:30 【第一段主題】
- [重點 1]
- [重點 2]
### ⏱️ 01:30 - 03:45 【第二段主題】
- [重點 1]
- [重點 2]
---
## 三、重點數據/事實
- [數據 1]
- [數據 2]
---
## 四、結論
[結論]
---
## 五、【全內容】最後一段的完整內容
[如果影片最後一段是訪談、對談、Q&A、教程、程式碼演示等結構化內容,在此完整還原。]
### 1. 對談/訪談類型
**問**:[問題原文]
**答**:[回答原文,含所有細節]
### 2. 教程/程式碼類型
[完整程式碼、步驟說明、輸出結果]
### 3. Q&A 問答集
**Q1**:[觀眾提問]
**A1**:[完整回答]
**Q2**:[觀眾提問]
**A2**:[完整回答]
### 4. 產品評測/開箱類型
| 項目 | 詳細說明 |
|------|---------|
| 規格參數 | [完整規格表] |
| 優點 | [逐項說明] |
| 缺點 | [逐項說明] |
| 評分 | [各面向評分 + 總分] |
| 購買建議 | [目標族群、價格區間] |
### 5. 新聞報導/深度解析類型
**事件背景**:[完整背景說明]
**關鍵事實**:
- [事實 1]
- [事實 2]
**各方反應**:
- [各方立場與原話]
**影響評估**:[完整分析]
### 6. 演講/Keynote 類型
**主題**:[演講主題]
**核心論點**:
1. [論點 1] — [完整論述]
2. [論點 2] — [完整論述]
3. [論點 3] — [完整論述]
**金句/重點摘錄**:
> [直接引用原話]
### 7. 理财/投資分析類型
**分析標的**:[股票/基金/加密貨幣等]
**基本面分析**:
- [營收、獲利、成長率等完整數據]
**技術分析**:
- [支撐位、壓力位、均線、指標]
**操作建議**:
- [進場/出場策略、停損停利點]
### 8. 運動賽事/紀錄類型
**賽事資訊**:[對陣雙方、日期、地點]
**逐場/逐回合記錄**:
#### 第 1 節/回合
[完整過程、關鍵時刻、得分]
#### 第 2 節/回合
[完整過程、關鍵時刻、得分]
**賽後分析**:[完整戰術分析、教練選手原話]
### 9. 健康/健身教學類型
**教學目標**:[鍛鍊部位、預期效果]
**動作分解**:
| 步驟 | 動作說明 | 時間/次數 | 注意事項 |
|------|---------|----------|---------|
| 1 | [完整動作描述] | [時數/次數] | [關鍵要點] |
| 2 | [完整動作描述] | [時數/次數] | [關鍵要點] |
**常見錯誤**:
- [錯誤 1] → [正確做法]
### 10. 歷史紀錄/紀錄片類型
**時代背景**:[完整歷史脈絡]
**關鍵人物/事件**:
- [人物 1]:[完整生平/貢獻]
- [人物 2]:[完整生平/貢獻]
**時間軸**:
- [年份]:[事件 + 詳細說明]
- [年份]:[事件 + 詳細說明]
### 11. 音樂/歌詞解析類型
**歌曲資訊**:[歌名、歌手、專輯、發行日期]
**完整歌詞**:
[第 1 段]
[完整歌詞]
[第 2 段]
[完整歌詞]
**創作背景**:[完整故事、靈感來源]
### 12. Cooking/食譜類型
**菜名**:[完整名稱]
**材料清單**:
| 食材 | 用量 | 備註 |
|------|------|------|
| [食材] | [精確用量] | [備註] |
**步驟**:
1. [完整步驟說明 + 時間 + 火候]
2. [完整步驟說明 + 時間 + 火候]
**關鍵技巧**:[完整秘訣說明]
### 12. 旅行/Vlog 類型
**地點資訊**:[完整地名、交通方式、行程日期]
**逐日行程**:
#### Day 1
- [08:00] [活動 + 詳細描述 + 費用]
- [12:00] [活動 + 詳細描述 + 費用]
- [18:00] [活動 + 詳細描述 + 費用]
**實用資訊**:
| 項目 | 詳細內容 |
|------|---------|
| 住宿 | [完整名稱、價格、評價] |
| 交通 | [詳細路線與費用] |
| 預算 | [總花費與分配] |
| 推薦 | [必去地點 + 理由] |
**其他結構化內容類型
[完整內容]
---
*Generated by youtube-summary skill (no external LLM calls)*
transcript.txt
[完整原始逐字稿,不做任何修改或摘要]
ASR Configuration
| Audio language | Backend | Invocation |
|---|---|---|
| Taiwanese Hokkien (台語) | Breeze ASR 26 | --asr breeze |
| All other languages | Whisper Turbo | default (--asr whisper) |
Breeze ASR endpoint:
- URL:
http://127.0.0.1:8025 - Max segment: 28 seconds (3000 mel feature limit)
- Audio format: Opus, 48kHz, mono, 16k
- Endpoint:
POST /transcribewithfile=@audio.ogg
Whisper Turbo is invoked through the Breeze streaming project's Transformers pipeline in /home/chihmin/models-work/flux2/.venv-rocm72/bin/python when available. The worker writes timestamped JSON used for the section breakdown and sets the Strix Halo ROCm variables HSA_OVERRIDE_GFX_VERSION=11.5.1, PYTORCH_HIP_ALLOC_CONF=expandable_segments:True, and TORCH_ROCM_AOTRITON_ENABLE_EXPERIMENTAL=1.
Override defaults when needed:
YOUTUBE_SUMMARY_PYTHON— Python executable for the Whisper worker.YOUTUBE_SUMMARY_WHISPER_MODEL— local HF snapshot or model ID.YOUTUBE_SUMMARY_WHISPER_LANGUAGE— optional forced language such asenglish.HF_HOME— Hugging Face cache root.
Error Handling
| Issue | Fix |
|---|---|
| Breeze ASR 500 | Wrong audio format — ensure opus/48kHz/mono/16k |
| Long-form error | Audio >30s — split into ≤28s segments |
| yt-dlp fails | Check URL format or network |
| video path not found | The script now discovers video.*; check the yt-dlp output if no file was produced |
| Whisper GPU crash | Confirm the Breeze ROCm venv/model path; do not replace the worker with the standalone whisper CLI |
| invalid Whisper timestamps | The worker drops empty chunks and clamps reversed/missing timestamps |
| Gist upload fails | Token invalid or no gist scope |
| Empty transcript | Video has no speech (music only) |
| Gist content corrupted | Content was passed as shell args with variable expansion — now fixed: scripts auto-detect file paths vs raw content |
Notes
- Always use Python for JSON (avoids shell escaping)
- Public gists by default
- Gist includes BOTH summary.md and raw transcript.txt
- Transcript is uploaded unmodified (完整原始逐字稿)
- Work dir:
/tmp/youtube-summary(cleaned up after) - Section breakdown uses timestamps:
⏱️ 00:00 - 01:30 【主題】 - Section 5 — 全內容:If the last segment is an interview, dialogue, Q&A, tutorial, code walkthrough, or any structured content type, reproduce the full verbatim content in this section. For interviews, use
**問**:/**答**:format. For tutorials, include complete code/examples. This is the definitive reference section. - No external LLM calls — everything is assembled from the raw transcript directly.