I'm trying to write a Violentmonkey userscript to save youtube thumbnails on my harddrive, but can't get it to work. I think the fact that I'm trying to save images from ytimg.com while being on youtube.com complicates things.
Here is the code I wrote so far, copypaste this into your Web Developer Tools Javascript console, and then click the "TEST" button in the top right corner, here is the YouTube channel I test this on https://www.youtube.com/@user-qm6hx2ud3r/videos. With Firefox it saves the thumbnail, but also opens thumbnail, and I want to stay on the page I am. With Chromium it just throws an error, "has been blocked by CORS policy". Change download2
to download
inside forElement
to see the different approach.
// ==UserScript==
// @name Grab channel info - youtube.com
// @namespace Violentmonkey Scripts
// @match https://www.youtube.com/*
// @grant none
// @version 1.0
// @author -
// @description -
// ==/UserScript==
"mode strict";
function save(url, name) {
const link = document.createElement('a')
link.href = url
link.download = name
link.style.display = 'none';
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
function download2(url, name) {
if (!url) return
if (!name) return
var xhr = new XMLHttpRequest();
xhr.onload = function() {
var reader = new FileReader();
reader.onloadend = function() {
//console.log(reader.result);
save(reader.result, name)
}
reader.readAsDataURL(xhr.response);
};
xhr.open('GET', url);
xhr.responseType = 'blob';
xhr.send();
}
async function download(url, name) {
if (!url) return
if (!name) return
const image = await fetch(url)
const imageBlog = await image.blob()
const imageURL = URL.createObjectURL(imageBlog)
const link = document.createElement('a')
link.href = imageURL
//link.download = name
link.style.display = 'none';
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
function forElement(el) {
let thumb = el.querySelector('ytd-thumbnail img').src
console.log(thumb)
download2(thumb, "downloaded-thumbnail.webp")
}
function start() {
let testbutton = document.querySelector("button#test")
if (!testbutton) {
document.querySelector('ytd-masthead div#container div#end').insertAdjacentHTML('afterbegin', '<button id="test">TEST</button>')
testbutton = document.querySelector("button#test")
}
testbutton.onclick = function() {
forElement(document.querySelectorAll("div#content.ytd-rich-item-renderer")[0])
}
}
start()
I'm trying to do saving right from the browser because I hope to save a bit of traffic this way, browser already downloaded those thumbnails and I don't want to save an already downloaded thumbnails. I can try making a WebExtensions if a simple userscript isn't enough for this task.
Related resources: https://dev.to/sbodi10/download-images-using-javascript-51a9 Force browser to download image files on click How can I convert an image into Base64 string using JavaScript?