iv-org / invidious

Invidious is an alternative front-end to YouTube
https://invidious.io
GNU Affero General Public License v3.0
16.01k stars 1.75k forks source link

[Findings / future enhancement?] Onesie playback (/initplayback) method of getting video playback links #2711

Open coletdjnz opened 2 years ago

coletdjnz commented 2 years ago

I notice the TV web client (TVHTML5) is currently undergoing an A/B test where the /player endpoint is not used, rather some "onesie" method is used using /initplayback google video URL to get the playback data. I don't really understand how this works, and it seems very obfuscated. As requested I am posting what I've seen here.

It sounds like this method is already used in the Android app for at least the past half year.


Steps to get a reproducible session

Since this is an A/B test, this will only happen sometimes.

  1. set user agent to some TV client (in my user agent switcher I set it to PS4, any will probably do)
  2. go to https://www.youtube.com/tv#/. if working correctly it will not redirect to the desktop site
  3. Look for a request to https://www.youtube.com/tv_config. In the response you should see onesieHotConfig key. If not, create a new session/clear cookies and retry from 2) again
  4. When clicking on a video, you should see request(s) to /initplayback and not /player*

*except for home page, they still seem to use /player for the ad or whatever?


Request

There is a POST request to the baseUrl (see config below).

The response also is encoded in some unknown format. The response Content-Type header says "application/vnd.yt-ump" There does seem to be hints of plaintext data in it, I can see parts of the video playback url subdomain:

...º..
.GV..th2tVl-gfEw
....*cf.sn-npo6e7s,ocb.1838531,ocbs.1,ups_r.254
:.."6" 7[.!û..Å.*.#¾.Õ%..ksÙ2¸j¶?5¼.ÎJ.*.*.Pètõ_$.¾2ÿ°ä.Ú

There is also periodic requests to the baseUrl with no data. It responds with 204 no content. Might be related to the generate_204 requests seen in the WEB client?

Config

The onesieHotConfig contains the following data:

"onesieHotConfig": {
        "clientKey": "XXX (base 64 encoded)",
        "encryptedClientKey": "XXX (base 64 encoded)",
        "keyExpiresInSeconds": 259200,
        "onesieUstreamerConfig": "gAEAqAEB0AIBgAQB4AQB+gSwASUAAIA/LVK4Xj81PQqXP1gBYAFyGQoVbWZzMl9jbWZzX2g1X3YzXzFfMDY1IAF48AGAAQHaAigQsOoBGKhGKNg2MJh1SAFQAVgBaAFwiCeAAfQDmAEBoAEB4AEB8AEB+gIyCGQQZBhkIGQtAABwQjUAAIxCSAFlAACAQGjAcIgBAZABZJgBZKUBAAAAP7AB4AO4AQGIAwGYAwGwAwC4AwHIAwHgA5BO8AMB+AMBuAQBkAUBqAUBsAUByAXg1APQBegH8AUB",
        "baseUrl": "/initplayback?source=youtube&orc=1&oeis=1&ip=XXX.XXX.XXX.XXX&c=TVHTML5&oad=3200&ovd=3200&oaad=11000&oavd=11000&ocs=700&oewis=1&oputc=1&ofpcc=1&msp=1&odeak=1&odepv=1&osfc=1"
    },

These values all have references throughout the player js (for both tv client and web client). There are references to hmac and IV too. Possibly this method uses some sort of encryption somewhere. https://www.youtube.com/s/player/a515f6d1/tv-player-ias.vflset/tv-player-ias.js

This may have some relation to the youtubei/v1/config Innertube endpoint, which seems to provide some sort of protobuf-encoded "hot" and "cold" config data. I can confirm this is used on the android embedded player, though I'm not entirely sure if it is related to the onesie playback method.

curl --request POST \
  --url 'https://youtubei.googleapis.com/youtubei/v1/config?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8' \
  --header 'Content-Type: application/json' \
  --data '{
    "context": {
        "client": {
            "clientName": "ANDROID_EMBEDDED_PLAYER",
            "clientVersion": "16.20",
            "hl": "en"
    }
}
}'

I don't know how the android app gets the config data.

/player ep response mention of onesie

There are references to this onesie playback method in the /player call. In android client response, there is a "onesieStreamingUrl":

"watchEndpoint": {
                "videoId": "w2eWEhDHhFo",
                "watchEndpointSupportedOnesieConfig": {
                  "playbackOnesieConfig": {
                    "url": "https://r2---sn-npoe7nez.googlevideo.com/initplayback?source=youtube&orc=1&oeis=1&c=ANDROID&oss=1&oda=1&oad=7000&ovd=7000&oaad=11000&oavd=11000&ocs=550&oewis=1&ohct=2&oaf1=1&oputc=1&ofpcc=2&osbr=1&osnz=1&obbl=24576&msp=1&odeak=1&odepv=1&osfc=1&id=c367961210c7845a&ip=XXX.XXX.XXX.XXX&initcwndbps=300000&mt=1639104053&oweuc=EiRFTU5SRVpnNk1UNXB1Z09WVC9Ld2tma1NFNDR0bHBJRklvRmIYAA%3D%3D&pxtags=Cg4KAnR4EggyNDAwODEwOA&rxtags=Cg4KAnR4EggyMzk5Nzk3MA%2CCg4KAnR4EggyNDAwODEwOA",
                    "exoPlayerInitConfig":

On WEB client, there is mention of an "HTML5 playback onesie":

"watchEndpoint": {
                    "videoId": "yoazYzO0E-g",
                    "watchEndpointSupportedOnesieConfig": {
                      "html5PlaybackOnesieConfig": {
                        "commonConfig": {
                          "url": "https://r3---sn-npoe7ne6.googlevideo.com/initplayback?source=youtube&orc=1&oeis=1&c=WEB&oad=3200&ovd=3200&oaad=11000&oavd=11000&ocs=700&oewis=1&oputc=1&ofpcc=1&msp=1&odeak=1&odepv=1&osfc=1&id=ca86b36333b413e8&ip=XXX.XXX.XXX.XXX&initcwndbps=2582500&mt=1639102610&oweuc="
                        }
                      }
                    }
                  }

Similar thing sometimes appears in the TVHTML5 player response (A/B testing again?)

Hopefully someone might be able to figure out what is going on :sweat_smile:

SamantazFox commented 2 years ago

Thanks for reporting your finding :)