Replit changed their pricing structure a few days ago, so a lot of these code repositories that were hosted for free were shut down. I had used @Manu.n’s code when he initially created it, but I didn’t want to rely on someone else maintaining it for the exact case that it may disappear at some point, so I made a copy of the code for myself. If you simply put this in a javascript column, and pass the url in the p1 parameter and a 1 for the p2 parameter, it will do the exact same thing. It does not rely on hosting the code with a third party. I don’t know if @Manu.n ever made improvements to the code over the past couple of years and I don’t remember if I ever tweaked it myself, but this is pretty much what he had initially, and it has worked pretty well for me for the most part. These days you could probably ask ChatGPT for the same thing, which may or may not provide a better method. Since this code has been working for me, I haven’t explored if there is anything better.
let YTQuality =
{
"0" : "0",
"1" : "1",
"2" : "2",
"3" : "3",
"low" : 'sddefault',
"low0" : 'sddefault',
"low1" : 'sd1',
"low2" : 'sd2',
"low3" : 'sd3',
"medium" : "mqdefault",
"medium0" : "mqdefault",
"medium1" : "mq1",
"medium2" : "mq2",
"medium3" : "mq3",
"high" : "hqdefault",
"high0" : "hqdefault",
"high1" : "hq1",
"high2" : "hq2",
"high3" : "hq3",
"max" : "maxresdefault",
"max0" : "maxresdefault",
"max1" : "maxres1",
"max2" : "maxres2",
"max3" : "maxres3"
}
// youtube thumbnail (base)
// quality = empty or : 0, 1, 2, 3, low0, low1, low2, low3, medium0, medium1, medium2, medium3, high0, high1, high2, high3, max0, max1, max2, max3
function get_youtube_thumbnail(url, quality) {
if (url) {
var video_id, thumbnail, result;
result = url.match(
/(?:youtu\.be\/|youtube\.com(?:\/embed\/|\/v\/|\/watch\?v=|\/user\/\S+|\/ytscreeningroom\?v=))([\w\-]{10,12})\b/
);
video_id = result[1];
if (video_id) {
let quality_key = YTQuality[quality];
if (quality_key == undefined || quality_key == "") {
quality_key = "sddefault";
}
var thumbnail =
"https://img.youtube.com/vi/" + video_id + "/" + quality_key + ".jpg";
return thumbnail;
}
}
return false;
}
// video thumbnail
async function thumbnail(url, ctime, imgw, imgh) {
return new Promise((resolve, reject) => {
var video = document.createElement('video');
var dataURI;
video.src = url;
video.type = "video/mp4";
video.crossOrigin = "anonymous";
if (video.duration > ctime)
ctime = video.duration;
video.load();
video.currentTime = ctime;
video.addEventListener('loadeddata', function (e) {
createImage();
}, false);
function createImage() {
var canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d');
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
if (imgw != 0) {
canvas.width = imgw;
}
if (imgh != 0) {
canvas.height = imgh;
}
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
dataURI = canvas.toDataURL('image/jpeg');
resolve(dataURI);
}
});
}
let cache = new Map();
url = p1 ?? "";
ctime = p2; // ?? 0.01;
imgw = 0 // imgw ?? 0;
imgh = 0 // imgh ?? 0;
if (url == '')
return;
if (
url.search("https://youtu") > -1 ||
url.search("https://www.youtu") > -1
) {
let dataURI3 = get_youtube_thumbnail(url, ctime);
return dataURI3;
}
let cacheKey = url + ctime + imgw + imgh;
ctime = ctime.replace(',','.');
ctime = parseFloat(ctime);
if (ctime == 0)
ctime = 1; //0.01;
let ret = cache.get(cacheKey);
if (ret == undefined) {
let dataURI2 = await thumbnail(url, Math.abs(ctime), imgw, imgh);
ret = dataURI2;
cache.set(cacheKey, ret);
}
return ret;