Skip to content

Instantly share code, notes, and snippets.

@lekoOwO
Last active July 19, 2024 19:30
Show Gist options
  • Save lekoOwO/c90c09409446e6c7663c489bf06dc649 to your computer and use it in GitHub Desktop.
Save lekoOwO/c90c09409446e6c7663c489bf06dc649 to your computer and use it in GitHub Desktop.
Get Youtube freg. URLs
javascript:(async()=>{function a(a){if(!a.includes("."))return a;return a.match(/^.*(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/)|(?:(?:watch)?\?v(?:i)?=|\&v(?:i)?=))([^#\&\?]*).*/)[1]}async function b(a,b){const d=new DOMParser().parseFromString(b,"text/html"),e=b.includes("<link rel=\"image_src\" href=\"")?d.querySelector("link[rel=image_src]").getAttribute("href"):`https://img.youtube.com/vi/${a}/maxresdefault.jpg`;return{title:d.querySelector("meta[name=title]").getAttribute("content"),id:a,channelName:d.querySelector(`link[itemprop="name"]`).getAttribute("content"),channelURL:"https://www.youtube.com/channel/"+d.querySelector(`meta[itemprop="channelId"]`).getAttribute("content"),description:b.includes("\"description\":{\"simpleText\":\"")?b.match(/"description":{"simpleText":"(.+?)"},/)[1].replaceAll("\\n","\n"):"",thumbnail:await c(e),thumbnailUrl:e,startTimestamp:b.includes("\"startTimestamp\":\"")?b.match(/"startTimestamp":"(.+?)"/)[1].replaceAll("\\n","\n"):""}}function c(a){var b=new XMLHttpRequest;return b.responseType="blob",new Promise(c=>{b.onload=function(){var a=new FileReader;a.onloadend=function(){c(a.result)},a.readAsDataURL(b.response)},b.open("GET",a),b.send()})}function d(b,c,d){var e=new Blob([b],{type:d});if(window.navigator.msSaveOrOpenBlob)window.navigator.msSaveOrOpenBlob(e,c);else{var f=document.createElement("a"),a=URL.createObjectURL(e);f.href=a,f.download=c,document.body.appendChild(f),f.click(),setTimeout(function(){document.body.removeChild(f),window.URL.revokeObjectURL(a)},0)}}const e={VIDEO:[337,315,266,138,313,336,308,271,264,335,303,299,248,169,137,334,302,298,247,136],AUDIO:[251,141,171,140,250,249,139]};(async function(){const c=a(location.href),f=await fetch(`https://www.youtube.com/watch?v=${c}`),g=await f.text(),h=g.match(/"itag":(?<itag>\d+),"url":"(?<url>[^"]+)"/g),i={};for(const a of h){const b=a.match(/"itag":(?<itag>\d+),"url":"(?<url>[^"]+)"/).groups;i[b.itag]=b.url.replaceAll("\\u0026","&")}let j={video:null,audio:null,metadata:await b(c,g),version:"1.5",createTime:new Date().toISOString()};for(const a of e.VIDEO)if(Object.keys(i).includes(a.toString())&&i[a.toString()].includes("noclen")){j.video={[a.toString()]:i[a.toString()]};break}for(const a of e.AUDIO)if(Object.keys(i).includes(a.toString())&&i[a.toString()].includes("noclen")){j.audio={[a.toString()]:i[a.toString()]};break}window.result=i,d(JSON.stringify(j,null,4),`${c}.urls.json`,"application/json")})()})();
(async() => {
const VERSION = "1.5"
const PRIORITY = {
"VIDEO": [
337, 315, 266, 138, // 2160p60
313, 336, // 2160p
308, // 1440p60
271, 264, // 1440p
335, 303, 299, // 1080p60
248, 169, 137, // 1080p
334, 302, 298, // 720p60
247, 136 // 720p
],
"AUDIO": [
251, 141, 171, 140, 250, 249, 139
]
}
function getYoutubeID(url){
if (!url.includes(".")) return url;
const regex = /^.*(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/)|(?:(?:watch)?\?v(?:i)?=|\&v(?:i)?=))([^#\&\?]*).*/;
return url.match(regex)[1];
}
async function getYoutubeVideoInfo(id, html){
const doc = new DOMParser().parseFromString(html, "text/html");
const thumbnailUrl = html.includes('<link rel="image_src" href="') ? doc.querySelector("link[rel=image_src]").getAttribute("href") : `https://img.youtube.com/vi/${id}/maxresdefault.jpg`
return {
title: doc.querySelector("meta[name=title]").getAttribute("content"),
id,
channelName: doc.querySelector(`link[itemprop="name"]`).getAttribute("content"),
channelURL: "https://www.youtube.com/channel/" + doc.querySelector(`meta[itemprop="channelId"]`).getAttribute("content"),
description: html.includes('"description":{"simpleText":"') ? html.match(/"description":{"simpleText":"(.+?)"},/)[1].replaceAll("\\n", "\n") : "",
thumbnail: await getImage(thumbnailUrl),
thumbnailUrl,
startTimestamp: html.includes('"startTimestamp":"') ? html.match(/"startTimestamp":"(.+?)"/)[1].replaceAll("\\n", "\n") : ""
}
}
function getImage(url){
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
return new Promise((resolve, reject) => {
xhr.onload = function() {
var reader = new FileReader();
reader.onloadend = function () {
resolve(reader.result);
}
reader.readAsDataURL(xhr.response);
};
xhr.open('GET', url);
xhr.send();
})
}
function download(data, filename, type) {
var file = new Blob([data], {type: type});
if (window.navigator.msSaveOrOpenBlob) // IE10+
window.navigator.msSaveOrOpenBlob(file, filename);
else { // Others
var a = document.createElement("a"), url = URL.createObjectURL(file);
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
setTimeout(function() {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 0);
}
}
async function main(){
const id = getYoutubeID(location.href)
const url = `https://www.youtube.com/watch?v=${id}`
const resp = await fetch(url);
const data = await resp.text();
const regex = /"itag":(?<itag>\d+),"url":"(?<url>[^"]+)"/g
const regexInner = /"itag":(?<itag>\d+),"url":"(?<url>[^"]+)"/
const match = data.match(regex);
const result = {}
for(const x of match){
const tmp = x.match(regexInner).groups;
result[tmp.itag] = tmp.url.replaceAll('\\u0026', "&")
}
let best = {
video: null,
audio: null,
metadata: await getYoutubeVideoInfo(id, data),
version: VERSION,
createTime: new Date().toISOString()
}
for(const itag of PRIORITY.VIDEO){
if (Object.keys(result).includes(itag.toString()) && result[itag.toString()].includes("noclen")){
best.video = {
[itag.toString()]: result[itag.toString()]
}
break;
}
}
for(const itag of PRIORITY.AUDIO){
if (Object.keys(result).includes(itag.toString()) && result[itag.toString()].includes("noclen")){
best.audio = {
[itag.toString()]: result[itag.toString()]
}
break;
}
}
window.result = result;
download(JSON.stringify(best, null, 4), `${id}.urls.json`, "application/json")
}
main()
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment