NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name Netflix - Open Largest Images
// @namespace Netflix
// @version 1.2
// @description Get the largest Netflix images of each type
// @author gazza911
// @match https://www.netflix.com/browse*
// @match https://www.netflix.com/title*
// @match https://www.netflix.com/*/title*
// @match https://www.netflix.com/search*
// @match https://www.netflix.com/watch*
// @icon https://www.google.com/s2/favicons?domain=netflix.com
// @grant GM.openInTab
// @grant GM.registerMenuCommand
// @run-at document-start
// @updateURL https://openuserjs.org/meta/gazza911/Netflix_-_Open_Largest_Images.meta.js
// @require https://code.jquery.com/jquery-3.6.0.min.js
// @license MIT
// ==/UserScript==
(function() {
var clickedEl;
document.addEventListener("contextmenu", function(event){
clickedEl = event.target;
});
GM.registerMenuCommand("Open Largest Element", ()=>{
openLargestImage(clickedEl);
});
})();
function getHighestImages(path, dimension) {
var highestDimension = 0;
var images = [];
if (path) {
for (var i = 0; i < path.length; i++) {
if (path[i][dimension] > highestDimension) {
images = [path[i].url];
highestDimension = path[i].h;
} else if (path[i][dimension] === highestDimension) {
if (images.indexOf(path[i].url) === -1) {
images.push(path[i].url);
}
}
}
}
return images;
}
function getTrackId(href) {
if (href.indexOf('/watch/') === 0 || href.indexOf('/title/') === 0) {
var end = href.indexOf('?');
if (end > 0) {
return href.substr(7, end - 7);
} else {
return href.substr(7);
}
}
}
function getDataFromSections(clickedEl) {
var sectionData = netflix.reactContext.models.nmTitleUI.data.sectionData;
var clickedImg = clickedEl.src || clickedEl.style["background-image"];
if (clickedImg.indexOf("url") === 0) {
var match = /url\(['"]*([^\)]*?)['"]*\)/gm.exec(clickedImg);
clickedImg = match[1];
}
var track;
for (var section of Object.values(sectionData)) {
switch (section.type) {
case "hero": {
if (clickedImg === section.data.artwork.heroImage.url) {
GM.openInTab(clickedImg);
return {trackId: null, episodeId: null};
}
break;
}
case "additionalVideos": {
for (var i = 0; i < section.data.supplementalVideos.length; i++) {
if (clickedImg === section.data.supplementalVideos[i].placeholderImageUrl) {
return {trackId: section.data.supplementalVideos[i].id, episodeId: null};
}
}
break;
}
case "seasonsAndEpisodes": {
for (var j = 0; j < section.data.seasons.length; j++) {
for (var k = 0; k < section.data.seasons[j].episodes.length; k++) {
if (clickedImg === section.data.seasons[j].episodes[k].artworkUrl) {
return {trackId: section.data.seasons[j].episodes[k].episodeId, episodeId: section.data.seasons[j].episodes[k].episodeId};
}
}
}
break;
}
case "moreTitles": {
for (var l = 0; l < section.data.titles.length; l++) {
if (clickedImg === section.data.titles[l].imageSrc) {
return {trackId: section.data.titles[l].id, episodeId: null};
}
}
break;
}
}
}
}
function openLargestImage(clickedEl) {
var apiUrl = netflix.reactContext.models.playerModel.data.config.ui.initParams.apiUrl;
if (apiUrl) {
var trackId;
var episodeId;
if ($(':focus').length > 0 || $(clickedEl).length === 1) {
if ($(':focus').hasClass('previewModal--container')) {
trackId = $(':focus').children(':first').children(':first').children(':first').attr("id");
if (!/^\d+$/.test(trackId)) {
trackId = null;
}
}
else {
var href = $(':focus').attr('href');
href = href ?? $(':focus').closest('.slider-refocus').attr("href");
trackId = href ? getTrackId(href) : null;
if (!trackId) {
href = $(':focus').closest('.slider-refocus').attr("href");
trackId = href ? getTrackId(href) : null;
}
var ptrackData = $(':focus').find('.ptrack-content').data('ui-tracking-context');
if (ptrackData) {
var startVideoIndex = ptrackData.indexOf('%22video_id%22:');
var endVideoIndex = ptrackData.indexOf(',', startVideoIndex);
trackId = ptrackData.substr(startVideoIndex + 15, endVideoIndex - startVideoIndex - 15);
episodeId = parseInt(trackId);
}
if (!trackId) {
trackId = getTrackId(window.location.pathname);
}
}
if (!trackId && $(clickedEl).length === 1) {
var data = getDataFromSections(clickedEl);
if (data) {
trackId = data.trackId;
episodeId = data.episodeId;
}
}
if (trackId) {
$.get(apiUrl + '/metadata?movieid=' + trackId, function (data) {
var images = {};
if (episodeId) {
for (var season of data.video.seasons) {
for (var episode of season.episodes) {
if (episodeId === episode.episodeId) {
images.episode = getHighestImages(episode.stills, 'w');
}
}
}
} else {
images.artwork = getHighestImages(data.video.artwork, 'w');
images.stills = getHighestImages(data.video.stills, 'w');
images.storyart = getHighestImages(data.video.storyart, 'w');
images.boxart = getHighestImages(data.video.boxart, 'h');
window.open(apiUrl + '/metadata?movieid=' + trackId);
}
for (var type in images) {
for (var i = 0; i < images[type].length; i++) {
GM.openInTab(images[type][i]);
}
}
});
}
}
} else {
console.log('Unable to get shakti build');
}
}