// ==UserScript==
// @name IMDb Watcher
// @namespace https://www.imdb.com/
// @icon https://vidsrc.net/template/vidsrc-ico.png
// @version 1.1.1
// @description Adds buttons on IMDb to watch movies/series for free
// @author cevoj35548 (orig. Undefined42)
// @license MIT
// @match https://*.imdb.com/title/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
const sources = [
{
name: 'Embed.su',
urls: {
movie: 'https://embed.su/embed/movie/{id}/1/1',
tv: 'https://embed.su/embed/tv/{id}/1/1',
tvEp: 'https://embed.su/embed/tv/{id}/{season}/{episode}'
},
color: '#9038ED',
textColor: '#f0f0f0'
},
{
name: 'SuperEmbed',
urls: {
movie: 'https://multiembed.mov/?video_id={id}',
tv: 'https://multiembed.mov/?video_id={id}',
tvEp: 'https://multiembed.mov/?video_id={id}&s={season}&e={episode}'
},
color: '#5009DE',
textColor: '#bad8eb'
},
{
name: '2Embed',
urls: {
movie: 'https://www.2embed.stream/embed/movie/{id}',
tv: 'https://www.2embed.stream/embed/tv/{id}',
tvEp: 'https://www.2embed.stream/embed/tv/{id}/{season}/{episode}'
},
color: '#0058a4',
textColor: '#bad8eb'
},
{
name: 'VidSrc',
urls: {
movie: 'https://vidsrc.net/embed/movie/{id}',
tv: 'https://vidsrc.net/embed/tv/{id}',
tvEp: 'https://vidsrc.net/embed/tv/{id}/{season}/{episode}'
},
color: '#125784',
textColor: '#bad8eb'
},
];
const cornerPadding = 20; // Distance from the corner of the screen
const buttonSpacing = 2; // Space between each button in the stack
// extract season and episode numbers from the IMDb page
function extractSeasonEpisode() {
const seasonEpisodeDiv = document.querySelector('[data-testid="hero-subnav-bar-season-episode-numbers-section"]');
if (seasonEpisodeDiv) {
const seasonEpisodeText = seasonEpisodeDiv.textContent.trim();
const match = seasonEpisodeText.match(/S(\d+).E(\d+)/);
if (match) {
return {
season: match[1],
episode: match[2]
};
}
}
return null;
}
// extract the series ID from the IMDb page
function extractSeriesId() {
const seriesLink = document.querySelector('[data-testid="hero-title-block__series-link"]');
if (seriesLink) {
const href = seriesLink.getAttribute('href');
const match = href.match(/\/title\/(tt\d+)\//);
if (match) {
return match[1];
}
}
return null;
}
// generate the URL for a specific source
function generateUrl(urls, isMovie, isEpisode, imdbId, seriesId, seasonEpisode) {
if (isMovie && isEpisode) {
return urls.movie.replace('{id}', imdbId);
} else if (seasonEpisode && seriesId) {
const { season, episode } = seasonEpisode;
return urls.tvEp.replace('{id}', seriesId).replace('{season}', season).replace('{episode}', episode);
} else {
return urls.tv.replace('{id}', imdbId);
}
}
sources.reverse().forEach((source, index) => {
const button = document.createElement('button');
button.textContent = `📽 Watch - ${source.name}`;
button.style.fontFamily = 'Arial';
button.style.position = 'fixed';
button.style.bottom = `${cornerPadding + index * (40 + buttonSpacing)}px`;
button.style.right = `${cornerPadding}px`;
button.style.padding = '10px';
button.style.background = source.color;
button.style.color = source.textColor;
button.style.border = 'none';
button.style.cursor = 'pointer';
button.style.fontWeight = 'bold';
button.style.borderRadius = '6px';
button.style.zIndex = '9999';
button.style.filter = 'drop-shadow(0 10px 8px rgb(0 0 0 / 0.05)) drop-shadow(0 4px 3px rgb(0 0 0 / 0.1))';
// add click event to redirect to the source URL
button.addEventListener('click', () => {
const imdbId = window.location.pathname.split('/')[2];
const isMovie = document.title.indexOf('TV Series') === -1;
const isEpisode = document.title.indexOf('TV Episode') === -1;
const seasonEpisode = extractSeasonEpisode();
const seriesId = extractSeriesId();
const url = generateUrl(source.urls, isMovie, isEpisode, imdbId, seriesId, seasonEpisode);
window.open(url, '_blank');
});
document.body.appendChild(button);
});
})();