Skip to content

Instantly share code, notes, and snippets.

@geuis
Last active January 10, 2024 16:43
Show Gist options
  • Save geuis/8b1b2ea57d7f9a9ae22f80d4fbf5b97f to your computer and use it in GitHub Desktop.
Save geuis/8b1b2ea57d7f9a9ae22f80d4fbf5b97f to your computer and use it in GitHub Desktop.
Get Youtube video urls
// Run from the dev tools console of any Youtube video
// Accurate as of July 2, 2020.
//
// Copy and paste this into the dev console in a browser with the desired video loaded.
//
// NOTE: Some Youtube videos do not directly expose the video url in the response.
// This script doesn't currently attempt to handle those. It will work for most other general video types though.
(async () => {
const html = await fetch(window.location.href).then((resp) => resp.text()).then((text) => text);
const startStr = 'ytplayer.config = {';
const start = html.indexOf(startStr) + startStr.length - 1;
const end = html.indexOf('};', start) + 1;
const playerObj = JSON.parse(html.slice(start, end));
playerObj.args.player_response = JSON.parse(playerObj.args.player_response);
const videoUrls = playerObj.args.player_response.streamingData.adaptiveFormats.reduce((acc, item) => {
if (!acc[item.quality]) {
acc[item.quality] = {};
}
const mimeType = item.mimeType.split(';')[0];
acc[item.quality][mimeType] = item;
return acc;
}, {});
console.log('!!', videoUrls);
})();
@guilhermemarconi
Copy link

Can I test this without the ytplayer?

I'm using React to create my own component (slider with video) and I don't think ytplayer is the best tool now, because it's too much just to get YouTube video URL.

You know some way to do that with only the video id?

@abbddo
Copy link

abbddo commented Jul 1, 2017

@gtkpr
Copy link

gtkpr commented Jul 22, 2017

this technique only provides you with separate video and audio files

@gtkpr
Copy link

gtkpr commented Jul 24, 2017

this script only works when the user loads a video url directly, instead of using YT internal navigation. in other words, you have to refresh the page on every video you wish to download in order to gain access to adaptive_fmts

@chay22
Copy link

chay22 commented Sep 14, 2017

I can't find adaptive_fmts but url_encoded_fmt_stream_map under args object and everything is working as pointed.
ytplayer.config.args.url_encoded_fmt_stream_map

@towfiqi
Copy link

towfiqi commented Feb 27, 2018

Doest work anymore in 2018

@Viktor19931
Copy link

ytplayer.config.args.url_encoded_fmt_stream_map doesnt work at mobile version of youtube.

@Viktor19931
Copy link

Does someone know how to get direct url on mobile version of youtube ?

@darkov19
Copy link

Uncaught TypeError: Cannot read property 'split' of undefined
at youtubedl.js:15

@geuis
Copy link
Author

geuis commented Jan 6, 2020

@ViralShastri review the updated script.

@nysander
Copy link

in what language is it written in? I need to rewrite it to swift

@geuis
Copy link
Author

geuis commented Jan 20, 2020

@nysander its javascript.

@roffe
Copy link

roffe commented Feb 15, 2020

does not work on for example https://www.youtube.com/watch?v=IcrbM1l_BoI

VM780:13 Uncaught (in promise) TypeError: Cannot read property 'split' of undefined
at :13:6

@yair-man
Copy link

Where do I put this code?

@geuis
Copy link
Author

geuis commented Mar 14, 2020

@yair-man its in the very first line

@Joshuajrodrigues
Copy link

Uncaught TypeError: Cannot read property 'split' of undefined
at :2:4

got this when i tired it out in console

@jarvis1234d
Copy link

Uncaught (in promise) TypeError: Cannot read property 'split' of undefined
It shows this error everytime I run it.
I get the url of the page when by using window.location.href but I need the url which contains other properties such as screen-resolution, frame-rate, bit-rate , etc.

I also tried using ifram api by using src="https://www.youtube.com/get_video_info?video_id={videoId}" but the file which it returns gives this error status=fail&errorcode=2&reason=Invalid+parameters..

Please help if you can.

@geuis
Copy link
Author

geuis commented Jul 3, 2020

@Joshuajrodrigues @jarvis1234d script is now updated. Try it out.

@serjmac
Copy link

serjmac commented Aug 6, 2020

It works with the updated july 2nd script, thank you @geuis

however the url from every object only contains video stream. Is there a way to get the url for a full video+audio stream?

@realrecordzLab
Copy link

After running the script what's the field that hold the url? I suppose that is the one named signatureCypher ? It starts with "s=yy.." so how to extract the url?

@3Samourai
Copy link

For Download video with audio

(async () => {
  html = await fetch(window.location.href).then(resp => resp.text()).then(text => text);
  startStr = 'ytplayer.config = {';
  start = html.indexOf(startStr) + startStr.length - 1;
  end = html.indexOf('};', start) + 1;
  playerObj = JSON.parse(html.slice(start, end));
  playerObj.args.player_response = JSON.parse(playerObj.args.player_response);
  videoUrls = playerObj.args.player_response.streamingData.formats[1].url;
  videoUrls = videoUrls.replace('"', 'r');
  return console.log(videoUrls);
})();

@Christopher-CO
Copy link

For Download video with audio

(async () => {
  html = await fetch(window.location.href).then(resp => resp.text()).then(text => text);
  startStr = 'ytplayer.config = {';
  start = html.indexOf(startStr) + startStr.length - 1;
  end = html.indexOf('};', start) + 1;
  playerObj = JSON.parse(html.slice(start, end));
  playerObj.args.player_response = JSON.parse(playerObj.args.player_response);
  videoUrls = playerObj.args.player_response.streamingData.formats[1].url;
  videoUrls = videoUrls.replace('"', 'r');
  return console.log(videoUrls);
})();

Thank you, this works great!

@realrecordzLab
Copy link

realrecordzLab commented Nov 17, 2020

For Download video with audio

(async () => {
  html = await fetch(window.location.href).then(resp => resp.text()).then(text => text);
  startStr = 'ytplayer.config = {';
  start = html.indexOf(startStr) + startStr.length - 1;
  end = html.indexOf('};', start) + 1;
  playerObj = JSON.parse(html.slice(start, end));
  playerObj.args.player_response = JSON.parse(playerObj.args.player_response);
  videoUrls = playerObj.args.player_response.streamingData.formats[1].url;
  videoUrls = videoUrls.replace('"', 'r');
  return console.log(videoUrls);
})();

Thank you, this works great!

I've tried the script but I get a reject in promise. Seems not working. TypeError: Cannot read property 'url' of undefined↵ at <anonymous>:8:71

@tcarroll2
Copy link

in what language is it written in? I need to rewrite it to swift

@nysander - did you ever get this converted to Swift?

@nysander
Copy link

in what language is it written in? I need to rewrite it to swift

@nysander - did you ever get this converted to Swift?

Nope because Apple is very strict with playback rights and I have dropped idea of this script in my app

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment