Загрузки через yt-dlp (ytdlp)

Требуется: FILE_ACCESS, NETWORK_REQUEST

Загрузка медиа с поддерживаемых сайтов через встроенный бинарник yt-dlp в основном процессе. Аддон не запускает yt-dlp напрямую.

Настройка

  1. Добавьте "FILE_ACCESS" и "NETWORK_REQUEST" в permissions в manifest.json.
  2. Выберите папку назначения:
    • Папка пользователя: запросите доступ manage (files.requestAccess(folder, 'manage')).
    • Временная папка аддона: пишите в ADDON_TMP_DIR — диалог согласия не нужен.
  3. Подпишитесь на прогресс и вызовите ytdlp.downloadFile.
const folder = 'C:\\Videos\\clips';
const access = await files.requestAccess(folder, 'manage');
if (!access.success) {
  console.warn(access.message);
  return;
}
{
  "id": "my-addon",
  "permissions": ["FILE_ACCESS", "NETWORK_REQUEST"]
}

Как это работает

ytdlp.downloadFile(url, outputPath, options?)

Параметр Обязателен Описание
url да URL медиа (http:// или https://)
outputPath да Абсолютный путь; допускаются переменные вроде %(title)s.%(ext)s
options.downloadId нет Связь с событиями прогресса; генерируется автоматически
options.concurrentFragments нет Параллельные фрагменты, 110
options.format нет Селектор -f yt-dlp (например ba/bestaudio)
options.extractAudio нет При true передаёт -x (извлечь аудио)
options.audioFormat нет --audio-format вместе с extractAudio (например m4a)
options.mergeOutputFormat нет --merge-output-format (например mp4)

Возвращает:

{
  success: boolean,
  downloadId?: string,
  error?: YtDlpAddonErrorCode,
  message?: string,
}

Прогресс (ytdlp:download-progress)

Подпишитесь до вызова downloadFile:

const downloadId = random.id();

events.On('ytdlp:download-progress', ({ downloadId: id, progress }) => {
  if (id !== downloadId) return;

  console.log(progress.stage, progress.percent, progress.speed, progress.eta);
  // progress.downloadedBytes, progress.totalBytes
});

progress.stage'downloading' во время загрузки, 'done' при успехе и 'cancelled' при остановке через ytdlp.cancelDownload.

ytdlp.cancelDownload(downloadId)

Прерывает активную загрузку с тем же downloadId. Промис downloadFile завершится с success: false и error: 'cancelled'.

Параметр Обязателен Описание
downloadId да Тот же id, что передан в downloadFile (или возвращён им)

Возвращает:

{
  success: boolean,
  downloadId?: string,
  error?: 'no_permission' | 'not_found' | 'invalid_download_id',
  message?: string,
}

Пример отмены

const downloadId = random.id();
const downloadPromise = ytdlp.downloadFile(url, outputPath, { downloadId });

cancelButton.onClick(async () => {
  const cancelled = await ytdlp.cancelDownload(downloadId);
  if (!cancelled.success) {
    console.warn(cancelled.error, cancelled.message);
  }
});

const result = await downloadPromise;
if (result.error === 'cancelled') {
  console.log('Загрузка остановлена пользователем');
}

Пример

const outputDir = 'C:\\Videos\\clips';
await files.requestAccess(outputDir, 'manage');

const downloadId = random.id();
events.On('ytdlp:download-progress', ({ downloadId: id, progress }) => {
  if (id !== downloadId) return;
  status.Update({
    current: 'online',
    message: { ru: `Загрузка ${progress.percent.toFixed(1)}%` },
  });
});

const result = await ytdlp.downloadFile(
  'https://www.twitch.tv/videos/1234567890',
  `${outputDir}\\%(uploader)s - %(title)s.%(ext)s`,
  { downloadId, concurrentFragments: 4 }
);

if (!result.success) {
  console.warn(result.error, result.message);
}

Переменные шаблона вывода

В outputPath можно использовать поля yt-dlp. Основные переменные:

Идентификация

Переменная Описание
%(id)s ID видео
%(title)s Название
%(fulltitle)s Полное название (без обрезки)
%(description)s Описание
%(webpage_url)s Ссылка на страницу
%(original_url)s Исходный URL

Формат

Переменная Описание
%(ext)s Расширение (mp4, mkv, webm, …)
%(format)s Выбранный формат (строка)
%(format_id)s ID формата
%(resolution)s Разрешение (например 1920x1080)
%(height)s Высота
%(width)s Ширина
%(fps)s FPS
%(vcodec)s Видеокодек
%(acodec)s Аудиокодек
%(tbr)s Общий bitrate

Автор / канал

Переменная Описание
%(uploader)s Имя канала/автора
%(uploader_id)s ID канала
%(uploader_url)s Ссылка на канал
%(channel)s Канал (YouTube/Twitch)
%(channel_id)s ID канала
%(channel_url)s Ссылка на канал

Дата и время

Переменная Описание
%(upload_date)s Дата (YYYYMMDD)
%(timestamp)s UNIX timestamp
%(release_date)s Дата релиза (если есть)

Длительность

Переменная Описание
%(duration)s Длительность в секундах
%(duration_string)s Читаемый формат (например 01:23:45)

Статистика

Переменная Описание
%(view_count)s Просмотры
%(like_count)s Лайки
%(comment_count)s Комментарии
%(average_rating)s Рейтинг (редко)

Метаданные

Переменная Описание
%(categories)s Категории
%(tags)s Теги (через запятую)
%(language)s Язык
%(availability)s Доступность

Плейлисты

Переменная Описание
%(playlist)s Имя плейлиста
%(playlist_id)s ID плейлиста
%(playlist_index)s Позиция
%(playlist_title)s Название плейлиста

Субтитры

Переменная Описание
%(subtitles)s Субтитры
%(automatic_captions)s Автосубтитры

Сайт / экстрактор

Переменная Описание
%(extractor)s Сайт (twitch, youtube, …)
%(extractor_key)s Ключ экстрактора

Twitch

Переменная Описание
%(creator)s Автор клипа
%(is_live)s Флаг трансляции
%(start_time)s Начало сегмента
%(end_time)s Конец сегмента

Полный список: шаблон вывода yt-dlp

Коды ошибок

При success: false поле error:

Код Причина
no_permission Нет FILE_ACCESS и/или NETWORK_REQUEST в манифесте
no_file_access Папка вывода не покрыта грантом manage — сначала files.requestAccess(folder, 'manage')
unsupported_platform Нет встроенного yt-dlp для этой ОС
binary_missing Бинарник не найден в установке приложения
invalid_url Пустой или не http(s) URL
invalid_path Пустой или неверный путь вывода
incorrect_url yt-dlp отклонил URL или не нашёл форматы
network_error Сеть/DNS/HTTP или ошибка запуска процесса
download_failed yt-dlp завершился с ошибкой без более точной классификации
cancelled Загрузка остановлена через ytdlp.cancelDownload

Ошибки cancelDownload:

Код Причина
no_permission Нет FILE_ACCESS и/или NETWORK_REQUEST
invalid_download_id Пустой downloadId
not_found Нет активной загрузки с этим id (уже завершена или не запускалась)

message — читаемое описание (часто stderr yt-dlp).

См. также