ทรานสคริปต์ YouTube
ดาวน์โหลดทรานสคริปต์ (คำบรรยาย/แคปชัน) จากวิดีโอ YouTube ทำงานได้ทั้งคำบรรยายที่สร้างด้วยมือและสร้างโดยอัตโนมัติ ไม่ต้องใช้คีย์ API หรือเบราว์เซอร์ — ใช้ InnerTube API ของ YouTube โดยตรงและจะเปลี่ยนไปใช้ yt-dlp โดยอัตโนมัติหาก YouTube บล็อกเส้นทาง API โดยตรง
ดึงข้อมูลเมตาดาต้าของวิดีโอและภาพปกเมื่อเรียกใช้ครั้งแรก เก็บแคชข้อมูลดิบเพื่อการจัดรูปแบบใหม่ที่รวดเร็ว
ไดเรกทอรีสคริปต์
สคริปต์ในไดเรกทอรีย่อย scripts/ {baseDir} = เส้นทางไดเรกทอรีของ SKILL.md นี้ แปลงค่ารันไทม์ ${BUN_X}: หากติดตั้ง bun → bun; หากมี npx → npx -y bun; มิฉะนั้นแนะนำให้ติดตั้ง bun แทนที่ {baseDir} และ ${BUN_X} ด้วยค่าจริง
| สคริปต์ | วัตถุประสงค์ |
|---|---|
scripts/main.ts | CLI สำหรับดาวน์โหลดทรานสคริปต์ |
วิธีใช้
# ค่าเริ่มต้น: มาร์กดาวน์พร้อมตราประทับเวลา (อังกฤษ)
${BUN_X} {baseDir}/scripts/main.ts <youtube-url-or-id>
# ระบุภาษา (ลำดับความสำคัญ)
${BUN_X} {baseDir}/scripts/main.ts <url> --languages zh,en,ja
# ไม่มีตราประทับเวลา
${BUN_X} {baseDir}/scripts/main.ts <url> --no-timestamps
# แบ่งตามบท
${BUN_X} {baseDir}/scripts/main.ts <url> --chapters
# ระบุผู้พูด (ต้องใช้การประมวลผลภายหลังด้วย AI)
${BUN_X} {baseDir}/scripts/main.ts <url> --speakers
# ไฟล์คำบรรยาย SRT
${BUN_X} {baseDir}/scripts/main.ts <url> --format srt
# แปลทรานสคริปต์
${BUN_X} {baseDir}/scripts/main.ts <url> --translate zh-Hans
# แสดงรายการทรานสคริปต์ที่มี
${BUN_X} {baseDir}/scripts/main.ts <url> --list
# บังคับดึงใหม่ (ไม่ใช้แคช)
${BUN_X} {baseDir}/scripts/main.ts <url> --refresh
ตัวเลือก
| ตัวเลือก | คำอธิบาย | ค่าเริ่มต้น |
|---|---|---|
<url-or-id> | URL ของ YouTube หรือรหัสวิดีโอ (อนุญาตหลายรายการ) | จำเป็น |
--languages <codes> | รหัสภาษา คั่นด้วยจุลภาค ตามลำดับความสำคัญ | en |
--format <fmt> | รูปแบบผลลัพธ์: text, srt | text |
--translate <code> | แปลเป็นรหัสภาษาที่ระบุ | |
--list | แสดงรายการทรานสคริปต์ที่มีแทนที่จะดึง | |
--timestamps | รวมตราประทับเวลา [HH:MM:SS → HH:MM:SS] ต่อย่อหน้า | เปิด |
--no-timestamps | ปิดการใช้งานตราประทับเวลา | |
--chapters | แบ่งบทจากคำอธิบายวิดีโอ | |
--speakers | ทรานสคริปต์ดิบพร้อมเมตาดาต้าสำหรับระบุผู้พูด | |
--exclude-generated | ข้ามทรานสคริปต์ที่สร้างโดยอัตโนมัติ | |
--exclude-manually-created | ข้ามทรานสคริปต์ที่สร้างด้วยมือ | |
--refresh | บังคับดึงใหม่ ไม่ใช้ข้อมูลแคช | |
-o, --output <path> | บันทึกไปยังเส้นทางไฟล์ที่ระบุ | สร้างโดยอัตโนมัติ |
--output-dir <dir> | ไดเรกทอรีผลลัพธ์ฐาน | youtube-transcript |
ตัวแปรสภาพแวดล้อมเสริม
| ตัวแปร | คำอธิบาย |
|---|---|
YOUTUBE_TRANSCRIPT_COOKIES_FROM_BROWSER | ส่งผ่านไปยัง yt-dlp --cookies-from-browser ระหว่างการสำรอง เช่น chrome, safari, firefox, หรือ chrome:Profile 1 |
รูปแบบอินพุต
ยอมรับรูปแบบใดๆ เหล่านี้เป็นอินพุตวิดีโอ:
- URL เต็ม:
https://www.youtube.com/watch?v=dQw4w9WgXcQ - URL ย่อ:
https://youtu.be/dQw4w9WgXcQ - URL ฝัง:
https://www.youtube.com/embed/dQw4w9WgXcQ - URL Shorts:
https://www.youtube.com/shorts/dQw4w9WgXcQ - รหัสวิดีโอ:
dQw4w9WgXcQ
รูปแบบผลลัพธ์
| รูปแบบ | นามสกุล | คำอธิบาย |
|---|---|---|
text | .md | มาร์กดาวน์พร้อม frontmatter (รวม description), หัวเรื่อง, สรุป, TOC/ปก/ตราประทับ/บท/ผู้พูดตามตัวเลือก |
srt | .srt | รูปแบบคำบรรยาย SubRip สำหรับโปรแกรมเล่นวิดีโอ |
ไดเรกทอรีผลลัพธ์
youtube-transcript/
├── .index.json # การจับคู่รหัสวิดีโอ → เส้นทางไดเรกทอรี (สำหรับค้นหาแคช)
└── {channel-slug}/{title-full-slug}/
├── meta.json # เมตาดาต้าวิดีโอ (ชื่อ, ช่อง, คำอธิบาย, ระยะเวลา, บท, ฯลฯ)
├── transcript-raw.json # ส่วนย่อยของทรานสคริปต์ดิบจาก YouTube API (แคช)
├── transcript-sentences.json # ทรานสคริปต์ที่แบ่งเป็นประโยค (แยกตามเครื่องหมายวรรคตอน, รวมข้ามส่วนย่อย)
├── imgs/
│ └── cover.jpg # ภาพปกขนาดย่อ
├── transcript.md # ทรานสคริปต์มาร์กดาวน์ (สร้างจากประโยค)
└── transcript.srt # คำบรรยาย SRT (สร้างจากส่วนย่อยดิบ หากใช้ --format srt)
{channel-slug}: ชื่อช่องในรูปแบบ kebab-case{title-full-slug}: ชื่อวิดีโอเต็มในรูปแบบ kebab-case
โหมด --list จะพิมพ์ผลลัพธ์ไปยัง stdout เท่านั้น (ไม่บันทึกไฟล์)
การแคช
เมื่อดึงครั้งแรก สคริปต์จะบันทึก:
meta.json— เมตาดาต้าวิดีโอ, บท, เส้นทางภาพปก, ข้อมูลภาษาtranscript-raw.json— ส่วนย่อยของทรานสคริปต์ดิบจาก YouTube API ({ text, start, duration }[])transcript-sentences.json— ทรานสคริปต์ที่แบ่งเป็นประโยค ({ text, start: "HH:mm:ss", end: "HH:mm:ss" }[]), แยกตามเครื่องหมายจบประโยค (.?!…。?!ฯลฯ), จัดสรรตราประทับเวลาตามสัดส่วนความยาวอักขระ, รวมข้อความโดยรู้จัก CJKimgs/cover.jpg— ภาพปกขนาดย่อ
การเรียกใช้ครั้งต่อไปสำหรับวิดีโอเดียวกันจะใช้ข้อมูลแคช (ไม่เรียกเครือข่าย) ใช้ --refresh เพื่อบังคับดึงใหม่ หากมีการร้องขอภาษาอื่น แคชจะถูกรีเฟรชโดยอัตโนมัติ
เมื่อ YouTube ตอบกลับด้วยการต่อต้านบอท / ถูกบล็อกบนเส้นทาง InnerTube โดยตรง สคริปต์จะลองใหม่ด้วยข้อมูลประจำตัวไคลเอนต์อื่นแล้วจึงเปลี่ยนไปใช้ yt-dlp หากมี หากจำเป็นต้องสำรองแต่ yt-dlp ไม่พร้อมใช้งาน เอเจนต์ควรตัดสินใจว่าจะทำให้ yt-dlp พร้อมใช้งานและดำเนินการต่ออย่างไรแทนที่จะผลักภาระการตัดสินใจติดตั้งให้ผู้ใช้
ผลลัพธ์ SRT (--format srt) สร้างจาก transcript-raw.json ผลลัพธ์ข้อความ/มาร์กดาวน์ใช้ transcript-sentences.json เพื่อขอบเขตประโยคที่เป็นธรรมชาติ
เวิร์กโฟลว์
เมื่อผู้ใช้ระบุ URL ของ YouTube และต้องการทรานสคริปต์:
- เรียกใช้ด้วย
--listก่อนหากผู้ใช้ไม่ได้ระบุภาษา เพื่อแสดงตัวเลือกที่มี - ใส่ URL ในเครื่องหมายคำพูดเดี่ยวเสมอ เมื่อเรียกใช้สคริปต์ — zsh ถือว่า
?เป็นอักขระไวลด์การ์ดแบบ glob ดังนั้น URL YouTube ที่ไม่มีเครื่องหมายคำพูดจะทำให้เกิด "no matches found": ใช้'https://www.youtube.com/watch?v=ID' - ค่าเริ่มต้น: เรียกใช้ด้วย
--chapters --speakersเพื่อผลลัพธ์ที่สมบูรณ์ที่สุด (บท + การระบุผู้พูด) - สคริปต์จะบันทึกข้อมูลแคช + ไฟล์ผลลัพธ์โดยอัตโนมัติและพิมพ์เส้นทางไฟล์
- สำหรับโหมด
--speakers: หลังจากสคริปต์บันทึกไฟล์ดิบ ให้ทำตามเวิร์กโฟลว์การระบุผู้พูดด้านล่างเพื่อประมวลผลภายหลังด้วยป้ายกำกับผู้พูด
เมื่อผู้ใช้ต้องการเพียงภาพปกหรือเมตาดาต้า การเรียกใช้สคริปต์ด้วยตัวเลือกใดๆ จะแคช meta.json และ imgs/cover.jpg ด้วย
เมื่อจัดรูปแบบวิดีโอเดียวกันใหม่ (เช่น ข้อความก่อนแล้วจึง SRT) ข้อมูลที่แคชแล้วจะถูกใช้ซ้ำ — ไม่จำเป็นต้องดึงใหม่
เวิร์กโฟลว์บทและผู้พูด
บท (--chapters)
สคริปต์จะแยกวิเคราะห์ตราประทับเวลาของบทจากคำอธิบายวิดีโอ (เช่น 0:00 บทนำ), แบ่งทรานสคริปต์ตามขอบเขตของบท, จัดกลุ่มส่วนย่อยเป็นย่อหน้าที่อ่านได้, และบันทึกเป็น .md พร้อมสารบัญ ไม่ต้องประมวลผลเพิ่มเติม
หากไม่มีตราประทับเวลาบทในคำอธิบาย ทรานสคริปต์จะถูกแสดงเป็นย่อหน้ากลุ่มโดยไม่มีหัวข้อบท
การระบุผู้พูด (--speakers)
การระบุผู้พูดต้องใช้การประมวลผลด้วย AI สคริปต์จะสร้างไฟล์ .md ดิบที่ประกอบด้วย:
- frontmatter YAML พร้อมเมตาดาต้าวิดีโอ (ชื่อ, ช่อง, วันที่, ปก, คำอธิบาย, ภาษา)
- คำอธิบายวิดีโอ (สำหรับการสกัดชื่อผู้พูด)
- รายการบทจากคำอธิบาย (หากมี)
- ทรานสคริปต์ดิบในรูปแบบ SRT (ตราประทับเวลาเริ่ม/สิ้นสุดที่คำนวณล่วงหน้า, ประหยัดโทเค็น)
หลังจากสคริปต์บันทึกไฟล์ดิบ ให้สร้างซับเอเจนต์ (ใช้โมเดลที่ถูกกว่าเช่น Sonnet เพื่อประหยัดค่าใช้จ่าย) เพื่อประมวลผลการระบุผู้พูด:
- อ่านไฟล์
.mdที่บันทึกไว้ - อ่านเทมเพลตพร้อมต์ที่
{baseDir}/prompts/speaker-transcript.md - ประมวลผลทรานสคริปต์ดิบตามพร้อมต์:
- ระบุผู้พูดโดยใช้เมตาดาต้าวิดีโอ (ชื่อ → แขก, ช่อง → โฮสต์, คำอธิบาย → ชื่อ)
- ตรวจจับการเปลี่ยนผู้พูดจากการไหลของบทสนทนา, รูปแบบคำถาม-คำตอบ, และเบาะแสบริบท
- แบ่งเป็นบท (ใช้บทจากคำอธิบายหากมี, มิฉะนั้นสร้างจากกะงานหัวข้อ)
- จัดรูปแบบด้วยป้ายกำกับ
**ชื่อผู้พูด:**, การจัดกลุ่มย่อหน้า (2-4 ประโยค), และตราประทับเวลา[HH:MM:SS → HH:MM:SS]
- เขียนทับไฟล์
.mdด้วยทรานสคริปต์ที่ประมวลผลแล้ว (เก็บ frontmatter YAML ไว้)
เมื่อใช้ --speakers, --chapters จะถูกใช้โดยนัย — ผลลัพธ์ที่ประมวลผลจะรวมการแบ่งบทเสมอ
กรณีข้อผิดพลาด
| ข้อผิดพลาด | ความหมาย |
|---|---|
| Transcripts disabled | วิดีโอไม่มีคำบรรยายเลย |
| No transcript found | ภาษาที่ร้องขอไม่มี |
| Video unavailable | วิดีโอถูกลบ, เป็นส่วนตัว, หรือถูกล็อคตามภูมิภาค |
| IP blocked | คำขอมากเกินไป, ลองใหม่ภายหลัง |
| Age restricted | วิดีโอต้องการการเข้าสู่ระบบเพื่อยืนยันอายุ |
| bot detected | สคริปต์จะลองไคลเอนต์อื่นแล้วจึง yt-dlp; หากเครื่องมือสำรองหายไป เอเจนต์ควรแก้ไขเอง, มิฉะนั้นหากยังล้มเหลวให้ลอง YOUTUBE_TRANSCRIPT_COOKIES_FROM_BROWSER=safari (หรือเบราว์เซอร์ของคุณ) |


