yt-dlp-kinopub
A yt-dlp extractor plugin for kino.pub / kino.watch: every quality, every audio track (labelled by studio) and all subtitles, whole series as playlists. Log in with your browser's cookies (--cookies-from-browser), or authorize the JSON API once for headless machines. The documentation below is in Russian.
Плагин-экстрактор для yt-dlp: kino.pub / kino.watch. После установки сайт работает в yt-dlp как любой другой:
yt-dlp --cookies-from-browser safari "https://kino.watch/item/view/38290/s1e1"
Это отдельная реализация в идиомах yt-dlp (куки браузера, аргументы экстрактора, кэш сессии, -f/-S), не обёртка над утилитой kinopub. Утилита и плагин друг от друга не зависят и могут жить рядом.
Установка
Любой из способов:
# 1. С PyPI
pip install yt-dlp-kinopub
# 2. Из git, без клонирования
pip install "git+https://github.com/niazlv/yt-dlp-kinopub"
# 3. Клоном прямо в папку плагинов yt-dlp; обновление — git pull
git clone https://github.com/niazlv/yt-dlp-kinopub ~/.config/yt-dlp/plugins/yt-dlp-kinopub
Проверка: в yt-dlp -v появится строка [debug] Extractor Plugins: KinoPubIE.
Авторизация
Основной путь — куки браузера, как у любого сайта в yt-dlp. Сессия API — для машин без браузера. Логин и пароль от сайта плагин не принимает: их некуда отправить.
1. Куки браузера (рекомендуется).
yt-dlp --cookies-from-browser safari "https://kino.watch/item/view/38290/s1e1"
Поддерживаются brave, chrome, chromium, edge, firefox, opera, safari, vivaldi, whale, с выбором профиля и контейнера; Safari на macOS требует Full Disk Access для терминала. Сайт за Cloudflare: если он отвечает челленджем (плагин скажет об этом прямо), передайте User-Agent того же браузера (--user-agent "…"), а при необходимости --impersonate safari (нужен curl_cffi: pip install "yt-dlp[default,curl-cffi]"). Куки уходят только на сайт и никогда на CDN.
2. Своя сессия API по коду. Для серверов и cron, где браузера нет: плагин авторизуется как самостоятельное устройство, токен обновляется сам. Это единственное место, где плагин использует --username, потому что другого слота для разовой интерактивной авторизации у yt-dlp нет.
yt-dlp --username oauth --password "<CLIENT_SECRET>" "kinopub:38290"
На экране появится ссылка и код: откройте ссылку, введите код, подтвердите. Сессия сохраняется в кэше yt-dlp (~/.cache/yt-dlp/kinopub/oauth.json), и дальше флаги не нужны. Секрет тот же, что для kinopub login --qr: kino.pub не выдаёт публичного OAuth-клиента, поэтому нужен секрет приложения. Он есть в kinopub sessions export (поле app_client_secret) после login --app на рутованном телефоне. Плагин его не содержит и не скачивает.
Через .netrc, чтобы не держать секрет в истории команд:
machine kinopub login oauth password <CLIENT_SECRET>
и затем yt-dlp --netrc "kinopub:38290". Секрет нужен один раз: пока в кэше есть refresh-токен, --username oauth с пустым паролем ничего не запрашивает. Когда сессия API есть, плагин предпочитает её кукам: API не за Cloudflare и отдаёт все сезоны одним запросом.
3. Готовый токен API. Например, токен приложения из kinopub login --app (sessions export → app_token). Это значение конфигурации, поэтому передаётся аргументом экстрактора и удобно живёт в ~/.config/yt-dlp/config. Плагин его не обновляет: ротация разлогинила бы приложение. Когда токен истечёт, API ответит 401, и плагин попросит новый.
yt-dlp --extractor-args "kinopub:token=<ACCESS_TOKEN>" "kinopub:38290/s1e1"
Формы ссылок
| Ссылка | Результат |
|---|---|
https://kino.watch/item/view/38290 |
весь элемент: фильм → одно видео, сериал → плейлист всех серий всех сезонов |
https://kino.watch/item/view/38290/s1e1 |
одна серия |
kinopub:38290, kinopub:38290/s1e1 |
то же по id, без домена (только API) |
https://kino.pub/item/view/38290 |
принимается; страницы запрашиваются с kino.watch |
Зеркало сайта задаётся аргументом экстрактора, как --site у утилиты:
yt-dlp --extractor-args "kinopub:site=kino.example" "https://kino.watch/item/view/38290"
Аргумент (--extractor-args "kinopub:…") |
Назначение |
|---|---|
site=<хост или origin> |
сайт для веб-пути (по умолчанию из ссылки, kino.pub → kino.watch) |
api_base=<origin> |
адрес API (по умолчанию https://api.service-kp.com, зеркало https://api.srvkp.com) |
token=<access_token> |
готовый токен API (см. «Авторизация», способ 3) |
audio=<шаблон>[,<шаблон>…] |
предпочтение аудиодорожек, как --audio у утилиты: подстрока студии, языка или идентификатора без учёта регистра; первый шаблон важнее второго; без совпадений остаётся дефолт сайта |
Примеры
# Что доступно: качества, аудиодорожки (с названием студии), субтитры
yt-dlp -F "kinopub:38290/s1e1"
# Серии 1–12 первого сезона: лучшее видео + дорожка AniLibria, все субтитры внутрь mkv
yt-dlp --playlist-items 1-12 -f "bv+ba[format_note*=AniLibria]" \
--embed-subs --sub-langs all --merge-output-format mkv "https://kino.watch/item/view/38290"
# Конкретная дорожка по идентификатору из -F: вторая дорожка группы 1080
yt-dlp -f "bv+audio-1080-2" "kinopub:38290/s1e1"
# Оригинальная озвучка по языку
yt-dlp -f "bv+ba[language=jpn]" "kinopub:38290/s1e1"
# Постоянное предпочтение: сначала AniLibria, иначе оригинал, иначе дефолт сайта (удобно в config)
yt-dlp --extractor-args "kinopub:audio=anilibria,jpn" "kinopub:38290"
# Все аудиодорожки в один файл
yt-dlp --audio-multistreams -f "bv+mergeall[vcodec=none]" --merge-output-format mkv "kinopub:38290/s1e1"
# Предпочесть h265, если он есть
yt-dlp -S "vcodec:h265" "kinopub:38290/s1e1"
# Имена файлов для сериала
yt-dlp -o "%(series)s/S%(season_number)02dE%(episode_number)02d - %(title)s.%(ext)s" "kinopub:38290"
Идентификаторы форматов читаемые и одинаковые от серии к серии:
| Идентификатор | Что это |
|---|---|
hls-1080p, hls-720p, hls-480p |
видео (через API с кодеком: hls-h264-1080p, hls-h265-1080p) |
audio-1080-1, audio-1080-2, … |
аудио: группа качества и номер дорожки, как его нумерует сам сайт |
http-h264-1080p |
прогрессивный mp4 с одной вшитой дорожкой; в сортировке по умолчанию ниже HLS |
Подписи качества берутся у сайта (720x406 он называет 480p). Название студии лежит в format_note, язык в language, и -F показывает их в колонке MORE INFO. Если у одного качества несколько битрейтов, к идентификатору добавляется битрейт: hls-1080p-3805k. Обычный запуск без -f берёт лучшее видео и дорожку, которую сайт играет по умолчанию, из группы лучшего качества.
Что нужно знать
- Секрет и refresh-токен лежат в кэше yt-dlp открытым текстом, как и любые сессии, которые yt-dlp хранит сам.
--no-cache-dirотключает сохранение (плагин предупредит),yt-dlp --rm-cache-dirудаляет всё. - Сессия плагина и сессия утилиты — разные устройства. Не передавайте плагину refresh-токен из
kinopub login --qr: ротация одним разлогинит другого. Токен приложения черезkinopub:token=передавать можно, его никто не обновляет. - CDN отвечает
429на агрессивную параллельность. У yt-dlp нет адаптивного снижения, как у утилиты, поэтому оставьте-N 1(по умолчанию) и при необходимости добавьте--retry-sleep fragment:exp=1:20. - В апстрим yt-dlp это не пойдёт: проект не принимает сайты с пиратским контентом, а для API нужен секрет, который в код не кладётся. Поэтому плагин живёт здесь.
Тесты
Офлайн, без сети и аккаунта: локальный сервер изображает API, OAuth-эндпоинт, CDN и сайт.
python -m unittest discover -s tests
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file yt_dlp_kinopub-0.1.0.tar.gz.
File metadata
- Download URL: yt_dlp_kinopub-0.1.0.tar.gz
- Upload date:
- Size: 47.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b26da8b080223b436010811118103491679797b49e3ee099ecf50c255f65329b
|
|
| MD5 |
4c991308ab2914075bd725faf4aae6e3
|
|
| BLAKE2b-256 |
f1911436e08dcca7e9ab4d6bbfa246665f0408cf5a690668755a632580ff588f
|
Provenance
The following attestation bundles were made for yt_dlp_kinopub-0.1.0.tar.gz:
Publisher:
publish.yml on niazlv/yt-dlp-kinopub
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
yt_dlp_kinopub-0.1.0.tar.gz -
Subject digest:
b26da8b080223b436010811118103491679797b49e3ee099ecf50c255f65329b - Sigstore transparency entry: 2729278348
- Sigstore integration time:
-
Permalink:
niazlv/yt-dlp-kinopub@82d8a37e526a31df1ef4cd11663853617a03b887 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/niazlv
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@82d8a37e526a31df1ef4cd11663853617a03b887 -
Trigger Event:
release
-
Statement type:
File details
Details for the file yt_dlp_kinopub-0.1.0-py3-none-any.whl.
File metadata
- Download URL: yt_dlp_kinopub-0.1.0-py3-none-any.whl
- Upload date:
- Size: 39.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
67107b17e1209781bca26d1fb8d5b0db8eab05d4d05b58bceefb322444c243ba
|
|
| MD5 |
e2af3f8fdfdd07b601b1153f06bfe504
|
|
| BLAKE2b-256 |
61225997b0c356d30e4784f48c251a93cb72ed8765a20d5d9406b8d167db05ca
|
Provenance
The following attestation bundles were made for yt_dlp_kinopub-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on niazlv/yt-dlp-kinopub
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
yt_dlp_kinopub-0.1.0-py3-none-any.whl -
Subject digest:
67107b17e1209781bca26d1fb8d5b0db8eab05d4d05b58bceefb322444c243ba - Sigstore transparency entry: 2729279355
- Sigstore integration time:
-
Permalink:
niazlv/yt-dlp-kinopub@82d8a37e526a31df1ef4cd11663853617a03b887 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/niazlv
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@82d8a37e526a31df1ef4cd11663853617a03b887 -
Trigger Event:
release
-
Statement type: