Vidsrc TMDB & IMDb Integration

Stream Movies and TV Shows directly on IMDb and TMDB in upto 1080p! No more shady websites with horrible ads and malware.

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Vidsrc TMDB & IMDb Integration
// @namespace    http://tampermonkey.net/
// @version      2024-09-11
// @description  Stream Movies and TV Shows directly on IMDb and TMDB in upto 1080p! No more shady websites with horrible ads and malware.
// @author       nour
// @match        https://www.themoviedb.org/*
// @match        https://www.imdb.com/title/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=netflix.com
// @require      https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/js/all.min.js
// ==/UserScript==

(function() {
    'use strict';

    // modal structure
    const modal = document.createElement('div');
    modal.style.display = 'none';
    modal.style.position = 'fixed';
    modal.style.zIndex = '10004';
    modal.style.left = '0';
    modal.style.top = '0';
    modal.style.width = '100%';
    modal.style.height = '100%';
    modal.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';

    const modalContent = document.createElement('div');
    modalContent.style.position = 'absolute';
    modalContent.style.top = '50%';
    modalContent.style.left = '50%';
    modalContent.style.transform = 'translate(-50%, -50%)';
    modalContent.style.width = '90%';
    modalContent.style.maxWidth = '1111px';
    modalContent.style.height = '90%';
    modalContent.style.maxHeight = '687px';
    modalContent.style.backgroundColor = '#000000';
    modalContent.style.border = '1px solid #000000';
    modalContent.style.borderRadius = '5px';
    modalContent.style.boxShadow = '0 2px 10px rgba(0,0,0,0.3)';

    const modalHeader = document.createElement('div');
    modalHeader.style.padding = '10px';
    modalHeader.style.backgroundColor = '#000000';
    modalHeader.style.color = '#FFFFFF';
    modalHeader.style.borderBottom = '1px solid #000000';
    modalHeader.style.display = 'flex';
    modalHeader.style.justifyContent = 'space-between';
    modalHeader.style.alignItems = 'center';

    const modalTitle = document.createElement('span');
    modalTitle.textContent = 'Vidsrc #1 Provider for your Streaming Needs';
    modalTitle.style.fontWeight = 'bold';

    const closeButton = document.createElement('span');
    closeButton.innerHTML = '<i class="fas fa-times"></i>';
    closeButton.style.cursor = 'pointer';
    closeButton.style.fontSize = '20px';

    modalHeader.appendChild(modalTitle);
    modalHeader.appendChild(closeButton);

    const iframe = document.createElement('iframe');
    iframe.style.width = '100%';
    iframe.style.height = 'calc(100% - 41px)'; // Subtract header height
    iframe.style.border = 'none';
    iframe.allowFullscreen = true;

    modalContent.appendChild(modalHeader);
    modalContent.appendChild(iframe);
    modal.appendChild(modalContent);
    document.body.appendChild(modal);

    // Function to create the Watch Now button content
    function createWatchNowButtonContent(isIMDb) {
        if (isIMDb) {
            return `
                <button style="
                    background-color: #f5c518;
                    color: #000000;
                    border: none;
                    padding: 5px 10px;
                    border-radius: 4px;
                    cursor: pointer;
                    font-weight: bold;
                    display: inline-flex;
                    align-items: center;
                    margin-left: 10px;
                ">
                    <i class="fas fa-play-circle" style="margin-right: 5px;"></i>
                    Watch Now
                </button>
            `;
        } else {
            const icon = '<i class="fas fa-play-circle" style="font-size: 36px; color: white;"></i>';
            return `
                <div class="text_wrapper">
                    <div class="button">
                        <div class="provider">
                            ${icon}
                        </div>
                        <div class="text">
                            <span>
                                <h4>Watch Now</h4>
                                <h3>Watch with Vidsrc</h3>
                            </span>
                        </div>
                    </div>
                </div>`;
        }
    }

    // Function to insert or replace the button
    function insertOrReplaceButton() {
        const contentType = getContentType();
        if (contentType === 'episode') {
            console.log("TV Episode detected, not showing button");
            return; // Don't show button for TV episodes
        }

        if (window.location.hostname === 'www.themoviedb.org') {
            insertTMDBButton();
        } else if (window.location.hostname === 'www.imdb.com') {
            insertIMDbButton();
        }
    }

    // Function to insert button for TMDB
    function insertTMDBButton() {
        const posterWrapper = document.querySelector('.poster_wrapper');
        if (posterWrapper) {
            let ottOffer = posterWrapper.querySelector('.ott_offer');
            if (!ottOffer) {
                ottOffer = document.createElement('div');
                ottOffer.className = 'ott_offer';
                posterWrapper.insertBefore(ottOffer, posterWrapper.firstChild);
            } else {
                const existingLink = ottOffer.querySelector('a');
                if (existingLink) {
                    existingLink.removeAttribute('href');
                    existingLink.style.cursor = 'pointer';
                }
            }

            ottOffer.innerHTML = createWatchNowButtonContent(false);

            const oldElement = ottOffer;
            const newElement = oldElement.cloneNode(true);
            oldElement.parentNode.replaceChild(newElement, oldElement);

            newElement.addEventListener('click', showModal);

            newElement.style.position = 'relative';
            newElement.style.zIndex = '10';
            newElement.style.marginBottom = '10px';
            newElement.style.cursor = 'pointer';
        }
    }

    // Function to insert button for IMDb
    function insertIMDbButton() {
        const titleElement = document.querySelector('.hero__primary-text');
        if (titleElement) {
            const watchNowButton = document.createElement('span');
            watchNowButton.innerHTML = createWatchNowButtonContent(true);
            watchNowButton.style.display = 'inline-block';
            watchNowButton.style.verticalAlign = 'middle';

            titleElement.insertAdjacentElement('afterend', watchNowButton);

            watchNowButton.querySelector('button').addEventListener('click', showModal);
        }
    }

    // Function to get ID (TMDB or IMDb)
    function getId() {
        if (window.location.hostname === 'www.themoviedb.org') {
            const match = window.location.pathname.match(/\/(movie|tv)\/(\d+)/);
            return match ? match[2] : null;
        } else if (window.location.hostname === 'www.imdb.com') {
            const match = window.location.pathname.match(/\/title\/(tt\d+)/);
            return match ? match[1] : null;
        }
        return null;
    }

    // Function to determine if it's a movie or TV show
function getContentType() {
    console.log("Starting getContentType function");
    console.log("Current URL:", window.location.href);
    console.log("Document title:", document.title);

    if (window.location.hostname === 'www.themoviedb.org') {
        console.log("Detected TMDB");
        const isMovie = window.location.pathname.includes('/movie/');
        console.log("Is movie path:", isMovie);
        return isMovie ? 'movie' : 'tv';
    } else if (window.location.hostname === 'www.imdb.com') {
        console.log("Detected IMDb");
        const title = document.title;
        console.log("Full title:", title);
        if (title.includes("TV Episode")) {
            console.log("Detected TV Episode");
            return 'episode';
        }
        const isSeries = title.includes("TV Series");
        console.log("Title includes 'TV Series':", isSeries);
        return isSeries ? 'tv' : 'movie';
    }

    console.log("Unknown website");
    return null;
}

// Test the function
const result = getContentType();
console.log("Final result:", result);

// Function to show modal
function showModal() {
    const id = getId();
    const contentType = getContentType();
    let baseUrl;

    // Set baseUrl based on the contentType
    if (contentType === 'tv') {
        baseUrl = 'https://vidsrc.me/embed/';
    } else {
        baseUrl = 'https://vidsrc.xyz/embed/';
    }

    if (id) {
        const isIMDb = window.location.hostname === 'www.imdb.com';
        const idParam = isIMDb ? id : `${contentType}?tmdb=${id}`;
        iframe.src = `${baseUrl}${idParam}`;
        modal.style.display = 'block';
    }
}

    // Function to initialize the script
    function init() {
        insertOrReplaceButton();
    }

    // Use a MutationObserver to detect when the relevant elements are added to the DOM
    const observer = new MutationObserver((mutations, obs) => {
        const relevantElement = window.location.hostname === 'www.themoviedb.org'
            ? document.querySelector('.poster_wrapper')
            : document.querySelector('.hero__primary-text');

        if (relevantElement) {
            init();
            obs.disconnect(); // Stop observing once we've found and modified the relevant element
        }
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });

    // Close modal on close button click
    closeButton.addEventListener('click', () => {
        modal.style.display = 'none';
        iframe.src = ''; // Clear the iframe source when closing
    });

    // Close modal when clicking outside of it
    modal.addEventListener('click', (event) => {
        if (event.target === modal) {
            modal.style.display = 'none';
            iframe.src = ''; // Clear the iframe source when closing
        }
    });
})();