- Shell 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
Wraps youtube-list-to-peertube.sh: given a YouTube playlist URL, looks up its title and video list via yt-dlp and forwards them, naming the PeerTube playlist after the YouTube one unless PT_PLAYLIST is set explicitly (a stale .env value should not override the derived title). Also adds PT_OTP support to youtube-list-to-peertube.sh's token request, matching move-to-watch-later.sh, and surfaces the actual error body on auth failure instead of a generic message. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P4bKubsWmVho2TsjBHkcQ7 |
||
| .env.example | ||
| .gitignore | ||
| add-unlisted-videos-to-playlist.sh | ||
| dedupe-across-playlists.sh | ||
| dedupe-channel-videos.sh | ||
| dedupe-playlist.sh | ||
| freetube-backfill-descriptions.sh | ||
| freetube-playlist-to-peertube.sh | ||
| load-env.sh | ||
| move-to-watch-later.sh | ||
| peertube-hide-all-videos.sh | ||
| README.md | ||
| youtube-list-to-peertube.sh | ||
| youtube-playlist-to-peertube.sh | ||
Утилиты миграции YouTube → PeerTube
Набор bash-скриптов для переноса видео и плейлистов с YouTube (в том числе из бэкапов FreeTube) на собственный инстанс PeerTube, а также для наведения порядка на канале PeerTube: удаление дублей, чистка плейлистов, массовое скрытие видео.
Все скрипты работают через официальный REST API PeerTube и yt-dlp для
скачивания с YouTube. Конфигурация передаётся через переменные окружения.
Зависимости
| Утилита | Нужна для |
|---|---|
curl |
всех скриптов |
jq |
всех скриптов |
yt-dlp |
скриптов, которые скачивают видео с YouTube |
# Debian/Ubuntu
sudo apt install curl jq
python3 -m pip install -U yt-dlp
Файл .env
Постоянные настройки (адрес инстанса, логин, handle канала, путь к кукам)
удобно один раз положить в файл .env рядом со скриптами — он подхватывается
всеми скриптами автоматически.
cp .env.example .env
$EDITOR .env
Формат — KEY=value, по одной паре на строку; пустые строки и #-комментарии
игнорируются. Значения, переданные при запуске
(PT_DRY_RUN=0 ./dedupe-channel-videos.sh) или уже заданные в окружении,
имеют приоритет над .env — так разовые параметры не приходится держать в файле.
.env в репозиторий не коммитится (см. .gitignore); пример — в .env.example.
Общие переменные окружения
Почти все скрипты понимают один и тот же набор переменных для доступа к PeerTube:
| Переменная | Обязательна | Описание |
|---|---|---|
PT_HOST |
да | адрес инстанса, например https://tube.example.com |
PT_USERNAME |
да | логин PeerTube |
PT_PASSWORD |
нет | пароль; если не задан — скрипт спросит интерактивно |
PT_CHANNEL |
зависит | handle канала, например my_channel |
PT_DRY_RUN |
нет | 1 — только показать, что будет сделано, без изменений |
У разрушительных операций (dedupe-channel-videos.sh, peertube-hide-all-videos.sh)
PT_DRY_RUN=1 включён по умолчанию — чтобы реально применить изменения,
нужно явно указать PT_DRY_RUN=0.
Куки YouTube
Скриптам с yt-dlp для многих видео нужны куки авторизованного аккаунта YouTube:
YTDLP_COOKIES_FILE=~/youtube-cookies.txt— файл в формате Netscape, экспортированный расширением браузера (надёжнее всего);YTDLP_COOKIES_BROWSER=chromium— брать куки напрямую из браузера, если файл не задан (закройте браузер перед запуском).
Файлы куки и бэкапы в репозиторий не коммитятся (см. .gitignore).
Скрипты
Перенос с YouTube на PeerTube
youtube-list-to-peertube.sh
Скачивает видео по списку ссылок YouTube (txt-файл, по одной ссылке на строку;
пустые строки и строки с # игнорируются), проверяет по названию (и опционально
длительности), нет ли уже такого видео на канале PeerTube, загружает новые через
API и добавляет каждое в указанный плейлист.
PT_HOST="https://tube.example.com" PT_USERNAME="me" \
PT_CHANNEL="my_channel" PT_PLAYLIST="Мой плейлист" \
./youtube-list-to-peertube.sh links.txt
Ключевые опции: PT_OTP (код 2FA, если включена), PT_PLAYLIST,
PT_PLAYLIST_CREATE=1, PT_PRIVACY (1=Public, 2=Unlisted, 3=Private — по
умолчанию, 4=Internal), PT_MATCH_DURATION=1, PT_DURATION_TOLERANCE,
YTDLP_SLEEP, YTDLP_PLAYER_CLIENT.
Прогресс пишется в <список>.done, ошибки yt-dlp — в <список>.errors.log.
youtube-playlist-to-peertube.sh
Принимает ссылку на плейлист YouTube целиком (например
https://youtube.com/playlist?list=PL9DC9A8822E21DD87), сам узнаёт у YouTube
через yt-dlp его название и список видео, формирует txt-список ссылок и
передаёт его в youtube-list-to-peertube.sh — в плейлист PeerTube с тем же
названием, что и у плейлиста YouTube (создаётся автоматически, если его ещё
нет).
PT_HOST="https://tube.example.com" PT_USERNAME="me" PT_CHANNEL="my_channel" \
./youtube-playlist-to-peertube.sh "https://youtube.com/playlist?list=PL9DC9A8822E21DD87"
Список ссылок сохраняется в youtube-playlist-<ID>.txt рядом со скриптами —
через него же youtube-list-to-peertube.sh ведёт файлы .done/.errors.log,
поэтому повторный запуск на том же плейлисте продолжит закачку и подхватит
новые видео, добавленные в плейлист с прошлого раза. Своё название плейлиста
на PeerTube можно задать через PT_PLAYLIST; остальные опции — те же, что у
youtube-list-to-peertube.sh.
freetube-playlist-to-peertube.sh
То же самое, но источник — бэкап плейлиста FreeTube (.db, один JSON-объект с
полем videos[]). В бэкапе уже есть title и author, поэтому проверка дублей
на PeerTube идёт без единого запроса к YouTube — yt-dlp вызывается только
для тех видео, которых на канале ещё нет.
PT_HOST="https://tube.example.com" PT_USERNAME="me" PT_CHANNEL="my_channel" \
PT_PLAYLIST="Мой плейлист" \
./freetube-playlist-to-peertube.sh freetube-playlist.db
Опции те же, что у youtube-list-to-peertube.sh (PT_PRIVACY по умолчанию 3).
Чтобы грузить сразу в системный плейлист «Watch later» аккаунта, не гадая,
как он называется на вашем языке интерфейса, укажите PT_PLAYLIST="@watch-later"
— плейлист найдётся по типу, а не по имени.
freetube-backfill-descriptions.sh
Дозаполняет описания у уже загруженных видео. Читает бэкап плейлиста FreeTube,
сопоставляет каждое видео с каналом PeerTube по названию. Если у видео на
PeerTube описание уже есть — пропускает; если нет — только тогда идёт к YouTube
через yt-dlp за описанием и обновляет на PeerTube только поле description
(название не трогается).
PT_HOST="https://tube.example.com" PT_USERNAME="me" PT_CHANNEL="my_channel" \
./freetube-backfill-descriptions.sh freetube-playlist.db
Опции: PT_FORCE_UPDATE=1 (обновлять даже при наличии описания), YTDLP_*.
Наведение порядка на канале PeerTube
dedupe-playlist.sh
Удаляет повторные элементы одного плейлиста: если одно и то же видео добавлено в плейлист несколько раз, оставляет один элемент.
PT_HOST="https://tube.example.com" PT_USERNAME="me" \
PT_PLAYLIST="Смотреть позже" PT_DRY_RUN=1 \
./dedupe-playlist.sh
dedupe-across-playlists.sh
Если видео состоит сразу в нескольких плейлистах из списка PT_PLAYLISTS
(разделитель — |, потому что в названиях бывают запятые), оставляет его только
в первом по приоритету, из остальных перечисленных — убирает. Плейлисты не из
списка не затрагиваются.
PT_HOST="https://tube.example.com" PT_USERNAME="me" \
PT_PLAYLISTS="Посмотреть в первую очередь|Смотреть позже" PT_DRY_RUN=1 \
./dedupe-across-playlists.sh
dedupe-channel-videos.sh ⚠️ разрушительный
Находит на канале видео-дубли (по нормализованному названию и, по умолчанию, по
длительности) и удаляет все, кроме самого раннего по дате загрузки.
DELETE /api/v1/videos/{id} удаляет видео безвозвратно вместе с
комментариями, статистикой и членством во всех плейлистах.
PT_DRY_RUN=1 по умолчанию — сначала посмотрите список.
PT_HOST="https://tube.example.com" PT_USERNAME="me" PT_CHANNEL="my_channel" \
./dedupe-channel-videos.sh # пробный прогон
PT_DRY_RUN=0 ... ./dedupe-channel-videos.sh # реально удалить
Опции: PT_MATCH_DURATION (по умолчанию 1), PT_DURATION_TOLERANCE (2 сек).
После удаления с PT_DRY_RUN=0 рекомендуется прогнать
add-unlisted-videos-to-playlist.sh, чтобы восстановить членство оставшихся
экземпляров в плейлистах.
add-unlisted-videos-to-playlist.sh
Находит все видео канала, которые не состоят ни в одном плейлисте аккаунта, и добавляет их в указанный плейлист (например «Смотреть позже»).
PT_HOST="https://tube.example.com" PT_USERNAME="me" PT_CHANNEL="my_channel" \
PT_PLAYLIST="Смотреть позже" PT_PLAYLIST_CREATE=1 \
./add-unlisted-videos-to-playlist.sh
Опции: PT_PLAYLIST_CREATE=1, PT_DRY_RUN=1.
move-to-watch-later.sh
Переносит все видео из указанного плейлиста в системный плейлист «Watch
later» аккаунта. Системный плейлист ищется не по имени (его отображаемое
имя локализовано и зависит от языка интерфейса аккаунта — «Watch later» /
«Смотреть позже» / «Посмотреть позже» и т.п.), а по типу (type.id == 2),
поэтому угадывать нужное название не нужно.
PT_HOST="https://tube.example.com" PT_USERNAME="me" \
PT_SOURCE_PLAYLIST="Смотреть позже" PT_DRY_RUN=1 \
./move-to-watch-later.sh
Опции: PT_OTP (код 2FA), PT_KEEP_SOURCE=1 (копировать, не удаляя из источника), PT_DRY_RUN=1.
peertube-hide-all-videos.sh
Переводит все видео канала в «скрытый» режим (по умолчанию PT_PRIVACY=2,
Unlisted — видно только по прямой ссылке). Операция обратима: вернуть в
Public можно тем же скриптом с PT_PRIVACY=1.
PT_DRY_RUN=1 по умолчанию.
PT_HOST="https://tube.example.com" PT_USERNAME="me" PT_CHANNEL="my_channel" \
./peertube-hide-all-videos.sh # пробный прогон
PT_DRY_RUN=0 ... ./peertube-hide-all-videos.sh # реально скрыть
Опции: PT_PRIVACY, PT_OTP (код 2FA), PT_SLEEP (пауза между запросами).
Типовой сценарий миграции
freetube-playlist-to-peertube.sh(илиyoutube-list-to-peertube.sh) — залить видео на PeerTube.freetube-backfill-descriptions.sh— дозаполнить описания.dedupe-channel-videos.sh— убрать дубли (сначала dry-run).add-unlisted-videos-to-playlist.sh— вернуть бесхозные видео в плейлист.dedupe-playlist.sh/dedupe-across-playlists.sh— почистить плейлисты.
Каждый скрипт подробно документирован в комментарии-шапке — смотрите его перед запуском.