MissAV Enhancer

Remove ads | Background play | Auto play | Custom fast-forward time | Full title | More

2025-03-07 يوللانغان نەشرى. ئەڭ يېڭى نەشرىنى كۆرۈش.

// ==UserScript==
// @name    MissAV Enhancer
// @description Remove ads | Background play | Auto play | Custom fast-forward time | Full title | More
// @name:zh-CN  MissAV 增强小助手
// @description:zh-CN  去除广告|后台播放|自动播放|自定义快进时间|完整标题|更多功能...
// @run-at       document-start
// @grant        unsafeWindow
// @grant        GM_addStyle
// @match        https://missav123.com/*
// @match        https://missav.ws/*
// @match        https://missav.ai/*
// @match        https://missav.com/*
// @match        https://thisav.com/*
// @author       DonkeyBear,track no,mrhydra,iSwfe,人民的勤务员 <[email protected]>
// @namespace    https://github.com/ChinaGodMan/UserScripts
// @supportURL    https://github.com/ChinaGodMan/UserScripts/issues
// @homepageURL   https://github.com/ChinaGodMan/UserScripts
// @license      MIT
// @icon  https://raw.githubusercontent.com/ChinaGodMan/UserScriptsHistory/main/scriptsIcon/missav-auto-login-helper.png
// @compatible     chrome
// @compatible     firefox
// @compatible     edge
// @compatible     opera
// @compatible     safari
// @compatible     kiwi
// @version         2025.03.07.2114
// @created         2025-03-07 21:14:34
// @modified        2025-03-07 21:14:34
// ==/UserScript==

/* 脚本来自:
https://greasyfork.org/scripts/493932 MISSAV视频控制条增强 @iSwfe
https://greasyfork.org/scripts/488770/  missav修改页面 @mrhydra
https://greasyfork.org/scripts/499213 missav永远播放+不弹广告 @track no
https://greasyfork.org/scripts/470539 MissAV 迷你加強包 @DonkeyBear
*/
const url = window.location.href
if (/^https:\/\/(missav|thisav)\.com/.test(url)) {
    window.location.href = url.replace('missav.com', 'missav.ws').replace('thisav.com', 'missav.ws')
}
(() => {
    'use strict'
    const minute = 5 // 最大快进分钟数
    const videoSettings = {
        // 【开关】背景色覆盖iPhone非安全区
        viewportFitCover: false,
        //播放页面显示一键回到播放器
        playCtrlEnable: true,
        // 视频控制条按钮间距
        buttonMargin: '.1rem',
        // 播放/暂停按钮的HTML样式
        htmlPlay: '▶️',
        htmlPause: '⏸️',
        // 【开关】修改时间跨度值按钮
        durationBtnEnable: true,
        // 最长快进/快退时间跨度值
        maxDuration: 60 * minute,
        // 后台禁止自动暂停模式
        autoPauseDisable: 1, // 0:默认模式(浏览器同一组标签,播放页面切换到另外标签暂停播放), 1:禁止所有暂停播放,切换到同一组标签不暂停播放
        // 自动静音播放
        autoMutePlay: true
    };


    (() => {
        // 【沉浸式状态栏/网页主题色】设置主题色
        var meta = document.createElement('meta')
        meta.name = 'theme-color'
        meta.content = '#090811'
        document.querySelector('head').appendChild(meta)
        // 【横屏左右沉浸式背景色/视口覆盖非安全区】解决iPhone横屏时背景色未覆盖非安全区(即iPhone刘海区域)的部分
        if (videoSettings.viewportFitCover) {
            var viewport = document.querySelector('head > meta[name=viewport]')
            viewport.content = 'width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover'
        }
    })()

    var handle = () => {
        console.log('【视频控制条增强】开始...')
        // 【页面内容区域】获取元素
        var content = document.querySelector('body > div:nth-child(3) > div.sm\\:container > div > div.flex-1.order-first > div:first-child')
        // 【视频区域】样式调整
        var video = content.querySelector('div:first-child')
        video.id = 'video'
        video.classList.value = 'relative -mx-4 sm:m-0 mt-1'
        // 【视频区域】设备横屏时自动锚点到视频
        window.addEventListener('orientationchange', () => { setTimeout(() => document.querySelector('#video').scrollIntoView(), 400) })
        // 【视频控制条】获取元素
        var bar = video.nextElementSibling
        // 一键回到播放器
        if (videoSettings.playCtrlEnable) {
            var div = document.createElement('div')
            div.innerHTML = '<button id="btnControl" onclick="video.scrollIntoView();" type="button" class="relative inline-flex items-center rounded-md bg-transparent pl-2 pr-2 py-2 font-medium text-white hover:bg-primary focus:z-10" style="position: fixed; top: 50%; right: 10px; transform: translateY(-50%); z-index: 1000; opacity: 1; background-color: transparent; border: 1px solid white; border-radius: 8px;border: none;width: 40px; height: 40px;">🔁</button>'
            document.body.appendChild(div)
        }
        // 【视频控制条】显示
        bar.classList.remove('sm:hidden')
        // 【视频控制条】样式调整
        bar.classList.value = 'flex -mx-4 sm:m-0 mt-1 bg-black justify-center'
        // 【视频控制条】加入播放/暂停按钮
        var span = document.createElement('span')
        var player = document.querySelector('video.player')
        span.classList.value = 'isolate inline-flex rounded-md shadow-sm'
        span.style = `margin: 0 ${videoSettings.buttonMargin}`
        span.innerHTML = '<button id="btnPlay" onclick="player.togglePlay();" type="button" class="relative -ml-px inline-flex items-center rounded-md bg-transparent pl-2 pr-2 py-2 font-medium text-white ring-1 ring-inset ring-white hover:bg-primary focus:z-10">' + videoSettings.htmlPlay + '</button>'
        bar.insertBefore(span, bar.lastElementChild)

        // 自动禁音播放
        if (videoSettings.autoMutePlay) {
            player.muted = true
            player.play()

        }
        // 【视频控制条】播放/暂停时,变化播放按钮形态
        player.onplay = () => { document.querySelector('#btnPlay').innerHTML = videoSettings.htmlPause }

        //FIXME -  禁止播放规则1,就这样写了,有空改改.
        let windowIsBlurred
        window.onblur = () => { windowIsBlurred = true }
        window.onfocus = () => { windowIsBlurred = false }
        player.onpause = () => {
            if (windowIsBlurred && videoSettings.autoPauseDisable === 1) {
                player.play()
            } else { document.querySelector('#btnPlay').innerHTML = videoSettings.htmlPlay }
        }

        // 【视频控制条】修改时间跨度按钮
        if (videoSettings.durationBtnEnable) {
            var leftBtn = bar.querySelector('span:first-child > button:first-child')
            var rightBtn = bar.querySelector('span:last-child > button:last-child')
            leftBtn.removeAttribute('@click.prevent')
            leftBtn.onclick = () => { player.currentTime -= videoSettings.maxDuration }
            leftBtn.innerHTML = leftBtn.innerHTML.replace('10m', `${minute}m`)
            rightBtn.removeAttribute('@click.prevent')
            rightBtn.onclick = () => { player.currentTime += videoSettings.maxDuration }
            rightBtn.innerHTML = rightBtn.innerHTML.replace('10m', `${minute}m`)
        }


        console.log('【视频控制条增强】完成。')
    }
    var trigger = () => {
        return !!document.querySelector('body > div:nth-child(3) > div.sm\\:container > div > div.flex-1.order-first > div:first-child > div.relative')
    }
    var interval
    var timeout
    interval = setInterval(() => {
        if (trigger()) {
            clearInterval(interval)
            clearTimeout(timeout)
            handle()
            return
        }
    }, 200)
    timeout = setTimeout(() => {
        clearInterval(interval)
        console.log('【视频控制条增强】触发条件匹配超时,已取消。')
    }, 10 * 1000)


    //LINK - 删除广告
    function removeElements() {
        document.querySelectorAll('div[class*="lg:hidden"]')
        const allElements = document.querySelectorAll(
            'div[class^="root"], ' +//右下角弹出窗
            'div[class*="fixed"][class*="right-"][class*="bottom-"], ' +
            'div[class*="pt-"][class*="pb-"][class*="px-"]:not([class*="sm:"]), ' +
            'div[class*="lg:hidden"], ' +//视频下方广告
            'div[class*="lg:block"], ' +
            'div.ts-outstream-video, ' +//页面底部广告
            'iframe,' +
            'ul.mb-4.list-none.text-nord14,' +//视频下面跳官方广告telegram,和一些其他的广告
            '.prose,' +//石床澪
            'img[alt="MissAV takeover Fanza"]'//石床澪图片
        )
        //  console.log(`[missav页面修改] 找到 ${allElements.length} 个需要处理的元素`)
        allElements.forEach(el => {
            if (el.tagName.toLowerCase() === 'iframe') {
                console.log(`[missav页面修改] 正在移除的 iframe 元素`)
                el.remove()
            } else {
                //  console.log(`[missav页面修改] 正在隐藏的 div 元素,class 属性: ${el.className}`)
                el.style.display = 'none'
            }
        })
    }
    //LINK - 节流函数
    function throttle(fn, delay) {
        let lastCall = 0
        return function (...args) {
            const now = new Date().getTime()
            if (now - lastCall < delay) {
                return
            }
            lastCall = now
            return fn(...args)
        }
    }

    function toLink() {
        const origin = window.location.origin
        const allDivs = document.querySelectorAll('div.my-2.text-sm.text-nord4.truncate, div.flex-1.min-w-0')
        // console.log(`[missav页面修改] 找到 ${allDivs.length} 个需要处理的元素`)
        allDivs.forEach(div => {
            if (div.matches('div.flex-1.min-w-0')) {
                const h2 = div.querySelector('h2')
                if (h2) {
                    const text = h2.innerText
                    const link = document.createElement('a')
                    link.href = `${origin}/genres/${text}`
                    link.innerText = text
                    h2.innerHTML = ''
                    h2.appendChild(link)
                    console.log(`[missav页面修改] 已经将文本 "${text}" 转换为链接`)
                }
            }
        })
    }

    // 取消打开新窗口行为
    unsafeWindow.open = () => { }

    //LINK - 页面加载之后执行操作
    document.addEventListener('DOMContentLoaded', () => {

        GM_addStyle(`div.my-2.text-sm.text-nord4.truncate { white-space: normal;}`)
        const observer = new MutationObserver(throttle(() => {
            removeElements()
            toLink()

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


    document.addEventListener('ready', () => {
        //自动点击视频`显示更多`
        const showMore = document.querySelector('a.text-nord13.font-medium.flex.items-center')
        if (showMore) { showMore.click() }

        // 取消页面没焦点自动暂停
        const pause = unsafeWindow.player.pause
        if (videoSettings.autoPauseDisable == 0) {
            unsafeWindow.player.pause = () => {
                if (document.hasFocus()) {
                    pause()
                }
            }
        }
    })

})()