Hanime Resumer and Hider

Store video timespamps locally, hide videos that have a timespamp, button to hide all videos in a playlist (all your liked videos)

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

You will need to install an extension such as Tampermonkey to install this script.

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

Advertisement:

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

Advertisement:

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         Hanime Resumer and Hider
// @namespace    http://tampermonkey.net/
// @version      1.2.1
// @description  Store video timespamps locally, hide videos that have a timespamp, button to hide all videos in a playlist (all your liked videos)
// @author       You
// @match        https://hanime.tv/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=hanime.tv
// @grant        GM.setValue
// @grant        GM.getValue
// ==/UserScript==

function l(...args){
    console.log('[Resumer]', ...args)
}

function getVideoKeyFromUrl(url = location.href) {
    let u;
    try {
        u = new URL(url, location.origin);
    } catch (err) {
        l('invalid URL', url, err);
        return undefined;
    }

    // Normal video URL: https://hanime.tv/videos/hentai/some-video
    let match = u.pathname.match(/\/videos\/hentai\/([^/?#]+)/);
    if (match) return match[1];

    // Playlist video URL: https://hanime.tv/playlists/<playlist-id>/video/some-video
    match = u.pathname.match(/\/playlists\/[^/]+\/video\/([^/?#]+)/);

    if (match) return match[1];

    return undefined;

}

//Resumer
let lastUrl = undefined
//Observe changes to the DOM
const observer = new MutationObserver(async (mutationsList, observer) => {
    let currentUrl = location.href
    if(currentUrl != lastUrl){
        //Get video element
        let key = getVideoKeyFromUrl();
        let video = document.querySelector('video#HTVPlayer_html5_api');

        l('url', currentUrl, lastUrl, key);
        if(video){
            l('Observing', key, video);

            //Resume
            let previousTime = await GM.getValue(key)
            if(previousTime){
                video.currentTime = previousTime
                l(`resuming ${key} ${video.currentTime}`)
            }
            //Save currentTime
            video.ontimeupdate = () => {
                key = getVideoKeyFromUrl();
                l('update', key, video.currentTime);
                GM.setValue(key, video.currentTime);
            }
            lastUrl = currentUrl;
        } else if(!key){
            lastUrl = currentUrl;
        }

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



async function hide(a){
    let key = getVideoKeyFromUrl(a.href);
    let previousTime = await GM.getValue(key);
    if(key != undefined && previousTime !== undefined){
        // l('hiding', key, previousTime);
        a.style.filter = 'brightness(0.3)';
    }
}
//Hider
const observer2 = new MutationObserver((mutationsList, observer) => {
    let links = document.querySelectorAll('a');
    for(let a of links) {
        hide(a);
    }

    //playlists (inefficient)
    /*if(document.URL.includes('/playlists/')){
        for(let a of document.querySelectorAll('.video__item a')){
            hide(a)
        }

        //Hide all liked videos
        if(!document.querySelector('#hide-all')){
            let group = document.querySelector('.btn-toggle.btn-toggle--selected')
            group.insertAdjacentHTML('afterEnd', '<button id="hide-all" type="button" class="btn btn--active btn--flat" style="position: relative;"><div class="btn__content">Hide All</div></button>')
            document.querySelector('#hide-all').onclick = async () => {
                for(let a of document.querySelectorAll('.video__item a')){
                    let name = a.href.replace('https://hanime.tv/videos/hentai/', '')
                    name = name.split('?')[0] //to remove ?playlist
                    let previousTime = await GM.getValue(name)
                    if(previousTime === undefined){
                        l('hiding', name)
                        a.style.filter = 'brightness(0.1)'
                        GM.setValue(name, 0)
                    }
                }
            }
        }
    }*/

})
observer2.observe(document, {subtree:true, childList:true})