Skip to content

Instantly share code, notes, and snippets.

@zenofile
Created September 30, 2020 00:47
Show Gist options
  • Save zenofile/6aa55338ed346d4a532b6f8a0df58df9 to your computer and use it in GitHub Desktop.
Save zenofile/6aa55338ed346d4a532b6f8a0df58df9 to your computer and use it in GitHub Desktop.
Extract video URLs from YouTube's dynamic mix playlists
var parse = (list) => {
const vp = /(?:youtube\.com.*(?:\?|&)(?:v)=|youtube\.com.*embed\/|youtube\.com.*v\/|youtu\.be\/)((?!videoseries)[a-zA-Z0-9_-]*)/;
const dl = Array.from(document.querySelectorAll(`a[href*="list=${list}"]`), e => e.href.match(vp)[1]);
return dl.filter((v, i, a) => a.indexOf(v) === i).map(e => `https://youtube.com/watch?v=${e}`);
};
var dl = (() => {
let a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
return (data, fileName) => {
let bytes = data,
blob = new Blob([bytes], {type: "octet/stream"}),
url = window.URL.createObjectURL(blob);
a.href = url;
a.download = fileName;
a.click();
window.URL.revokeObjectURL(url);
};
})();
(function() {
const lp = /(?:(?:\?|&)(?:v|list)=|embed\/|v\/|youtu\.be\/)((?!videoseries)[a-zA-Z0-9_-]*)/g;
const m = Array.from(window.location.href.matchAll(lp)).flat();
const l = m.length == 4 ? m[3] : undefined;
if (l) dl(parse(l).join('\n'), `${l}.txt`);
else console.warn('Could not parse playlist.');
})();
javascript:(function()%7Bvar%20parse%20%3D%20(list)%20%3D%3E%20%7B%0A%20%20const%20vp%20%3D%20%2F(%3F%3Ayoutube%5C.com.*(%3F%3A%5C%3F%7C%26)(%3F%3Av)%3D%7Cyoutube%5C.com.*embed%5C%2F%7Cyoutube%5C.com.*v%5C%2F%7Cyoutu%5C.be%5C%2F)((%3F!videoseries)%5Ba-zA-Z0-9_-%5D*)%2F%3B%0A%20%20const%20dl%20%3D%20Array.from(document.querySelectorAll(%60a%5Bhref*%3D%22list%3D%24%7Blist%7D%22%5D%60)%2C%20e%20%3D%3E%20e.href.match(vp)%5B1%5D)%3B%0A%20%20return%20dl.filter((v%2C%20i%2C%20a)%20%3D%3E%20a.indexOf(v)%20%3D%3D%3D%20i).map(e%20%3D%3E%20%60https%3A%2F%2Fyoutube.com%2Fwatch%3Fv%3D%24%7Be%7D%60)%3B%0A%7D%3B%0A%0Avar%20dl%20%3D%20(()%20%3D%3E%20%7B%0A%20%20%20%20let%20a%20%3D%20document.createElement(%22a%22)%3B%0A%20%20%20%20document.body.appendChild(a)%3B%0A%20%20%20%20a.style%20%3D%20%22display%3A%20none%22%3B%0A%0A%20%20%20%20return%20(data%2C%20fileName)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20let%20bytes%20%3D%20data%2C%0A%20%20%20%20%20%20%20%20blob%20%3D%20new%20Blob(%5Bbytes%5D%2C%20%7Btype%3A%20%22octet%2Fstream%22%7D)%2C%0A%20%20%20%20%20%20%20%20url%20%3D%20window.URL.createObjectURL(blob)%3B%0A%0A%20%20%20%20%20%20%20%20a.href%20%3D%20url%3B%0A%20%20%20%20%20%20%20%20a.download%20%3D%20fileName%3B%0A%20%20%20%20%20%20%20%20a.click()%3B%0A%20%20%20%20%20%20%20%20window.URL.revokeObjectURL(url)%3B%0A%20%20%20%20%7D%3B%0A%7D)()%3B%0A%0A(function()%20%7B%0A%20%20%20%20const%20lp%20%3D%20%2F(%3F%3A(%3F%3A%5C%3F%7C%26)(%3F%3Av%7Clist)%3D%7Cembed%5C%2F%7Cv%5C%2F%7Cyoutu%5C.be%5C%2F)((%3F!videoseries)%5Ba-zA-Z0-9_-%5D*)%2Fg%3B%0A%20%20%20%20const%20m%20%3D%20Array.from(window.location.href.matchAll(lp)).flat()%3B%0A%20%20%20%20const%20l%20%3D%20m.length%20%3D%3D%204%20%3F%20m%5B3%5D%20%3A%20undefined%3B%0A%20%20%20%20if%20(l)%20dl(parse(l).join('%5Cn')%2C%20%60%24%7Bl%7D.txt%60)%3B%0A%20%20%20%20else%20console.warn('Could%20not%20parse%20playlist.')%3B%0A%7D)()%3B%7D)()%3B
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment