Транскрипт 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 для загрузки транскриптов |
Использование
# По умолчанию: markdown с метками времени (английский)
${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
# С идентификацией говорящих (требуется постобработка ИИ)
${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 или ID видео (можно несколько) | Обязательно |
--languages <codes> | Коды языков, через запятую, в порядке приоритета | en |
--format <fmt> | Формат вывода: text, srt | text |
--translate <code> | Перевести на указанный код языка | |
--list | Показать доступные транскрипты вместо загрузки | |
--timestamps | Включать метки времени [ЧЧ:ММ:СС → ЧЧ:ММ:СС] на каждый абзац | вкл |
--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 - ID видео:
dQw4w9WgXcQ
Форматы вывода
| Формат | Расширение | Описание |
|---|---|---|
text | .md | Markdown с frontmatter (включая description), заголовок, краткое содержание, опционально TOC/обложка/метки времени/главы/говорящие |
srt | .srt | Формат субтитров SubRip для видеоплееров |
Выходная директория
youtube-transcript/
├── .index.json # Сопоставление ID видео → путь директории (для поиска в кэше)
└── {channel-slug}/{title-full-slug}/
├── meta.json # Метаданные видео (название, канал, описание, длительность, главы и т.д.)
├── transcript-raw.json # Необработанные фрагменты транскрипта из API YouTube (кэшировано)
├── transcript-sentences.json # Транскрипт, сегментированный по предложениям (разделённый по знакам препинания, объединённый между фрагментами)
├── imgs/
│ └── cover.jpg # Миниатюра видео
├── transcript.md # Транскрипт в формате Markdown (сгенерирован из предложений)
└── transcript.srt # Субтитры SRT (сгенерированы из необработанных фрагментов, если указан --format srt)
{channel-slug}: Название канала в kebab-case{title-full-slug}: Полное название видео в kebab-case
Режим --list выводит только в stdout (файл не сохраняется).
Кэширование
При первом запросе скрипт сохраняет:
meta.json— метаданные видео, главы, путь к обложке, информация о языкеtranscript-raw.json— необработанные фрагменты транскрипта из API YouTube ({ text, start, duration }[])transcript-sentences.json— транскрипт, сегментированный по предложениям ({ text, start: "ЧЧ:мм:сс", end: "ЧЧ:мм:сс" }[]), разделённый по знакам конца предложения (.?!…。?!и т.д.), временные метки пропорционально распределяются по длине символов, с учетом слияния текста для CJKimgs/cover.jpg— миниатюра видео
Последующие запуски для того же видео используют кэшированные данные (без сетевых вызовов). Используйте --refresh для принудительного перезапроса. Если запрошен другой язык, кэш автоматически обновляется.
Когда YouTube возвращает антибот / заблокированные ответы на прямом пути InnerTube, скрипт повторяет попытку с альтернативными идентификаторами клиента, а затем, при наличии, переключается на yt-dlp. Если требуется откат, но yt-dlp недоступен, агент должен решить, как сделать yt-dlp доступным, и продолжить, вместо того чтобы перекладывать решение об установке на пользователя.
Вывод SRT (--format srt) генерируется из transcript-raw.json. Текстовый/markdown вывод использует transcript-sentences.json для естественных границ предложений.
Рабочий процесс
Когда пользователь предоставляет URL YouTube и хочет получить транскрипт:
- Сначала запустите с
--list, если пользователь не указал язык, чтобы показать доступные варианты - Всегда заключайте URL в одинарные кавычки при запуске скрипта — zsh обрабатывает
?как глобальный шаблон, поэтому незакавыченный 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)
Идентификация говорящих требует обработки ИИ. Скрипт выводит необработанный .md файл, содержащий:
- YAML frontmatter с метаданными видео (название, канал, дата, обложка, описание, язык)
- Описание видео (для извлечения имён говорящих)
- Список глав из описания (при наличии)
- Необработанный транскрипт в формате SRT (предварительно вычисленные временные метки начала/конца, эффективное использование токенов)
После того как скрипт сохранит необработанный файл, породите подагента (используйте более дешёвую модель, например Sonnet, для экономии) для обработки идентификации говорящих:
- Прочитайте сохранённый
.mdфайл - Прочитайте шаблон промпта из
{baseDir}/prompts/speaker-transcript.md - Обработайте необработанный транскрипт в соответствии с промптом:
- Идентифицируйте говорящих, используя метаданные видео (название → гость, канал → ведущий, описание → имена)
- Определите смены говорящих по течению разговора, паттернам вопрос-ответ и контекстным подсказкам
- Сегментируйте на главы (используйте главы из описания, если есть, иначе создайте из смен тем)
- Форматируйте с метками
**Имя говорящего:**, группировкой абзацев (2-4 предложения) и временными метками[ЧЧ:ММ:СС → ЧЧ:ММ:СС]
- Перезапишите
.mdфайл обработанным транскриптом (сохраните YAML frontmatter)
При использовании --speakers подразумевается --chapters — обработанный вывод всегда включает сегментацию по главам.
Ошибки
| Ошибка | Значение |
|---|---|
| Транскрипты отключены | У видео вообще нет субтитров |
| Транскрипт не найден | Запрошенный язык недоступен |
| Видео недоступно | Видео удалено, приватно или заблокировано по региону |
| IP заблокирован | Слишком много запросов, повторите попытку позже |
| Возрастное ограничение | Видео требует входа для проверки возраста |
| Обнаружен бот | Скрипт повторяет попытку с альтернативными клиентами, затем yt-dlp; если инструменты отката отсутствуют, агент должен решить эту проблему самостоятельно, в противном случае, если всё равно не удаётся, попробуйте YOUTUBE_TRANSCRIPT_COOKIES_FROM_BROWSER=safari (или ваш браузер) |


