Netflix Marathon

Automatically skip recaps, intros and click nexts on Netflix, DisneyPlus and Amazon video for you.

< Feedback on Netflix Marathon

Question/comment

§
Posted: 2021.05.09.
Edited: 2021.05.09.

Please review my refactored version. It should be easier to read and easier to extend.

I also added Amazon's "next-episode button" in line 54.

// ==UserScript==
// @name         Netflix Marathon
// @namespace    https://greasyfork.org/en/scripts/30029-netflix-marathon
// @version      2.7.1
// @description  Automatically skip recaps, intros and click nexts on Netflix, DisneyPlus and Amazon video for you.
// @author       ran, me
// @include      https://www.netflix.com/*
// @include      https://www.amazon.com/gp/video/*
// @include      https://www.amazon.de/gp/video/*
// @include      https://www.amazon.*/gp/video/*
// @include      https://www.amazon.*/gp/product/*
// @include      https://primevideo.com/region/*/detail/*
// @include      https://*.primevideo.com/region/*/detail/*
// @include      https://primevideo.com/detail/*
// @include      https://*.primevideo.com/detail/*
// @include      https://*.primevideo.com/*
// @include      https://www.peacocktv.com/watch/*
// @include      https://www.disneyplus.com//video/*
// @include      https://www.disneyplus.com/*/video/*
// @require      http://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js
// @grant        none
// @license MIT
// ==/UserScript==

function log(thing) {
    const logEnabled = false;
    logEnabled === true && console.log(thing);
}

const targets = [
    {log: 'Found autoplay',               className: 'postplay-still-container'}, 
    {log: 'Found autoplay',               className: 'WatchNext-still-container'}, 
    {log: 'Found Amazon video next',      className: 'countdown'}, 
    {log: 'Found Amazon skip ad',         className: 'adSkipButton'}, 
    {log: 'Found Amazon skip intro',      className: 'skipElement'}, 
    {log: 'Found peacock skip intro',     className: 'playback-controls__skip--button'}, 
    {log: '', className: 'PlayerControlsNeo__layout PlayerControlsNeo__layout--dimmed', className1stChildClick: 'interrupter-actions', count: 80}, 
    {log: '', className: 'skip__button', className1stChildClick: 'skip__button'}, // skips recaps and intros on disneyplus
    {log: 'Found autoplay',               className: 'video_view--mini', querySelector: '*[data-testid="up-next-play-button"]'}, // auto plays next episode on disneyplus
    {log: 'Found Amazon imdb skip intro', className: 'atvwebplayersdk-skipelement-button'},
];

const jQueryTargets = [
    {selector: "div div:contains('Skip')",       innerText: 'Skip',       log: ''}, // amazon trailers
    {selector: "div div:contains('Skip Intro')", innerText: 'Skip Intro', log: ''}, // amazon intro
    {selector: "div div:contains('Skip Recap')", innerText: 'Skip Recap', log: ''}, // amazon recap
];

var count = 0;

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function find() {
    if (count === 0) {
        // amazon next-episode button
        var elements = document.querySelectorAll("[data-uia='next-episode-seamless-button']");
        if (elements.length !== 0) {
            log('Found credits.');
            elements[0].click()
            count = 80;
        }

        else if (document.getElementsByClassName('skip-credits').length !== 0 && document.getElementsByClassName('skip-credits-hidden').length === 0) {
            log('Found credits.');
            await sleep(200);
            document.getElementsByClassName('skip-credits')[0].firstElementChild.click();
            await sleep(200);
            document.querySelector('.button-nfplayerPlay').click();
            count = 80;
            log('Found credits. +4s');
            //window.clearInterval(intervalId);
        }

        targets.forEach(target => {
            const elements = document.getElementsByClassName(target.className);
            if (elements.length !== 0) {
                log(target.log);
                if (target.hasOwnProperty('className1stChildClick')) {
                    document.getElementsByClassName(target.className1stChildClick)[0].firstChild.click();
                }
                else if (target.hasOwnProperty('querySelector')) {
                    document.querySelector(target.querySelector).click();
                }
                else {
                    elements[0].click();
                }
                count = target.hasOwnProperty('count') ? target.count : 5;
            }
        });

        jQueryTargets.forEach(target => {
            const badDivs = $(target.selector);
            for (let i = 0; i < badDivs.length; i++) {
                if (i === 0) {
                    log(target.log);
                }
                if (badDivs[i].innerText === target.innerText) {
                    badDivs[i].click();
                    count = 5;
                }
            }
        });
    }
    else {
        count--;
    }
}

var intervalId = window.setInterval(find, 300);
§
Posted: 2021.05.09.
Edited: 2021.05.09.

Update:

  • I wrote Amazon's "next-episode button" in line 54. but I ment to say Netflix.
  • Also after I tested my code, I needed to correct it. See below.

add this to targets:

    {log: 'Found Netflix video next',      className: 'button-nfplayerNextEpisode'},

and remove lines 58 to 66:

        // amazon next-episode button
        var elements = document.querySelectorAll("[data-uia='next-episode-seamless-button']");
        if (elements.length !== 0) {
            log('Found credits.');
            elements[0].click()
            count = 80;
        }

        else
§
Posted: 2021.05.09.
Edited: 2021.05.09.

complete corrected code:

// ==UserScript==
// @name         Netflix Marathon
// @namespace    https://greasyfork.org/en/scripts/30029-netflix-marathon
// @version      2.7.1
// @description  Automatically skip recaps, intros and click nexts on Netflix, DisneyPlus and Amazon video for you.
// @author       ran, me
// @include      https://www.netflix.com/*
// @include      https://www.amazon.com/gp/video/*
// @include      https://www.amazon.de/gp/video/*
// @include      https://www.amazon.*/gp/video/*
// @include      https://www.amazon.*/gp/product/*
// @include      https://primevideo.com/region/*/detail/*
// @include      https://*.primevideo.com/region/*/detail/*
// @include      https://primevideo.com/detail/*
// @include      https://*.primevideo.com/detail/*
// @include      https://*.primevideo.com/*
// @include      https://www.peacocktv.com/watch/*
// @include      https://www.disneyplus.com//video/*
// @include      https://www.disneyplus.com/*/video/*
// @require      http://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js
// @grant        none
// @license MIT
// ==/UserScript==

function log(thing) {
    const logEnabled = false;
    logEnabled === true && console.log(thing);
}

const targets = [
    {log: 'Found autoplay',               className: 'postplay-still-container'},
    {log: 'Found autoplay',               className: 'WatchNext-still-container'},
    {log: 'Found Amazon video next',      className: 'countdown'},
    {log: 'Found Amazon skip ad',         className: 'adSkipButton'},
    {log: 'Found Amazon skip intro',      className: 'skipElement'},
    {log: 'Found peacock skip intro',     className: 'playback-controls__skip--button'},
    {log: '', className: 'PlayerControlsNeo__layout PlayerControlsNeo__layout--dimmed', className1stChildClick: 'interrupter-actions', count: 80},
    {log: '', className: 'skip__button', className1stChildClick: 'skip__button'}, // skips recaps and intros on disneyplus
    {log: 'Found autoplay',               className: 'video_view--mini', querySelector: '*[data-testid="up-next-play-button"]'}, // auto plays next episode on disneyplus
    {log: 'Found Amazon imdb skip intro', className: 'atvwebplayersdk-skipelement-button'},
    {log: 'Found Netflix video next',      className: 'button-nfplayerNextEpisode'},

];

const jQueryTargets = [
    {selector: "div div:contains('Skip')",       innerText: 'Skip',       log: ''}, // amazon trailers
    {selector: "div div:contains('Skip Intro')", innerText: 'Skip Intro', log: ''}, // amazon intro
    {selector: "div div:contains('Skip Recap')", innerText: 'Skip Recap', log: ''}, // amazon recap
];

var count = 0;

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function find() {
    if (count === 0) {
        if (document.getElementsByClassName('skip-credits').length !== 0 && document.getElementsByClassName('skip-credits-hidden').length === 0) {
            log('Found credits.');
            await sleep(200);
            document.getElementsByClassName('skip-credits')[0].firstElementChild.click();
            await sleep(200);
            document.querySelector('.button-nfplayerPlay').click();
            count = 80;
            log('Found credits. +4s');
            //window.clearInterval(intervalId);
        }

        targets.forEach(target => {
            const elements = document.getElementsByClassName(target.className);
            if (elements.length !== 0) {
                log(target.log);
                if (target.hasOwnProperty('className1stChildClick')) {
                    document.getElementsByClassName(target.className1stChildClick)[0].firstChild.click();
                }
                else if (target.hasOwnProperty('querySelector')) {
                    document.querySelector(target.querySelector).click();
                }
                else {
                    elements[0].click();
                }
                count = target.hasOwnProperty('count') ? target.count : 5;
            }
        });

        jQueryTargets.forEach(target => {
            const badDivs = $(target.selector);
            for (let i = 0; i < badDivs.length; i++) {
                if (i === 0) {
                    log(target.log);
                }
                if (badDivs[i].innerText === target.innerText) {
                    badDivs[i].click();
                    count = 5;
                }
            }
        });
    }
    else {
        count--;
    }
}

var intervalId = window.setInterval(find, 300);

Sorry, I didn't figure out how to combine code and collapse like in this example: https://gist.github.com/pierrejoubert73/902cc94d79424356a8d20be2b382e1ab

§
Posted: 2021.05.10.
Edited: 2021.05.10.

@wOxxOm please delete this discussion. Thank you
I opened an updated and clean discussion at https://greasyfork.org/en/scripts/30029-netflix-marathon/discussions/86665

Post reply

Sign in to post a reply.