Мы неоднократно рассказывали о специальном софте, который позволяет скачивать видео с YouTube. Это в первую очередь youtube-dl (yt-dl) и его клоны, такие как yt-dlp и yt-dlc. С ними воюют могучие копирасты, пытаются удалить их из поисковой выдачи, с хостингов, с Github и так далее, по известной схеме «тотальная война».
Но главным врагом для этих программ остаются даже не правообладатели, а злобная корпорация Google, которая постоянно вносит изменения в YouTube API, чтобыпрекратить злоупотребления сервисом помешать людям скачивать файлы, ведь от этого Google никакой прибыли.
Сами программки — просто технические инструменты для скачивания общедоступного контента, они ничего не воруют и не пиратят. Просто доступ происходит нестандартным способом, который не предусмотрен официально. Посмотрим, как это делается.
Исходный код yt-dl и самого популярного клона yt-dlp написаны на Python и опубликованы на Github. Все инструменты используют стандартный интерфейс YouTube API, который постоянно меняется для борьбы как раз с этими сервисами.
Ниже приведены примеры обращения к YouTube API из командной строки. Примерно такие же «хакерские» способы используются в
У каждого видео YouTube есть уникальный идентификатор, который отображается в командной строке. Например, взять лекцию по введению в нейросети с популярного стэнфордского курса CS229 («Машинное обучение»):
Здесь это
Чтобы из консоли получить ссылку на видеофайл для встроенного плеера, обращаемся к YouTube API установкой правильного контекста, который проверяется API. В данном случае проверяется отправитель
Получаем результат:
Адрес можно также взять с помощью Developer Tools на открытой веб-странице.
Это и есть искомый URL. Формат его следующий:
Некоторые из этих параметров YouTube API описаны в документацииYouTube
Дело в том, что YouTube (Google) всячески мешает альтернативным клиентам скачивать видеофайлы на максимальной скорости, расценивая это как нелегальное использование своих ресурсов. Для этого реализовано специальное ограничение скорости.
Например, попробуем скачать вышеуказанный URL без преобразования. Из консоли:
И мы увидим, что скорость скачивания никогда не превышает 30−50 КБ/с:
Но на такой скорости наша лекция продолжительностью 1 ч 20 мин будет скачиваться примерно пять с половиной часов. Налицо явное несоответствие.
Похоже, в YouTube заложен лимит на скорость скачивания видео при запросе через API, а браузер обходит это ограничение. И наши любимые программки вроде
Как объясняет хакер 0x7D0 (вероятно, он входит в число контрибьюторов
Параметр представляет собой своего рода DRM, то есть проверку валидности сайта, на котором установлен плеер. Если URL не проходит проверку, то YouTube обрезает скорость скачивания, как в нашем примере.
Так что для скачивания файлов с YouTube на нормальной скорости без файла
Примерно так же делает
После вычисления мы получаем новый «быстрый» URL. Интересно, что даже для него действуют ограничения скорости YouTube, чтобы она не превышала необходимой скорости для файла данного размера и качества, но
Более подробно эта тема обсуждается в репозитории
Потом скачанные фрагменты склеиваем в единое целое, при необходимости объединяя видео и звук. Вот почему
Проделав все эти шаги, мы можем скачивать видео с YouTube на высокой скорости даже без использования
Как уже было сказано, юристы правообладателей пытаются всячески помешать работе альтернативных клиентов для YouTube. Хуже всего, когда изымаются домены, потому что тогда программа не может нормально обновиться или ломается какая-нибудь функциональность типа сообщений о багах. Остаётся только репозиторий на Github, который принадлежит Microsoft, так что хакерский софт там на птичьих правах.
Представим, что YouTube поменял API, в результате
Конфискованный домен yt-dl.org. Он уже давно в таком состоянии
Юридическая атака на
В данный момент битву против
Сравнение коммитов в мастер yt-dl (вверху) и yt-dlp (внизу)
Как уже было сказано, исходный код
Эта война копирастов из YouTube (Google) с якобы «пиратским» софтом выглядит довольно забавно, ведь на заре своего существования сам YouTube считался абсолютно пиратским. Как и российский стартап ВКонтакте, сразу после запуска он быстро набрал популярность за счёт того, что пользователи могли безнаказанно публиковать там нелицензионный контент: фильмы, сериалы, мультики и пр. И они там долго висели.
Например, в 2006 году редакторы Википедии обсуждали предложение удалить из энциклопедии все ссылки на YouTube, поскольку «львиная доля контента там является пиратским». Тогда YouTube особо не спешил бороться с этим явлением. Но спустя двадцать лет уже сам вошёл в число рьяных копирастов. Ничего не поделаешь, это капитализм. Ну а с ВК вообще всё понятно, сейчас нелицензионный контент в РФ почти официально разрешён. Говорят, в прошлом году даже в кинотеатрах крутили пиратки (только без рекламы 1xbet), может и сейчас где-то крутят, никто за это уже не будет особо карать.
В случае с нынешней историей основной вывод таков: программы для скачивания на самом деле реализуют базовые функции YouTube API, просто в таком виде, какой не нравится правообладателям. Но те ничего не могут поделать, потому что код программ открыт и способ реализации понятен, так что такие инструменты может сделать каждый и использовать их никто не запретит.
Наличие кучи «сервисов по загрузке видео» доказывает, что реализовать такой функционал довольно легко. Правда, есть нюансы, главный из которых — ограничение на скорость скачивания. Но всё можно решить. И в принципе можно спокойно обойтись даже без специальных инструментов вроде
Но главным врагом для этих программ остаются даже не правообладатели, а злобная корпорация Google, которая постоянно вносит изменения в YouTube API, чтобы
Сами программки — просто технические инструменты для скачивания общедоступного контента, они ничего не воруют и не пиратят. Просто доступ происходит нестандартным способом, который не предусмотрен официально. Посмотрим, как это делается.
Исходный код yt-dl и самого популярного клона yt-dlp написаны на Python и опубликованы на Github. Все инструменты используют стандартный интерфейс YouTube API, который постоянно меняется для борьбы как раз с этими сервисами.
Ниже приведены примеры обращения к YouTube API из командной строки. Примерно такие же «хакерские» способы используются в
yt-dl
и yt-dlp
.▍ Как получить URL файла для скачивания
У каждого видео YouTube есть уникальный идентификатор, который отображается в командной строке. Например, взять лекцию по введению в нейросети с популярного стэнфордского курса CS229 («Машинное обучение»):
https://www.youtube.com/watch?v=MfIjxPh6Pys
Здесь это
MfIjxPh6Pys
.Чтобы из консоли получить ссылку на видеофайл для встроенного плеера, обращаемся к YouTube API установкой правильного контекста, который проверяется API. В данном случае проверяется отправитель
/youtubei/v1/player
. Под Linux с установленной утилитой http
задание контекста, запрос URL и получение результата выглядит таким образом:$ echo -n '{"videoId":"MfIjxPh6Pys","context":{"client":{"clientName":"WEB","clientVersion":"2.20230810.05.00"}}}' |
http post 'https://www.youtube.com/youtubei/v1/player' |
jq -r '.streamingData.adaptiveFormats[0].url'
Получаем результат:
https://rr1---sn-cxauxaxjvh-hn9ee.googlevideo.com/videoplayback?expire=1696595317&ei=FakfZfXlEtGlv_IPxNaV2AU&ip=37.214.30.90&id=o-AMiXDDvzOJHVfbTdoHu7xOdk9fvOq9m84I3Wzk753Yu5&itag=137&aitags=133%2C134%2C135%2C136%2C137%2C160%2C242%2C243%2C244%2C247%2C248%2C278&source=youtube&requiressl=yes&mh=Rz&mm=31%2C26&mn=sn-cxauxaxjvh-hn9ee%2Csn-4g5edndd&ms=au%2Conr&mv=m&mvi=1&pl=23&initcwndbps=1002500&spc=UWF9fzcbe7KrcWzhYWx5WsJlt_lA6NVDpNGO3Cm8sw&vprv=1&svpuc=1&mime=video%2Fmp4&ns=P1X5iZALtEvoq7t3wbLWUZ4P&gir=yes&clen=948670888&dur=4813.466&lmt=1587563951213289&mt=1696573267&fvip=4&keepalive=yes&fexp=24007246&beids=24350018&c=WEB&txp=5316222&n=eCX-4hI1kOARp7xm&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cspc%2Cvprv%2Csvpuc%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AGM4YrMwRAIgT-QJYv9PrBilbApceUYThL_ioh_3bimU0gGWaMXw2HACIAZMSJ8EB_eiu_TJDm77Z0PQUFRuKSJlqX-RDXsQzxoK&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AK1ks_kwRAIgSFJb5d1DNHo8RRoocYbq_YW_QDeKOp_BVnEfD3sHNoMCIB5lV1AM1hiZ75rOHfnY5DRk71AVcE-K3Bo2kMxi6_6x
Адрес можно также взять с помощью Developer Tools на открытой веб-странице.
Это и есть искомый URL. Формат его следующий:
Protocol: https
Hostname: rr1---sn-cxauxaxjvh-hn9ee.googlevideo.com
Path name: /videoplayback
Query Parameters:
expire: 1696595317
ei: FakfZfXlEtGlv_IPxNaV2AU
ip: 37.214.30.90
id: o-AMiXDDvzOJHVfbTdoHu7xOdk9fvOq9m84I3Wzk753Yu5
itag: 137
aitags: 133,134,135,136,137,160,242,243,244,247,248,278
source: youtube
requiressl: yes
mh: Rz
mm: 31,26
mn: sn-cxauxaxjvh-hn9ee/Csn-4g5edndd
ms: au
mv: m
mvi: 1
pl: 23
initcwndbps: 1002500
spc: UWF9fzcbe7KrcWzhYWx5WsJlt_lA6NVDpNGO3Cm8sw
vprv: 1
svpuc: 1
mime: video/mp4
ns: P1X5iZALtEvoq7t3wbLWUZ4P
gir: yes
clen: 948670888
dur: 4813.466
lmt: 1587563951213289
mt: 1696573267
fvip: 4
keepalive: yes
fexp: 24007246
beids: 24350018
c: WEB
txp: 5316222
n: eCX-4hI1kOARp7xm
sparams: expire,ei,ip,id,aitags,source,requiressl,spc,vprv,svpuc,mime,ns,gir,clen,dur,lmt
sig: AGM4YrMwRAIgT-QJYv9PrBilbApceUYThL_ioh_3bimU0gGWaMXw2HACIAZMSJ8EB_eiu_TJDm77Z0PQUFRuKSJlqX-RDXsQzxoK
lsparams: mh,mm,mn,ms,mv,mvi,pl,initcwndbps
lsig: AK1ks_kwRAIgSFJb5d1DNHo8RRoocYbq_YW_QDeKOp_BVnEfD3sHNoMCIB5lV1AM1hiZ75rOHfnY5DRk71AVcE-K3Bo2kMxi6_6x
Некоторые из этих параметров YouTube API описаны в документации
yt-dlp
, но нам они вроде бы не нужны. Казалось бы, берём URL и скачиваем, у нас есть валидный адрес. Но не всё так просто.▍ Ограничение скорости
Дело в том, что YouTube (Google) всячески мешает альтернативным клиентам скачивать видеофайлы на максимальной скорости, расценивая это как нелегальное использование своих ресурсов. Для этого реализовано специальное ограничение скорости.
Например, попробуем скачать вышеуказанный URL без преобразования. Из консоли:
$ http --print=b --download 'https://rr1---sn-cxauxaxjvh-hn9ee.googlevideo.com/videoplayback?expire=1696595317&ei=FakfZ[и т. д.]'
И мы увидим, что скорость скачивания никогда не превышает 30−50 КБ/с:
Но на такой скорости наша лекция продолжительностью 1 ч 20 мин будет скачиваться примерно пять с половиной часов. Налицо явное несоответствие.
Похоже, в YouTube заложен лимит на скорость скачивания видео при запросе через API, а браузер обходит это ограничение. И наши любимые программки вроде
yt-dlp
тоже его обходят. Каким образом? Всё очень просто: оказывается, наш URL «ненастоящий», обманка, а для скачивания на нормальной скорости его требуется немножко изменить.▍ Взлом защиты
Как объясняет хакер 0x7D0 (вероятно, он входит в число контрибьюторов
yt-dlp
и/или NewPipe), в 2021 году в YouTube API появилась поддержка специального параметра n
в вышеуказанном URL (n: eCX-4hI1kOARp7xm
). Значение параметра должно быть преобразовано с помощью JS-алгоритма, приведённого в файле base.js
на веб-странице со встроенным плеером (мы же указали контекст, что выдаём себя за YouTube-плеер).Параметр представляет собой своего рода DRM, то есть проверку валидности сайта, на котором установлен плеер. Если URL не проходит проверку, то YouTube обрезает скорость скачивания, как в нашем примере.
Так что для скачивания файлов с YouTube на нормальной скорости без файла
base.js
не обойтись. Поскольку вышеупомянутый JS-алгоритм (DRM) обфусцирован и часто меняется, файл нужно постоянно скачивать с сайта YouTube или обновлять его в своей локальной версии, когда на сервере меняется проверка. Как вариант, 0x7D0 публикует JS-код для автоматического скачивания файла base.js
, извлечения кода алгоритма, передачи ему параметра n
и вычисления результата. Такой скрипт нужно запускать каждый раз, чтобы получить новый URL и скачать файл на нормальной скорости.
Скрипт для вычисления n
import axios from 'axios';
import vm from 'vm'
const videoId = 'aqz-KE-bpKQ';
/**
* From the Youtube API, retrieve metadata about the video (title, video format and audio format)
*/
async function retrieveMetadata(videoId) {
const response = await axios.post('https://www.youtube.com/youtubei/v1/player', {
"videoId": videoId,
"context": {
"client": { "clientName": "WEB", "clientVersion": "2.20230810.05.00" }
}
});
const formats = response.data.streamingData.adaptiveFormats;
return [
response.data.videoDetails.title,
formats.filter(w => w.mimeType.startsWith("video/webm"))[0],
formats.filter(w => w.mimeType.startsWith("audio/webm"))[0],
];
}
/**
* From the Youtube Web Page, retrieve the challenge algorithm for the n query parameter
*/
async function retrieveChallenge(video_id){
/**
* Find the URL of the javascript file for the current player version
*/
async function retrieve_player_url(video_id) {
let response = await axios.get('https://www.youtube.com/embed/' + video_id);
let player_hash = /\/s\/player\/(\w+)\/player_ias.vflset\/\w+\/base.js/.exec(response.data)[1]
return `https://www.youtube.com/s/player/${player_hash}/player_ias.vflset/en_US/base.js`
}
const player_url = await retrieve_player_url(video_id);
const response = await axios.get(player_url);
let challenge_name = /\.get\("n"\)\)&&\(b=([a-zA-Z0-9$]+)(?:\[(\d+)\])?\([a-zA-Z0-9]\)/.exec(response.data)[1];
challenge_name = new RegExp(`var ${challenge_name}\\s*=\\s*\\[(.+?)\\]\\s*[,;]`).exec(response.data)[1];
const challenge = new RegExp(`${challenge_name}\\s*=\\s*function\\s*\\(([\\w$]+)\\)\\s*{(.+?}\\s*return\\ [\\w$]+.join\\(""\\))};`, "s").exec(response.data)[2];
return challenge;
}
/**
* Solve the challenge and replace the n query parameter from the url
*/
function solveChallenge(challenge, formatUrl) {
const url = new URL(formatUrl);
const n = url.searchParams.get("n");
const n_transformed = vm.runInNewContext(`((a) => {${challenge}})('${n}')`);
url.searchParams.set("n", n_transformed);
return url.toString();
}
const [title, video, audio] = await retrieveMetadata(videoId);
const challenge = await retrieveChallenge(videoId);
video.url = solveChallenge(challenge, video.url);
audio.url = solveChallenge(challenge, audio.url);
console.log(video.url);
Примерно так же делает
yt-dlp
. Для решения этой задачи в программу встроен маленький интерпретатор JavaScript.После вычисления мы получаем новый «быстрый» URL. Интересно, что даже для него действуют ограничения скорости YouTube, чтобы она не превышала необходимой скорости для файла данного размера и качества, но
yt-dlp
успешно взламывает и это второе ограничение. Это делается простым добавлением к запросу параметра &range=start-end
. Файл разбивается на части, которые скачиваются одновременно. Простой параметр сразу кардинально увеличивает скорость, обычно до максимально возможной для вашего канала.Более подробно эта тема обсуждается в репозитории
yt-dlp
(issue 6400). Там обсуждение ведётся по-партизански: участники поясняют, что Google следит и за самим обсуждением, и за обновлениями yt-dlp
, и своевременно вносит изменения в работу YouTube API, чтобы противодействовать методам обхода ограничений.Потом скачанные фрагменты склеиваем в единое целое, при необходимости объединяя видео и звук. Вот почему
yt-dlp
не работает без установленного ffmpeg
(универсальная консольная утилита для обработки медиафайлов, см. «Безграничные возможности FFmpeg на примерах»). В документации FFmpeg написано, как склеить фрагменты одной командой. Проделав все эти шаги, мы можем скачивать видео с YouTube на высокой скорости даже без использования
yt-dlp
и др. ▍ Три года гонений
Как уже было сказано, юристы правообладателей пытаются всячески помешать работе альтернативных клиентов для YouTube. Хуже всего, когда изымаются домены, потому что тогда программа не может нормально обновиться или ломается какая-нибудь функциональность типа сообщений о багах. Остаётся только репозиторий на Github, который принадлежит Microsoft, так что хакерский софт там на птичьих правах.
Представим, что YouTube поменял API, в результате
yt-dl
скатился до зарезанной скорости. Пользователь идёт на официальный сайт за новой версией — и видит там такую картину:Конфискованный домен yt-dl.org. Он уже давно в таком состоянии
Юридическая атака на
youtube-dl
началась ровно три года назад, когда RIAA прислала DMCA-запрос на удаление репозитория на Github (его сначала удалили, а потом восстановили). И с тех пор youtube-dl
прессуют на всех фронтах.В данный момент битву против
youtube-dl
правообладатели могут при желании считать выигранной, они могут составить победные отчёты и получить заслуженные бонусы: количество пользователей и интенсивность разработки проекта упали. Но они не понимают, что всё это произошло, потому что вышел более продвинутый форк yt-dlp, который хостится на Github с множеством собственных форков. С 1200-ми контрибуторами он настолько активно поддерживается, что даже оригинальный yt-dl
бэкпортирует у него большинство своих исправлений. Другими словами, этот форк уже обогнал по популярности своего родителя (там 790 контрибуторов). Возможно, такое развитие событий напрямую связано с гонениями на оригинальную версию.Сравнение коммитов в мастер yt-dl (вверху) и yt-dlp (внизу)
Как уже было сказано, исходный код
youtube-dl
и yt-dlp
написан на Python. Поэтому программы работают в питоновской среде даже без компиляции. Они также распространяются через родной питоновский менеджер пакетов pip
. Хотя проще всего взять бинарники из официального репозитория на том же GitHub и использовать их без всяких зависимостей.▍ Дежа вю
Эта война копирастов из YouTube (Google) с якобы «пиратским» софтом выглядит довольно забавно, ведь на заре своего существования сам YouTube считался абсолютно пиратским. Как и российский стартап ВКонтакте, сразу после запуска он быстро набрал популярность за счёт того, что пользователи могли безнаказанно публиковать там нелицензионный контент: фильмы, сериалы, мультики и пр. И они там долго висели.
Например, в 2006 году редакторы Википедии обсуждали предложение удалить из энциклопедии все ссылки на YouTube, поскольку «львиная доля контента там является пиратским». Тогда YouTube особо не спешил бороться с этим явлением. Но спустя двадцать лет уже сам вошёл в число рьяных копирастов. Ничего не поделаешь, это капитализм. Ну а с ВК вообще всё понятно, сейчас нелицензионный контент в РФ почти официально разрешён. Говорят, в прошлом году даже в кинотеатрах крутили пиратки (только без рекламы 1xbet), может и сейчас где-то крутят, никто за это уже не будет особо карать.
▍ Выводы
В случае с нынешней историей основной вывод таков: программы для скачивания на самом деле реализуют базовые функции YouTube API, просто в таком виде, какой не нравится правообладателям. Но те ничего не могут поделать, потому что код программ открыт и способ реализации понятен, так что такие инструменты может сделать каждый и использовать их никто не запретит.
Наличие кучи «сервисов по загрузке видео» доказывает, что реализовать такой функционал довольно легко. Правда, есть нюансы, главный из которых — ограничение на скорость скачивания. Но всё можно решить. И в принципе можно спокойно обойтись даже без специальных инструментов вроде
yt-dlp
(но только с ограничением по скорости). Вот чтобы быстро скачивать без посторонних инструментов, придётся немножко заморочиться. В целом же, скачивать файлы с YouTube можно и самостоятельно.Узнавайте о новых акциях и промокодах первыми из нашего Telegram-канала 💰