Расширение для скачивания видео с VK в один клик. Теперь и для desktop-а

—

от автора

Всем привет! Недавно публиковал статью о создании браузерного расширения для скачивания любого видео загруженного во ВКонтакте в любом из доступных качеств.

На тот момент всё ограничилось возможностью скачивания лишь с мобильной версии сайта, так как из неё проще всего вытащить прямые ссылки на .mp4 файлы. Впрочем, не буду повторять всё то, что было сказано в первой статье. Настоятельно рекомендую потратить несколько минут и сначала прочесть её, а затем вернуться сюда. Иначе Вы рискуете не понять некоторых моментов и можете посчитать данную статью поверхностной.

На этом со вступлением всё. Перейдём к сути. Вчера у меня всё же дошли руки до того, чтобы заставить расширение работать и на полной версии сайта. И вот как я это сделал.

Выясняем как всё устроено

В предыдущий раз алгоритм действий был следующим:

  • Смотрим в исходный код страницы

  • Видим в нём тег <video> со вложенными тегами <source>

  • Вытаскиваем ссылки на файлы интересующего нас формата

  • Мы великолепны

Попробовав повторить эти пункты мы зависнем на втором, обнаружив вот это:

<div class="videoplayer">   <div class="videoplayer_media">     <video src="blob:https://vk.com/ca08cc90-10c4-444f-a1bd-004ef4a2057d"></video>   </div> </div>

Да, никаких привычных глазу форматов, только Binary Large Object. Если не вдаваться в детали — мы имеем дело с потоковым видео, которое отдаётся сервером в режиме реального времени небольшими чанками. Этот Большой Бинарный Объект и есть один из таких чанков.

Существуют способы скачивания подобных данных, в том числе с помощью такого софта как ffmpeg и VLC Media Player, но мы ведь не хотим этим заниматься, правда? Переключиться на мобильную версию VK и скачать видео с неё — дело пары кликов, а мы хотим упростить процесс, а не усложнять его.

Немного пошевелив мозгами и поглядев на монструозные исходники фронтенда VK я пришёл к мысли, что где-то ссылки на .mp4 файлы всё же должны храниться. Нутром чую, что должны. Не особо надеясь на положительный исход я приступил к поискам и через 10-15 минут они увенчались успехом.

Давайте запустим любое видео и выведем в консоль браузера один интересный объект: window.mvcur.player.vars. Среди десятков его полей будут в том числе вот такие:

{   "url360": "https://vkvd39.mycdn.me/...type=1&amp;...",   "url480": "https://vkvd39.mycdn.me/...type=2&amp;...",   "url720": "https://vkvd39.mycdn.me/...type=3&amp;..." }

Такие знакомые ссылки с таким знакомым параметром type. Замечательно. Переходим к следующему шагу.

Вырываемся из клетки

Казалось бы — бери ссылки, отображай их под видео и дело сделано. Но не всё так просто. Скрипты каждого отдельного браузерного расширения выполняются в так называемом изолированном окружении. Они не имеют доступа к уже существующим на странице JavaScript-объектам и каким-либо данным из других расширений. Чтобы «достучаться» до нужных нам свойств объекта window мы выполним JavaScript-инъекцию.

Для начала добавим в manifest.json правило, для исполнения содержимого файла scripts/desktop.js при переходе на любую страницу на домене vk.com:

"content_scripts": [   {     "js": ["scripts/desktop.js"],     "matches": ["https://vk.com/*"],     "run_at": "document_idle"   } ]

Также дадим расширению доступ к файлу со скриптом, инъекцию которого мы будем осуществлять:

"web_accessible_resources": [   {     "resources": ["scripts/desktop-injection.js"],     "matches": ["https://vk.com/*"]   } ]

Реализуем элементарную инъекцию:

// scripts/desktop.js  const script = document.createElement('script'); script.charset = 'utf-8'; script.type = 'text/javascript'; script.src = chrome.runtime.getURL('scripts/desktop-injection.js'); document.querySelector('body').appendChild(script);
// scripts/desktop-injection.js  (() => {   alert('скрипт (кродеться)'); })();
Прокрался

Прокрался

Достигаем цели

Извлечём ссылки на видео и скомпонуем их в точно такой же блок, как и в мобильной версии VK:

// scripts/desktop-injection.js  let videoSources = {   '144p': window.mvcur.player.vars.url144,   // Все остальные качества    '2160p': window.mvcur.player.vars.url2160 };  const label = document.createElement('span'); label.innerText = 'Скачать:'; label.style.marginRight = '2px';  const panel = document.createElement('div'); panel.id = 'vkVideoDownloaderPanel'; panel.appendChild(label);  for (const [quality, url] of Object.entries(videoSources)) {   if (typeof url !== 'undefined') {     const aTag = document.createElement('a');     aTag.href = url;     aTag.innerText = quality;     aTag.style.margin = '0 2px';     panel.appendChild(aTag);   } }

Невырвиглазно отобразим на странице:

// scripts/desktop-injection.js  /*  * Не под всеми видео есть блок с названием. * Если он есть - располагаем ссылки над ним. * Иначе - над блоком с кнопками лайка, репоста и т.п. * Таким образом ссылки всегда будут находиться сразу под плеером. */ const videoTitleBlock = document.querySelector('div.mv_title_wrap'); if (videoTitleBlock) {   panel.style.margin = '8px 0';   videoTitleBlock.before(panel); } else {   panel.style.margin = '8px 15px';   document.querySelector('div.mv_actions_block').before(panel); }

Весь код в scripts/desktop.js по сути идентичен тому, что использовался для мобильной версии VK в первой статье: мониторинг отрисовки контейнера плеера, «переходов» между страницами и т. д. Добавил разве что дополнительный логический флаг, чтобы функция парсинга и отображения ссылок не вызывалась более одного раза да немного изменил механизм определения того, находимся ли мы на странице с видео.

Результат

Результат

Ознакомиться с полным исходным кодом и скачать расширение можно в репозитории на моём GitHub. Если столкнётесь с какими-то проблемами, буду рад Вашим баг-репортам в issues. Также, если у Вас есть аккаунт — буду признателен за звёздочку 🙂

Спасибо, что дочитали до конца.


ссылка на оригинал статьи https://habr.com/ru/articles/731078/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *