Skip to content

Instantly share code, notes, and snippets.

@LuanRT
Last active July 1, 2024 03:35
Show Gist options
  • Save LuanRT/9c7be4af538d424ff44ce38e9d06c700 to your computer and use it in GitHub Desktop.
Save LuanRT/9c7be4af538d424ff44ce38e9d06c700 to your computer and use it in GitHub Desktop.
Getting YouTube's script & css URLs from `/app_shell`
import * as ResourceManifest from './messages/youtube/ResourceManifest.js';
const appShellResponse = await fetch("https://www.youtube.com/app_shell", {
headers: {
"service-worker-navigation-preload": "true",
},
method: "GET"
});
if (!appShellResponse.ok)
throw new Error("Failed to fetch app shell");
// Because this is supposed to be used in a service worker, the response body is empty. The headers contain the data we want.
const resourceManifest = appShellResponse.headers.get('x-resource-manifest');
function base64ToU8(base64: string): Uint8Array {
return Uint8Array.from(atob(base64), c => c.charCodeAt(0));
}
const manifest = ResourceManifest.decodeBinary(base64ToU8(decodeURIComponent(resourceManifest)));
console.info(manifest);
{
urls: [
{
url: 'https://www.youtube.com/s/player/5b22937f/player_ias.vflset/en-US/base.js'
},
{
url: 'https://www.youtube.com/s/desktop/28bb7000/jsbin/web-animations-next-lite.min.vflset/web-animations-next-lite.min.js'
},
{
url: 'https://www.youtube.com/s/desktop/28bb7000/jsbin/webcomponents-all-noPatch.vflset/webcomponents-all-noPatch.js'
},
{
url: 'https://www.youtube.com/s/desktop/28bb7000/jsbin/fetch-polyfill.vflset/fetch-polyfill.js'
},
{
url: 'https://www.youtube.com/s/desktop/28bb7000/jsbin/intersection-observer.min.vflset/intersection-observer.min.js'
},
{
url: 'https://www.youtube.com/s/desktop/28bb7000/jsbin/scheduler.vflset/scheduler.js'
},
{
url: 'https://www.youtube.com/s/desktop/28bb7000/jsbin/www-i18n-constants-en-US.vflset/www-i18n-constants.js'
},
{
url: 'https://www.youtube.com/s/desktop/28bb7000/jsbin/www-tampering.vflset/www-tampering.js'
},
{
url: 'https://www.youtube.com/s/desktop/28bb7000/cssbin/www-main-desktop-home-page-skeleton.css'
},
{
url: 'https://www.youtube.com/s/desktop/28bb7000/cssbin/www-onepick.css'
},
{
url: 'https://www.youtube.com/s/_/ytmainappweb/_/ss/k=ytmainappweb.kevlar_base.YSrhXbQn4yo.L.X.O/am=AAABWg/d=0/br=1/rs=AGKMywHRsn6N1PzL9qt2Miw8LXsmp_TMww'
},
{
url: 'https://www.youtube.com/s/desktop/28bb7000/jsbin/desktop_polymer_legacy_browsers.vflset/desktop_polymer_legacy_browsers.js'
},
{
url: 'https://www.youtube.com/s/desktop/28bb7000/cssbin/www-main-desktop-watch-page-skeleton.css'
},
{
url: 'https://www.youtube.com/s/desktop/28bb7000/jsbin/www-searchbox.vflset/www-searchbox.js'
},
{
url: 'https://www.youtube.com/s/player/5b22937f/player_ias.vflset/en-US/captions.js'
},
{
url: 'https://www.youtube.com/s/player/5b22937f/player_ias.vflset/en-US/endscreen.js'
},
{
url: 'https://www.youtube.com/s/player/5b22937f/player_ias.vflset/en-US/offline.js'
},
{
url: 'https://www.youtube.com/s/player/5b22937f/player_ias.vflset/en-US/miniplayer.js'
},
{
url: 'https://www.youtube.com/s/player/5b22937f/player_ias.vflset/en-US/remote.js'
},
{ url: 'https://www.youtube.com/s/player/5b22937f/www-player.css' },
{
url: 'https://www.youtube.com/s/desktop/28bb7000/img/favicon.ico'
}
]
}
syntax = "proto2";
package youtube;
message UrlItem {
string url = 1;
}
message ResourceManifest {
repeated UrlItem urls = 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment