MissAVAutoPlay

Auto play/pause videos on MissAV with a keyboard shortcut Alt + A

// ==UserScript==
// @name         MissAVAutoPlay
// @namespace    http://tampermonkey.net/
// @version      1.0.2
// @description  Auto play/pause videos on MissAV with a keyboard shortcut Alt + A
// @description:ja MissAVの動画をショートカットキーAlt + Aで自動再生・停止します。
// @description:zh 使用快捷键Alt + A自动播放/暂停MissAV上的视频。
// @author       Nabbit
// @match        https://missav.ai/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=missav.ai
// @require      https://code.jquery.com/jquery-3.7.1.min.js
// @grant        none
// @license      Nabbit
// ==/UserScript==

/* global $ */
(function() {
    'use strict';

    const player = $('.plyr__poster');
    if ( player.length > 0 ) {
    // --- 多言語対応テキスト ---
    const translations = {
        en: {
            on: '▶️ Video autoplay is ON.',
            off: '⏹️ Video autoplay is OFF.',
            loaded: '✅ Autoplay script loaded | ALT+A to toggle'
        },
        ja: {
            on: '▶️ 動画の自動再生がONになりました。',
            off: '⏹️ 動画の自動再生がOFFになりました。',
            loaded: '✅ 自動再生スクリプト読込完了 | ALT+AでON/OFF'
        },
        zh: {
            on: '▶️ 视频自动播放已开启。',
            off: '⏹️ 视频自动播放已关闭。',
            loaded: '✅ 自动播放脚本已加载 | ALT+A 切换开关'
        }
    };

    /**
     * ブラウザの言語設定を取得する関数
     * @returns {string} 'ja', 'zh', または 'en'
     */
    function getLanguage() {
        const lang = navigator.language.toLowerCase();
        if (lang.startsWith('ja')) {
            return 'ja';
        }
        if (lang.startsWith('zh')) {
            return 'zh';
        }
        return 'en'; // デフォルトは英語
    }

    const i18n = translations[getLanguage()];
    let intervalId = null;
    let isAutoPlayEnabled = false;

    /**
     * 画面に通知メッセージを表示する関数 (jQuery版)
     * @param {string} message - 表示するテキスト
     * @param {number} duration - 表示時間(ミリ秒)
     */
    function showNotification(message, duration = 2000) {
        // 既存の通知があれば削除
        $('#video-autoplay-notifier').remove();

        // 通知用のdiv要素をjQueryで作成
        const $notifier = $('<div>', {
            id: 'video-autoplay-notifier',
            text: message
        }).css({
            'position': 'fixed',
            'bottom': '10%',
            'left': '50%',
            'transform': 'translateX(-50%)',
            'padding': '50px 100px',
            'background-color': 'rgba(0, 0, 0, 0.7)',
            'color': 'white',
            'border-radius': '8px',
            'z-index': '99999',
            'font-size': '15px',
            'font-family': 'sans-serif',
            'opacity': '1',
            'transition': 'opacity 0.5s ease-out'
        });

        // bodyに要素を追加し、指定時間後にフェードアウトして削除
        $notifier.appendTo('body').delay(duration).fadeOut(500, function() {
            $(this).remove();
        });
    }

    function startAutoPlay() {
        if (isAutoPlayEnabled) return;
        isAutoPlayEnabled = true;
        showNotification(i18n.on);

        // jQueryの.each()を使ってビデオを再生
        $('video').each(function() {
            if (this.paused) {
                this.play().catch(e => {}); // エラーは無視
            }
        });

        intervalId = setInterval(() => {
            $('video').each(function() {
                if (this.paused) {
                    this.play().catch(e => {}); // エラーは無視
                }
            });
        }, 1000);
    }

    function stopAutoPlay() {
        if (!isAutoPlayEnabled) return;
        isAutoPlayEnabled = false;
        clearInterval(intervalId);
        intervalId = null;
        showNotification(i18n.off);
    }

    // jQueryでイベントリスナーを設定
    $(window).on('keydown', (event) => {
        // ショートカットキー: Alt + A
        if (event.altKey && event.key.toLowerCase() === 'a') {
            event.preventDefault();
            if (isAutoPlayEnabled) {
                stopAutoPlay();
            } else {
                startAutoPlay();
            }
        }
    });

    // 最初にスクリプト読み込み完了の通知を表示
    showNotification(i18n.loaded);
    }
})();