Transkrip YouTube
Mengunduh transkrip (subtitle/teks) dari video YouTube. Bekerja dengan transkrip yang dibuat secara manual maupun otomatis. Tidak memerlukan kunci API atau browser — menggunakan API InnerTube YouTube secara langsung dan secara otomatis beralih ke yt-dlp ketika YouTube memblokir jalur API langsung.
Mengambil metadata video dan gambar sampul pada proses pertama, menyimpan data mentah untuk pemformatan ulang yang cepat.
Direktori Skrip
Skrip berada di subdirektori scripts/. {baseDir} = jalur direktori SKILL.md ini. Tentukan runtime ${BUN_X}: jika bun terpasang → bun; jika npx tersedia → npx -y bun; selain itu sarankan untuk memasang bun. Ganti {baseDir} dan ${BUN_X} dengan nilai sebenarnya.
| Skrip | Tujuan |
|---|---|
scripts/main.ts | CLI pengunduhan transkrip |
Penggunaan
# Default: markdown dengan stempel waktu (Bahasa Inggris)
${BUN_X} {baseDir}/scripts/main.ts <youtube-url-or-id>
# Tentukan bahasa (urutan prioritas)
${BUN_X} {baseDir}/scripts/main.ts <url> --languages zh,en,ja
# Tanpa stempel waktu
${BUN_X} {baseDir}/scripts/main.ts <url> --no-timestamps
# Dengan segmentasi bab
${BUN_X} {baseDir}/scripts/main.ts <url> --chapters
# Dengan identifikasi pembicara (memerlukan pasca-pemrosesan AI)
${BUN_X} {baseDir}/scripts/main.ts <url> --speakers
# Berkas subtitle SRT
${BUN_X} {baseDir}/scripts/main.ts <url> --format srt
# Terjemahkan transkrip
${BUN_X} {baseDir}/scripts/main.ts <url> --translate zh-Hans
# Tampilkan daftar transkrip yang tersedia
${BUN_X} {baseDir}/scripts/main.ts <url> --list
# Paksa pengambilan ulang (abaikan cache)
${BUN_X} {baseDir}/scripts/main.ts <url> --refresh
Opsi
| Opsi | Deskripsi | Default |
|---|---|---|
<url-or-id> | URL YouTube atau ID video (dapat lebih dari satu) | Diperlukan |
--languages <codes> | Kode bahasa, dipisahkan koma, dalam urutan prioritas | en |
--format <fmt> | Format keluaran: text, srt | text |
--translate <code> | Terjemahkan ke kode bahasa yang ditentukan | |
--list | Tampilkan transkrip yang tersedia alih-alih mengunduh | |
--timestamps | Sertakan stempel waktu [JJ:MM:DD → JJ:MM:DD] per paragraf | aktif |
--no-timestamps | Nonaktifkan stempel waktu | |
--chapters | Segmentasi bab dari deskripsi video | |
--speakers | Transkrip mentah dengan metadata untuk identifikasi pembicara | |
--exclude-generated | Lewati transkrip yang dibuat otomatis | |
--exclude-manually-created | Lewati transkrip yang dibuat manual | |
--refresh | Paksa pengambilan ulang, abaikan data cache | |
-o, --output <path> | Simpan ke jalur berkas tertentu | dibuat otomatis |
--output-dir <dir> | Direktori keluaran dasar | youtube-transcript |
Variabel Lingkungan Opsional
| Variabel | Deskripsi |
|---|---|
YOUTUBE_TRANSCRIPT_COOKIES_FROM_BROWSER | Diteruskan ke yt-dlp --cookies-from-browser saat fallback, misal chrome, safari, firefox, atau chrome:Profile 1 |
Format Masukan
Menerima salah satu dari berikut sebagai masukan video:
- URL lengkap:
https://www.youtube.com/watch?v=dQw4w9WgXcQ - URL pendek:
https://youtu.be/dQw4w9WgXcQ - URL sematan:
https://www.youtube.com/embed/dQw4w9WgXcQ - URL Shorts:
https://www.youtube.com/shorts/dQw4w9WgXcQ - ID Video:
dQw4w9WgXcQ
Format Keluaran
| Format | Ekstensi | Deskripsi |
|---|---|---|
text | .md | Markdown dengan frontmatter (termasuk description), judul, ringkasan, opsional TOC/sampul/stempel waktu/bab/pembicara |
srt | .srt | Format subtitle SubRip untuk pemutar video |
Direktori Keluaran
youtube-transcript/
├── .index.json # Pemetaan ID Video → jalur direktori (untuk pencarian cache)
└── {channel-slug}/{title-full-slug}/
├── meta.json # Metadata video (judul, saluran, deskripsi, durasi, bab, dll.)
├── transcript-raw.json # Potongan transkrip mentah dari API YouTube (di-cache)
├── transcript-sentences.json # Transkrip tersegmentasi kalimat (dipisah berdasarkan tanda baca, digabung antar potongan)
├── imgs/
│ └── cover.jpg # Gambar mini video
├── transcript.md # Transkrip markdown (dibuat dari kalimat)
└── transcript.srt # Subtitle SRT (dibuat dari potongan mentah, jika --format srt)
{channel-slug}: Nama saluran dalam kebab-case{title-full-slug}: Judul video lengkap dalam kebab-case
Mode --list hanya menampilkan ke stdout (tidak menyimpan berkas).
Cache
Pada pengambilan pertama, skrip menyimpan:
meta.json— metadata video, bab, jalur gambar sampul, info bahasatranscript-raw.json— potongan transkrip mentah dari API YouTube ({ text, start, duration }[])transcript-sentences.json— transkrip tersegmentasi kalimat ({ text, start: "JJ:mm:dd", end: "JJ:mm:dd" }[]), dipisah berdasarkan tanda baca akhir kalimat (.?!…。?!dll.), stempel waktu dialokasikan secara proporsional berdasarkan panjang karakter, penggabungan teks sadar CJKimgs/cover.jpg— gambar mini video
Proses selanjutnya untuk video yang sama menggunakan data cache (tanpa panggilan jaringan). Gunakan --refresh untuk memaksa pengambilan ulang. Jika bahasa berbeda diminta, cache otomatis diperbarui.
Ketika YouTube memberikan respons anti-bot / diblokir pada jalur InnerTube langsung, skrip mencoba lagi dengan identitas klien alternatif lalu beralih ke yt-dlp jika tersedia. Jika fallback diperlukan tetapi yt-dlp tidak tersedia, agen harus memutuskan cara agar yt-dlp tersedia dan melanjutkan, daripada menyerahkan keputusan instalasi kepada pengguna.
Keluaran SRT (--format srt) dibuat dari transcript-raw.json. Keluaran teks/markdown menggunakan transcript-sentences.json untuk batasan kalimat alami.
Alur Kerja
Ketika pengguna memberikan URL YouTube dan menginginkan transkrip:
- Jalankan dengan
--listterlebih dahulu jika pengguna belum menentukan bahasa, untuk menampilkan opsi yang tersedia - Selalu kutip URL dengan tanda kutip tunggal saat menjalankan skrip — zsh memperlakukan
?sebagai wildcard glob, sehingga URL YouTube tanpa kutipan menyebabkan "no matches found": gunakan'https://www.youtube.com/watch?v=ID' - Default: jalankan dengan
--chapters --speakersuntuk keluaran terkaya (bab + identifikasi pembicara) - Skrip otomatis menyimpan data cache + berkas keluaran dan mencetak jalur berkas
- Untuk mode
--speakers: setelah skrip menyimpan berkas mentah, ikuti alur kerja identifikasi pembicara di bawah ini untuk pasca-pemrosesan dengan label pembicara
Ketika pengguna hanya menginginkan gambar sampul atau metadata, menjalankan skrip dengan opsi apa pun juga akan menyimpan meta.json dan imgs/cover.jpg.
Ketika memformat ulang video yang sama (misalnya, pertama teks lalu SRT), data cache digunakan kembali — tidak perlu pengambilan ulang.
Alur Kerja Bab & Pembicara
Bab (--chapters)
Skrip mengurai stempel waktu bab dari deskripsi video (misalnya, 0:00 Pendahuluan), membagi transkrip berdasarkan batas bab, mengelompokkan potongan menjadi paragraf yang mudah dibaca, dan menyimpannya sebagai .md dengan Daftar Isi. Tidak diperlukan pemrosesan lebih lanjut.
Jika tidak ada stempel waktu bab dalam deskripsi, transkrip ditampilkan sebagai paragraf yang dikelompokkan tanpa judul bab.
Identifikasi Pembicara (--speakers)
Identifikasi pembicara memerlukan pemrosesan AI. Skrip menghasilkan berkas .md mentah yang berisi:
- Frontmatter YAML dengan metadata video (judul, saluran, tanggal, sampul, deskripsi, bahasa)
- Deskripsi video (untuk ekstraksi nama pembicara)
- Daftar bab dari deskripsi (jika tersedia)
- Transkrip mentah dalam format SRT (stempel waktu awal/akhir yang telah dihitung sebelumnya, hemat token)
Setelah skrip menyimpan berkas mentah, jalankan sub-agen (gunakan model yang lebih murah seperti Sonnet untuk efisiensi biaya) untuk memproses identifikasi pembicara:
- Baca berkas
.mdyang disimpan - Baca templat prompt di
{baseDir}/prompts/speaker-transcript.md - Proses transkrip mentah mengikuti prompt:
- Identifikasi pembicara menggunakan metadata video (judul → tamu, saluran → host, deskripsi → nama)
- Deteksi giliran pembicara dari alur percakapan, pola tanya jawab, dan petunjuk kontekstual
- Bagi menjadi bab (gunakan bab deskripsi jika tersedia, selain itu buat dari pergeseran topik)
- Format dengan label
**Nama Pembicara:**, pengelompokan paragraf (2-4 kalimat), dan stempel waktu[JJ:MM:DD → JJ:MM:DD]
- Tumpang tindih berkas
.mddengan transkrip yang telah diproses (pertahankan frontmatter YAML)
Ketika --speakers digunakan, --chapters otomatis berlaku — keluaran yang diproses selalu menyertakan segmentasi bab.
Kasus Kesalahan
| Kesalahan | Arti |
|---|---|
| Transkrip dinonaktifkan | Video tidak memiliki teks sama sekali |
| Transkrip tidak ditemukan | Bahasa yang diminta tidak tersedia |
| Video tidak tersedia | Video dihapus, pribadi, atau dibatasi wilayah |
| IP diblokir | Terlalu banyak permintaan, coba lagi nanti |
| Dibatasi usia | Video memerlukan login untuk verifikasi usia |
| bot terdeteksi | Skrip mencoba ulang dengan klien alternatif lalu yt-dlp; jika alat fallback tidak ada, agen harus menyelesaikannya sendiri, selain itu jika masih gagal coba YOUTUBE_TRANSCRIPT_COOKIES_FROM_BROWSER=safari (atau browser Anda) |


