Skip to content

Instantly share code, notes, and snippets.

@zvakanaka
Last active May 28, 2024 18:40
Show Gist options
  • Save zvakanaka/63e91be63ff19c83526d3c5d2672da5a to your computer and use it in GitHub Desktop.
Save zvakanaka/63e91be63ff19c83526d3c5d2672da5a to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name Youtube Show Likes Percentage
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Show likes/views percentage in search results.
// @author Adam Q.
// @match https://www.youtube.com/*
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant GM_xmlhttpRequest
// ==/UserScript==
(async function () {
"use strict";
const waitMs = 330;
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
try {
await callback(array[index], index, array);
} catch (error) {
console.error(error);
throw error;
}
}
}
function timeout(ms) {
return new Promise((r) => setTimeout(r, ms));
}
await timeout(2000);
function getLikesColor(percentLikes, thumbnail) {
if (percentLikes <= 1) {
thumbnail.parentElement.style.filter = "opacity(5%)";
}
if (percentLikes >= 10) {
return `linear-gradient(217deg, rgba(255,0,0,.8), rgba(255,0,0,0) 70.71%),
linear-gradient(127deg, rgba(0,255,0,.8), rgba(0,255,0,0) 70.71%),
linear-gradient(336deg, rgba(0,0,255,.8), rgba(0,0,255,0) 70.71%)`;
} else if (percentLikes >= 9) {
return "blue";
} else if (percentLikes >= 8) {
return "blue";
} else if (percentLikes >= 7) {
return "blue";
} else if (percentLikes >= 6) {
return "blue";
} else if (percentLikes >= 5) {
return "blue";
} else if (percentLikes >= 4) {
return "green";
} else if (percentLikes >= 3) {
return "yellow";
} else if (percentLikes >= 2) {
return "orange";
} else if (percentLikes >= 1) {
return "red";
}
return "red";
}
asyncForEach(
document.querySelectorAll("ytd-video-renderer, ytd-playlist-video-renderer"),
async (resultEl, i, arr) => {
console.log(`Waiting ${waitMs}ms for ${i + 1}/${arr.length}`);
await timeout(waitMs);
console.log(`Done waiting for ${i + 1}`);
const res = await fetch(resultEl.querySelector("a").href);
const text = await res.text();
console.log(`${parseInt(text.length / 1024, 10)} KB`);
try {
const videoMetadata = JSON.parse(
text.split("ytInitialData =")[1].split(";</script>")[0]
);
const videoData = {
likes: 0,
views: 0,
videoTitle: ""
};
const contentsObj = videoMetadata?.contents?.twoColumnWatchNextResults?.results?.results?.contents?.find(obj => Object.hasOwn(obj, 'videoPrimaryInfoRenderer'));
try {
const rawLikes = contentsObj.videoPrimaryInfoRenderer.videoActions.menuRenderer.topLevelButtons[0].segmentedLikeDislikeButtonViewModel.likeButtonViewModel.likeButtonViewModel.toggleButtonViewModel.toggleButtonViewModel.defaultButtonViewModel.buttonViewModel.title;
const likes = rawLikes.replace('K', '000').replace('.50', '5');
videoData.likes = parseInt(
likes.replace(
/,/g,
""
),
10
);
} catch (error) {
console.log(videoMetadata.contents.twoColumnWatchNextResults.results.results.contents);
console.log("error getting video data failed to get like", error);
}
try {
videoData.views = parseInt(
contentsObj.videoPrimaryInfoRenderer.viewCount.videoViewCountRenderer.viewCount.simpleText.replace(
/,/g,
""
),
10
);
} catch (error) {
// console.log('videoMetadata', videoMetadata)
console.log("error getting video data", error);
}
try {
videoData.videoTitle = resultEl
.querySelector("#title-wrapper,#video-title")
.textContent.trim();
} catch (error) {
console.log("error getting video data", error);
}
const { likes, views, videoTitle } = videoData;
const percentLikes = parseInt((likes / views) * 100, 10);
const infoString = `(${percentLikes}%) - ${videoTitle}`;
console.log(infoString, videoData);
const thumbnail = resultEl.querySelector("ytd-thumbnail");
const backgroundDiv = document.createElement("div");
backgroundDiv.style.background = `white`;
backgroundDiv.style.width = `100%`;
backgroundDiv.style.height = `20px`;
backgroundDiv.style.opacity = "70%";
backgroundDiv.style.position = "absolute";
backgroundDiv.style.bottom = "0";
const div = document.createElement("div");
div.style.width = `${percentLikes}%`;
div.style.height = `20px`;
div.style.fontSize = `18px`;
div.style.background = getLikesColor(percentLikes, thumbnail);
div.style.opacity = "70%";
div.style.position = "absolute";
div.style.bottom = "0";
div.textContent = `${percentLikes}%`;
const div2 = document.createElement("div");
div2.style.height = `20px`;
div2.style.background = "white";
div2.style.opacity = "70%";
div2.style.position = "absolute";
div2.style.top = "0";
div2.textContent = `${percentLikes}%`;
thumbnail.appendChild(backgroundDiv);
thumbnail.appendChild(div);
thumbnail.appendChild(div2);
} catch (error) {
console.error(error);
}
}
);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment