Как написать свой клиент для YouTube, не привлекая внимания санитаров

от автора

Привет, Хабр! Когда‑то давно я наткнулся на ролик, где парень писал консольный клиент для YouTube. Идея была просто потрясающей! Написать свой минималистичный и быстрый клиент, который не будет надоедать лентами рекомендаций, рекламой и т. д.

Но вот беда, автор, не найдя возможности использовать YouTube API, решил спарсить одну из фронтенд обёрток над YouTube.

Стоит ли говорить о том, что такое решение сильно теряет в производительности и абсолютно нежизнеспособно на какой‑либо длительный период времени?

И вот относительно недавно я решил написать свой минималистичный ютуб клиент на базе Android приложения.

Часто бывает, что во время прогулок по городу хочется послушать ютуб в фоновом или в PiP режиме, не отвлекаясь от общения с друзьями в мессенджере.
Теперь это возможно!

YouTube в фоне доступен в магазине приложений RuStore

YouTube в фоне доступен в магазине приложений RuStore

В этой статье я хочу поделиться как бесплатно работать с YouTube API.

Как оказалось, для этого существует невероятно простая Python библиотека InnerTube:

Библиотека обрабатывает низкоуровневое взаимодействие с базовым API InnerTube, используемым каждой службой YouTube.

Что-то типа брутфорса*

Библиотека используется в основе известной утилиты yt-dlp

Приложение ViMusic также использует эту библиотеку и уже более двух лет работает без обновлений. Так что вcё надежно, как швейцарские часы!

Простой пример использования InnerTube. При выводе мы получим данные в формате JSON, которые в дальнейшем можно обработать по вашему усмотрению.

import innertube  client = innertube.InnerTube("WEB")  # Поиск списка видео по запросу client.search(query="уроки программирования на python")  # Получить данные для воспроизведения видео Rick Astley - Never Gonna Give You Up client.player(video_id="dQw4w9WgXcQ")

Тащить целиком эту библиотеку в наше Android приложение совсем необязательно.

Достаточно будет понять, какие параметры и тело запроса нам нужно передавать.
Если порыться в коде проекта InnerTube, то можно найти файл config.py с параметрами для создания запроса к WEB клиенту.

К слову, существует множество вариантов клиентов, таких как TVLITE, ANDROID, IOS и др.
У всех них будут разные версии, и где-то могут отличаться возвращаемые данные.

REFERER_YOUTUBE: str = "https://www.youtube.com/" USER_AGENT_WEB: str = (     "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36" )  config: Config = Config(     base_url="https://youtubei.googleapis.com/youtubei/v1/",     clients=[         ClientContext(             client_id=1,             client_name="WEB",             client_version="2.20230728.00.00",             user_agent=USER_AGENT_WEB,             referer=REFERER_YOUTUBE,             api_key="AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8",         )     ], )

Ну а теперь переходим к запросам из Android приложения. Стандартом для работы с сетью, естественно, является Retrofit.

Самым сложным для меня оказалось конвертировать JSON объект с 40 тысячами строк ответа в дата классы.

interface InnerTubeService {     @POST("v1/player")     suspend fun getPlayerInfo(@Body body: PlayerBody): Response<PlayerResponse>      @POST("v1/search?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8")     suspend fun searchVideos(@Body body: SearchBody): Response<SearchResponse> }  // Body для поиска видео по названию val searchBody = SearchBody(                 contentCheckOk = true, context = Context(                     client = Client(                         androidSdkVersion = 31,                         clientName = "WEB",                         clientScreen = "WATCH",                         clientVersion = "2.20230728.00.00",                         gl = "US",                         hl = "en"                     ), thirdParty = ThirdParty(embedUrl = "https://www.youtube.com/")                 ), playbackContext = PlaybackContext(                     contentPlaybackContext = ContentPlaybackContext(                         signatureTimestamp = 19250                     )                 ), racyCheckOk = true, query = query             )  //Body для получения данных проигрывателя val playerBody = PlayerBody(                 contentCheckOk = true, context = Context(                     client = Client(                         androidSdkVersion = 31,                         clientName = "TVLITE",                         clientScreen = "WATCH",                         clientVersion = "2",                         gl = "US",                         hl = "en"                     ), thirdParty = ThirdParty(embedUrl = "https://www.youtube.com/")                 ), playbackContext = PlaybackContext(                     contentPlaybackContext = ContentPlaybackContext(                         signatureTimestamp = 19250                     )                 ), racyCheckOk = true, videoId = videoId             )

Вот так выглядит ответ с потоковой ссылкой для просмотра.

data class PlayerResponse(val streamingData : StreamingData,                           val videoDetails : VideoDetails)  data class StreamingData(val formats : List<Formats>)  data class Formats(val itag : Long, val url : String)

Итог

Всё работает достаточно шустро и напрямую с YouTube API.

Я уже реализовал историю просмотра видео. В дальнейшем появятся плейлисты, будет переработан мини-плеер и др.

Спасибо за внимание! Надеюсь, что эта статья будет полезна и для ваших проектов.


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


Комментарии

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

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