Привет, Хабр! Когда‑то давно я наткнулся на ролик, где парень писал консольный клиент для 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.

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

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

Комментарии (49)


  1. Daddy_Cool
    16.05.2024 21:35
    +2

    Очень интересно! Я так понимаю в "Корпорации добра" очень неодобрительно смотрят на сторонние клиенты.
    https://www.ixbt.com/live/sw/v-youtube-opolchilis-na-prilozheniya-klienty-blokiruyuschie-reklamu-na-ploschadke-i-pochemu-eto-vazhno-dlya-rossiyskih-polzovateley.html
    "сервис представил новое решение — под запрет попадут и сторонние клиенты для YouTube, сами блокирующие рекламные вставки".
    Тот же NewPipe у меня через какое-то время переставал работать.


    1. zhirnoov Автор
      16.05.2024 21:35
      +2

      Мне писали, что у NewPipe особый алгоритм для работы с ютубом и где-то даже на гитхабе есть код. Что касается InnerTube, то это достаточно надежная библиотека, т.к она основана на брутфорсе. Фактически это тот же YouTube API.
      ViMusic (клон YouTube Music) работает без обновлений уже два года.
      Естественно в Google Play его никто не пустит.


      1. ferosod
        16.05.2024 21:35
        +7

        это достаточно надежная библиотека, т.к она основана на брутфорсе

        А есть подробности по этому пункту? "Надежность" и "брутфорс" звучит как что-то взаимоисключающее


        1. zhirnoov Автор
          16.05.2024 21:35
          +2

          Всего лишь мои домыслы. Глубокий анализ я не проводил.
          Если найдете информацию, то с радостью сам ознакомлюсь.
          Я сужу по тому, что библиотека существует уже 3,5 года.
          Google легко может грохнуть yt-dlp, на котором держатся вообще все онлайн загрузчики видео. Только почему-то этого не происходит.
          Полагаю, если они пофиксят эту лазейку, то похерят просмотр видео на множеств устройств, вероятно на очень старых.


          1. ogost
            16.05.2024 21:35
            +2

            С yt-dlp гугл вяло, но борется. youtube время от времени меняет апи, или снижает до минимума трафик по user-agent или как-то по другому вставляет им палки в колёса, но ребяты оперативно обновляют. Сам yt-dlp - это форк от youtube-dl, который забросили то ли из-за угроз от гугла, то ли просто устали обновлять при каждом чихе ютуба.


            1. 13werwolf13
              16.05.2024 21:35
              +1

              там всё очень мутно
              гугл вроде бы как борется с yt-dlp и youtube-dl, но при этом сотрудники гугла и помогают разрабам и вроде даже коммитят изредка (не фактчекал, знаю только со слов человека имеющего некое отношение к проекту).
              там либо левая рука не знает что делает правая, либо "7 пятниц на неделе"..


              1. iqp
                16.05.2024 21:35
                +1

                там либо левая рука не знает что делает правая, либо "7 пятниц на неделе"..

                Как вариант "не можешь победить, возглавь"


              1. DeskundigeICT
                16.05.2024 21:35
                +1

                На самом деле, гигантские корпорации, правда, имеют конкурирующие команды разработки, скупают кучу других стартапов и действуют скорее как экосистема, а не единый организм.

                Я лично видел как разработчики Гугла участвовали в нелегальном портировании Chrome OS (со всеми плюшками вроде Google Play и Assistant) на обычные ПК (не хромбуки). Проект назывался Croissant, после смены архитектуры- Brunch.


        1. ZetaTetra
          16.05.2024 21:35
          +1

          Куда уж надёжней брутфорса, главное чтобы времени хватило...

          Китайцы взломали сервер Пентагона, вот как это было:

          1. Каждый китаец попробовал один пароль.

          2. Каждый второй пароль был "Мао Цзедун"

          3. На 74357181-й попытке- сервер согласился, что у него пароль "Мао Цзедун"


    1. ZetaTetra
      16.05.2024 21:35

      Оригинал: https://support.google.com/youtube/thread/269521462/enforcement-on-third-party-apps

      Viewers who are using these third-party apps may experience buffering issues or see the error “The following content is not available on this app” when trying to watch a video

      Не запрет, а косяки при просмотре.


    1. un1t
      16.05.2024 21:35

      С ньюпайпом есть глюк. Он парсит страницу ютюба со ссылками на потоки, но они протухают через 4 часа. Если продолжить смотреть видео позже, то там вываливается ошибка. Но там можно куда-то тыкнуть и оно продолжит играть. Он работает я им пользуюсь. Только этот глюк раздражает.


  1. un1t
    16.05.2024 21:35
    +2

    1) Если тыкнуть на плеер в шторке уведомлений, то сам плеер не открывается.

    2) В шторке уведомлений только две кнопки плей/пауза и переметка назад. Мне бы хотелось там увидеть кнопки проматывающие на несколько секунда назад и на несколько секунд вперед. Например т.к. это сделано в полноразмерном плеере. В идеале, чтобы время насколько проматывается можно было менять в настройках.


    1. zhirnoov Автор
      16.05.2024 21:35
      +1

      Окей, понял. Доработаю.


  1. jonic
    16.05.2024 21:35
    +1

    В рутубе это и так работает. Да и в ютубе тоже.


    1. zhirnoov Автор
      16.05.2024 21:35
      +1

      В ютубе только для премиум версии, которая в России с 2022 года недоступна.


      1. jonic
        16.05.2024 21:35

        Попросите друга с iOS купить вам подписку и кидайте ему 249 рублей в месяц на телефон


        1. borisphen2001
          16.05.2024 21:35

          Даже имея премиум подписку, при запуске Ютуба без впн вылазит полноэкранное предупреждение, о том что премиум функции не будут работать. Ну хоть без рекламы, уже хорошо.


          1. jonic
            16.05.2024 21:35
            +1

            Да блин, как оно у меня работает то тогда?


          1. ilyamodder
            16.05.2024 21:35

            Ничего там не вылазит, сам пользуюсь, оплачивая именно через iOS.


  1. Dolios
    16.05.2024 21:35

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

    Так это много лет уже возможно с подпиской. Вот что в ютубе через жж сделано, так это подписки на каналы - все в одной куче без возможности как-то по папкам/группам их разложить.


    1. zhirnoov Автор
      16.05.2024 21:35
      +1

      возможно с подпиской

      Доступно не только лишь для всех. Для россиян с 2022 года недоступно.

      По подпискам на каналы интересно. Если доберусь, то может что-то такое и реализую.
      Только как вариант без авторизации и аккаунта. Т.е все подписки хранить в БД на устройстве пользователя.


      1. Dolios
        16.05.2024 21:35
        +1

        Кстати, был же ещё Vanced, он тоже вроде фоновый режим умел, если я не путаю. Вы его смотрели?


        1. ogost
          16.05.2024 21:35

          емнип заброшен много лет назад.


          1. shaseer
            16.05.2024 21:35
            +6

            Закрыт по требованию Гугла, но есть форк - ReVanced


          1. gudvinr
            16.05.2024 21:35

            Не заброшен, а прижат гуглом, когда они решили собирать донаты

            После этого перезапустили в виде фреймворка для патчинга андроид приложений - ReVanced

            Принципиальный нюанс - приложения патчатся на устройстве пользователя


    1. vikarti
      16.05.2024 21:35
      +1

      Вы еще скажите что покупки в Google Play везде работают.


      1. Dolios
        16.05.2024 21:35

        Как будто большая проблема стать для гугла аргентинским кабальеро...


        1. 13werwolf13
          16.05.2024 21:35
          +7

          технически - никаких проблем. но принципиально делать этого не буду. я готов платить, если не хотят брать деньги это их проблемы, буду брать бесплатно. где это видно чтобы покупатель за продавцом бегал и уговаривал взять деньги, силой в карман пихал.


        1. un1t
          16.05.2024 21:35
          +1

          А что там Аргентина россиянам карты выдает удаленно? Или вы о чем? Я конечно знаю, что можно сделать карту в Казахстане, но ехать туда чисто ради карты не хочу и платить посредникаи 20к тоже не хочу.


          1. Dolios
            16.05.2024 21:35

            Аргентина, это регион с ценами, близкими к российским. Рабочую карту я бы порекомендовал иметь на случай экстренной эвакуации.


            1. un1t
              16.05.2024 21:35

              Непонятно почему Аргентина? Можно получить аргентинскую карту удаленно?


              1. Dolios
                16.05.2024 21:35

                Аргентина, это регион с ценами, близкими к российским.

                Какое именно слово в этой фразе вам не понятно?

                Можно получить аргентинскую карту удаленно?

                Аргентинская карта не требуется, подойдёт любая карта, которая принимается в мире.


  1. jackcrane
    16.05.2024 21:35
    +1

    как бы еще смотреть комментарии под некоторыми видео (не привлекая внимание сантиаров ест-но) ?


    1. zhirnoov Автор
      16.05.2024 21:35
      +1

      У InnerTube есть и на этот случай есть пример кода (сам не тестировал, но вариант свежий).
      Если не секрет, то для чего это вам? Собиратесь парсить комментарии?


      1. jackcrane
        16.05.2024 21:35

        в питоне не силен. хочу почитать что накидали в комменты к ранним роликам одному конспирологу и историчскому ревизионисту.


  1. vedmak3
    16.05.2024 21:35
    +2

    Могу посоветовать обратить внимание на оригинал решения, а именно youtube-dl. А если быть еще точнее, то сюда https://github.com/ytdl-org/youtube-dl/blob/master/youtube_dl/extractor/youtube.py


  1. D7ILeucoH
    16.05.2024 21:35
    +3

    Выглядит как ненужный велосипед. Есть бесплатный Vanced/ReVanced, который умеет ещё и не скачивать видео, если вы слушаете музыку в фоне - экономит трафик. Если хочешь сделать что-то полезное, лучше выкати ПР со своей идеей в этот проект.


    1. nixtonixto
      16.05.2024 21:35

      Revanced требует авторизацию через MicroG, т.е. есть риск слить аккаунт. Но в остальном - очень достойная замена официальному приложению.


    1. nitro80
      16.05.2024 21:35

      Пользуюсь SmartTube, умеет пропускать рекламу, вступления и пр.


  1. ris58h
    16.05.2024 21:35
    +3

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

    Смотрю YouTube на мобилке в браузере: Firefox (Android) или Orion (iOS). Установлены расширения uBlock и Video Background Play Fix. Полёт нормальный.


    1. SnakeSolid
      16.05.2024 21:35

      У меня тоже Firefox, из расширений стоит только uBlock. После блокировки видео ставится на паузу, но его можно запустить/остановить с экрана блокировки как в обычном плеере.


      1. ris58h
        16.05.2024 21:35
        +2

        Я ж написал: Video Background Play Fix.


  1. ris58h
    16.05.2024 21:35

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

    Каким местом это брутфорс? Просто внутренний API используемый YouTube. Я в своих расширениях его тоже использую. Кстати, пару недель назад они поломали обратную совместимость своими изменениями, но этого стоит ожидать - на то он и внутренний API.


  1. minaevmike
    16.05.2024 21:35

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

    Но эта возможность есть и в стандартном плеере Ютуба, если не жлобить 200р в месяц


    1. Kasyan666
      16.05.2024 21:35

      А что делать половине планеты, где Premium не доступен? Казахстану, например?


      1. Elendiar1
        16.05.2024 21:35

        Установить revanced extended?


        1. Kasyan666
          16.05.2024 21:35
          +1

          Это понятно и правильно. Но, я про "жлобить 200р в месяц" писал.


      1. Dolios
        16.05.2024 21:35

        1. Kasyan666
          16.05.2024 21:35
          +2

          Каюсь, пропустил, но что делать остальным

          110 странам?
          • Afghanistan

          • Albania

          • Botswana

          • Brunei

          • Burkina Faso

          • Burundi

          • Cape Verde (Cabo Verde)

          • Central African Republic

          • Chad

          • China

          • Comoros

          • Congo (Congo-Brazzaville)

          • Côte d’Ivoire

          • Cuba

          • Democratic Republic of the Congo

          • Djibouti

          • Dominica

          • Equatorial Guinea

          • Eritrea

          • Eswatini (formerly Swaziland)

          • Ethiopia

          • Fiji

          • Gabon

          • Gambia

          • Grenada

          • Guinea

          • Guinea-Bissau

          • Guyana

          • Haiti

          • Holy See (Vatican City)

          • Kiribati

          • Kyrgyzstan

          • Lesotho

          • Liberia

          • Madagascar

          • Malawi

          • Maldives

          • Mali

          • Marshall Islands

          • Mauritania

          • Mauritius

          • Micronesia

          • Moldova

          • Monaco

          • Mongolia

          • Mozambique

          • Myanmar (formerly Burma)

          • Namibia

          • Nauru

          • Niger

          • North Korea

          • Palau

          • Palestine State

          • Papua New Guinea

          • Rwanda

          • Saint Kitts and Nevis

          • Saint Lucia

          • Saint Vincent and the Grenadines

          • Samoa

          • San Marino

          • Sao Tome and Principe

          • Seychelles

          • Sierra Leone

          • Solomon Islands

          • Suriname

          • Syria

          • Tajikistan

          • Timor-Leste

          • Togo

          • Tonga

          • Turkmenistan

          • Tuvalu

          • Uganda

          • Uzbekistan

          • Vanuatu

          • Venezuela

          • Western Sahara

          • Yemen

          • Zambia

          • Zimbabwe

          Я думаю, многие их жители и рады бы "не жлобить 200р в месяц", да, вот паспортом не вышли. Так, что, эта ситуация не всегда о "жлобстве".