Greasy Fork

Greasy Fork is available in English.

Ultimate Video Optimizer

高效视频流媒体性能优化脚本

当前为 2025-06-09 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Ultimate Video Optimizer
// @namespace    http://greasyfork.icu/zh-CN/users/1474228-moyu001
// @version      1.0
// @description  高效视频流媒体性能优化脚本
// @author       moyu001
// @match        *://*/*
// @grant        unsafeWindow
// @grant        GM_getValue
// @grant        GM_setValue
// @license      MIT
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';

    // 配置管理
    const ConfigManager = {
        defaults: {
            enableBufferOptimization: true,  // 是否启用缓冲优化
            maxBufferSize: 15,  // 最大缓冲时长(秒)
            minBufferSize: 2,  // 最小缓冲阈值(秒)
            hlsJsUrl: null,  // 用户自定义 Hls.js 路径(留空则使用默认 CDN)
            hlsJsVersion: '1.4.3',  // 用户自定义 Hls.js 版本(默认1.4.3,格式:主版本.次版本.修订版)
            logLevel: 'warn',  // 日志级别(error/warn/info/debug)
            scanInterval: 3000,  // 视频扫描间隔(毫秒)
            maxScanAttempts: 15,  // 最大扫描次数(避免无限扫描)
            suppressStallWarningsAfter: 3,  // 卡顿警告抑制阈值(超过后转为 debug 日志)
            bufferRatios: { hls: 1.3, mp4: 0.8, dash: 1.0, webm: 1.0 }, // 各类型视频的缓冲比例
            enableDebugLog: false, // 是否启用调试/优化日志(关闭可减少资源占用)
        },

        getConfig() {
            let storedConfig = {};
            try {
                if (typeof GM_getValue === 'function') {
                    storedConfig = GM_getValue('videoOptimizerConfig') || {};
                }
            } catch (e) {
                this.log('warn', 'GM_getValue 不可用,使用默认配置');
            }
            const allowedKeys = ['enableBufferOptimization', 'maxBufferSize', 'minBufferSize', 'hlsJsUrl', 'hlsJsVersion', 'logLevel', 'scanInterval', 'maxScanAttempts', 'suppressStallWarningsAfter', 'bufferRatios'];

            const safeStoredConfig = Object.fromEntries(
                Object.entries(storedConfig)
                    .filter(([key]) => allowedKeys.includes(key))
                    .filter(([key, value]) => {
                        if (['maxBufferSize', 'minBufferSize', 'scanInterval', 'maxScanAttempts', 'suppressStallWarningsAfter'].includes(key)) {
                            const numValue = typeof value === 'string' ? parseFloat(value) : value;
                            return typeof numValue === 'number' && !isNaN(numValue);
                        }
                        return true;
                    })
                    .map(([key, value]) => {
                        if (['maxBufferSize', 'minBufferSize', 'scanInterval', 'maxScanAttempts', 'suppressStallWarningsAfter'].includes(key) && typeof value === 'string') {
                            return [key, parseFloat(value)];
                        }
                        return [key, value];
                    })
            );
            const mergedConfig = { ...this.defaults, ...safeStoredConfig };

            const allowedLevels = ['error', 'warn', 'info', 'debug'];
            if (!allowedLevels.includes(mergedConfig.logLevel)) {
                ConfigManager.log('error', `无效的日志级别: ${mergedConfig.logLevel}(使用默认值 'info')`);
                mergedConfig.logLevel = 'info';
            }

            return mergedConfig;
        },

        get(key) {
            return this.getConfig()[key];
        },

        log(level, message) {
            const allowedLevels = ['error', 'warn', 'info', 'debug'];
            const configLevel = this.get('logLevel');
            const minLevelIndex = allowedLevels.indexOf(configLevel);
            const currentLevelIndex = allowedLevels.indexOf(level);
            const enableDebugLog = this.get('enableDebugLog');

            // enableDebugLog 为 true 时,所有 info/debug 日志都输出;warn/error 始终输出
            if (
                level === 'error' || level === 'warn' ||
                (enableDebugLog && (level === 'info' || level === 'debug')) ||
                (!enableDebugLog && currentLevelIndex <= minLevelIndex)
            ) {
                const prefix = `[VideoOptimizer:${level.toUpperCase()}]`;
                if (console[level]) {
                    console[level](`${prefix} ${message}`);
                } else {
                    console.log(`${prefix} ${message}`);
                }
            }
        },

        setConfig(newConfig) {
            try {
                if (typeof GM_setValue === 'function') {
                    GM_setValue('videoOptimizerConfig', newConfig);
                }
            } catch (e) {
                this.log('warn', 'GM_setValue 不可用,配置未保存');
            }
        },
    };

    // 智能视频检测器
    class VideoDetector {
        constructor() {
            this.videoElements = new WeakMap();
            this.scanAttempts = 0;
            this.maxScanAttempts = Math.max(ConfigManager.get('maxScanAttempts'), 1);
            this.scanInterval = ConfigManager.get('scanInterval');

            ConfigManager.log('info', 'Starting video detection');
            this.startMonitoring();
        }

        startMonitoring() {
            // 调整首次扫描时机:仅当 DOM 已加载时立即执行,否则等待 DOMContentLoaded
            if (document.readyState === 'interactive' || document.readyState === 'complete') {
                this.scanExistingVideos();
            } else {
                document.addEventListener('DOMContentLoaded', () => this.scanExistingVideos(), { once: true });
            }

            // 设置定期扫描
            this.scanIntervalId = setInterval(() => {
                this.scanExistingVideos();

                // 达到最大扫描次数后停止
                if (this.scanAttempts >= this.maxScanAttempts) {
                    ConfigManager.log('info', `Reached max scan attempts (${this.maxScanAttempts})`);
                    this.stopScanning();
                }
            }, this.scanInterval);

            // 设置DOM变化监听
            this.setupMutationObserver();
        }

        scanExistingVideos() {
            this.scanAttempts++;

            // 获取所有视频元素
            const videos = document.querySelectorAll('video');
            ConfigManager.log('debug', `Found ${videos.length} video elements on scan attempt ${this.scanAttempts}`);

            // 处理每个视频
            videos.forEach(video => {
                // 新增:检查视频源是否变更(通过 currentSrc 对比)
                const lastProcessedSrc = video.dataset.uvoLastSrc;
                const currentSrc = video.currentSrc || video.src;
                if (lastProcessedSrc && lastProcessedSrc !== currentSrc) {
                    // 源变更时清除标记,允许重新处理
                    video.removeAttribute('data-uvo-processed');
                    ConfigManager.log('debug', `Video source changed (${lastProcessedSrc} → ${currentSrc}), resetting processed flag`);
                }
                video.dataset.uvoLastSrc = currentSrc; // 记录当前源

                // 跳过已处理的视频(双重检查)
                if (this.videoElements.has(video) || video.hasAttribute('data-uvo-processed')) {
                    return;
                }

                // 检查有效性
                const validation = this.validateVideoElement(video);
                if (validation.valid) {
                    this.processVideoElement(video, validation.type);
                    video.setAttribute('data-uvo-processed', 'true'); // 标记为已处理
                } else {
                    ConfigManager.log('debug', `Skipping invalid video: ${validation.reason}`);
                }
            });
        }

        validateVideoElement(video) {
            // 基本类型检查
            if (!(video instanceof HTMLVideoElement)) {
                return { valid: false, reason: 'Not a video element' };
            }
            // 可见性检查
            if (document.readyState === 'interactive' || document.readyState === 'complete') {
                const computedStyle = getComputedStyle(video);
                let parent = video.parentElement;
                let isParentVisible = true;
                while (parent) {
                    const parentStyle = getComputedStyle(parent);
                    if (
                        parentStyle.display === 'none' ||
                        parentStyle.visibility === 'hidden' ||
                        parseFloat(parentStyle.opacity) <= 0
                    ) {
                        isParentVisible = false;
                        break;
                    }
                    parent = parent.parentElement;
                }
                const isVisible = (
                    computedStyle.display !== 'none' &&
                    computedStyle.visibility !== 'hidden' &&
                    parseFloat(computedStyle.opacity) > 0 &&
                    !video.hidden &&
                    isParentVisible &&
                    video.getBoundingClientRect().width > 0 &&
                    video.getBoundingClientRect().height > 0
                );
                if (!isVisible) {
                    return { valid: false, reason: 'Element or its parent is not visible' };
                }
            }
            // 尺寸检查
            const hasMinimumSize = (
                (video.offsetWidth > 50 && video.offsetHeight > 30) ||
                (video.clientWidth > 50 && video.clientHeight > 30)
            );
            if (!hasMinimumSize) {
                return { valid: false, reason: 'Element too small (width>50px & height>30px required)' };
            }
            // 内容检查
            const hasContent = (
                video.src ||
                video.currentSrc ||
                video.querySelector('source[src]') ||
                video.querySelector('source[type]')
            );
            if (!hasContent) {
                return { valid: false, reason: 'No video source' };
            }
            // 识别媒体类型
            const type = this.identifyMediaType(video);
            if (!type) {
                return { valid: false, reason: 'Unsupported media type' };
            }
            return { valid: true, type };
        }

        processVideoElement(video, type) {
            ConfigManager.log('info', `Processing ${type.toUpperCase()} video element`);

            try {
                // 创建优化器
                const optimizer = new VideoOptimizer(video, type);
                this.videoElements.set(video, optimizer);

                // 添加销毁监听
                this.setupCleanupListener(video);

                // 优化:标记具体优化类型(如 data-uvo-active="hls")
                video.setAttribute('data-uvo-active', type);

                return true;
            } catch (e) {
                ConfigManager.log('error', `Failed to process video: ${e.message}`);
                return false;
            }
        }

        setupCleanupListener(video) {
            // 初始化观察者数组(修正:移除错误的覆盖操作)
            video._cleanupObservers = [];

            // 原有父节点观察者
            const parentObserver = new MutationObserver(() => {
                if (!document.contains(video)) {
                    ConfigManager.log('info', 'Video element removed from DOM (via parent mutation)');
                    this.cleanupVideo(video);
                    parentObserver.disconnect(); // 触发时断开自身
                }
            });
            if (video.parentNode) {
                parentObserver.observe(video.parentNode, { childList: true });
            }
            video._cleanupObservers.push(parentObserver); // 正确添加

            // 新增自身观察者
            const selfObserver = new MutationObserver(() => {
                if (!document.contains(video)) {
                    ConfigManager.log('info', 'Video element removed from DOM (via self mutation)');
                    this.cleanupVideo(video);
                    selfObserver.disconnect(); // 触发时断开自身
                }
            });
            selfObserver.observe(video, { attributes: false, childList: false, subtree: false });
            video._cleanupObservers.push(selfObserver); // 正确添加

            // 新增:监听视频元素src变更和子source元素变化
            const updateObserver = new MutationObserver(() => {
                const oldType = video.dataset.uvoActive;
                const newValidation = this.validateVideoElement(video);

                // 类型变更或片源更新时重新初始化
                if (newValidation.valid && newValidation.type !== oldType) {
                    ConfigManager.log('info', `Video source updated (${oldType} → ${newValidation.type})`);
                    this.cleanupVideo(video);
                    this.processVideoElement(video, newValidation.type);

                    // 新增:触发后断开并移除自身引用
                    updateObserver.disconnect();
                    const index = video._cleanupObservers.indexOf(updateObserver);
                    if (index > -1) {
                        video._cleanupObservers.splice(index, 1);
                    }
                }
            });

            updateObserver.observe(video, {
                attributes: true,
                attributeFilter: ['src', 'currentSrc'], // 监听src属性变更
                childList: true, // 监听子source元素增删
                subtree: true
            });

            // 存储观察者引用,用于清理
            video._cleanupObservers.push(updateObserver); // 正确添加
        }

        cleanupVideo(video) {
            const optimizer = this.videoElements.get(video);
            if (optimizer) {
                optimizer.cleanup();
                this.videoElements.delete(video);
            }

            // 新增:空值检查(避免 undefined 调用 forEach)
            if (video._cleanupObservers && Array.isArray(video._cleanupObservers)) {
                video._cleanupObservers.forEach(observer => observer.disconnect());
                delete video._cleanupObservers;
            }
        }

        /**
         * 识别视频媒体类型(检测优先级从高到低):
         * 1. 视频元素自身的 type 属性(如 video.type)
         * 2. 视频源 URL 的扩展名(如 .m3u8、.mpd)
         * 3. 子 source 元素的 type 属性或 src 扩展名
         * 4. 视频元素的 data-type 属性(如 data-type="hls")
         * 5. 默认返回 mp4(兼容未识别的视频)
         * @param {HTMLVideoElement} video 目标视频元素
         * @returns {'hls'|'mp4'|'dash'|'webm'|null} 媒体类型
         */
        identifyMediaType(video) {
            // 修正:正则表达式匹配主文件名(排除查询参数和哈希)
            const hlsRegex = /\.m3u8(\?.*)?$/i;
            const dashRegex = /\.mpd(\?.*)?$/i;
            const mp4Regex = /\.mp4(\?.*)?$/i;
            const m4sRegex = /\.m4s(\?.*)?$/i;
            const webmRegex = /\.webm(\?.*)?$/i;
            // 1. 检查type属性(修正:用 getAttribute 获取)
            const typeAttr = video.getAttribute('type');
            if (typeAttr === 'application/vnd.apple.mpegurl') return 'hls';
            if (typeAttr === 'video/mp4') return 'mp4';
            if (typeAttr === 'application/dash+xml') return 'dash';
            if (typeAttr === 'video/webm') return 'webm';
            // 2. 检查src/扩展名
            const src = video.currentSrc || video.src;
            if (src) {
                if (hlsRegex.test(src)) return 'hls';
                if (dashRegex.test(src)) return 'dash';
                if (mp4Regex.test(src)) return 'mp4';
                if (m4sRegex.test(src)) return 'mp4';
                if (webmRegex.test(src)) return 'webm';
            }
            // 3. 检查source元素
            const sources = video.querySelectorAll('source');
            for (const source of sources) {
                const sourceType = source.getAttribute('type');
                if (sourceType === 'application/vnd.apple.mpegurl') return 'hls';
                if (sourceType === 'video/mp4') return 'mp4';
                if (sourceType === 'application/dash+xml') return 'dash';
                if (sourceType === 'video/webm') return 'webm';
                if (source.src) {
                    if (hlsRegex.test(source.src)) return 'hls';
                    if (dashRegex.test(source.src)) return 'dash';
                    if (mp4Regex.test(source.src)) return 'mp4';
                    if (m4sRegex.test(source.src)) return 'mp4';
                    if (webmRegex.test(source.src)) return 'webm';
                }
            }
            // 4. 检查data属性
            if (video.dataset.type === 'hls') return 'hls';
            if (video.dataset.type === 'dash') return 'dash';
            if (video.dataset.type === 'mp4') return 'mp4';
            // 5. 未识别类型返回 null
            return null;
        }

        setupMutationObserver() {
            this.mutationTimeout = null;
            this.mutationDebounce = ConfigManager.get('mutationDebounce') || 200;
            this.lastScanTime = 0; // 新增:记录上次扫描时间
            this.minScanInterval = 1000; // 新增:最小扫描间隔(1秒)
            this.mutationObserver = new MutationObserver(mutations => {
                const now = Date.now();
                // 新增:控制扫描频率,避免短时间内重复扫描
                if (now - this.lastScanTime < this.minScanInterval) {
                    ConfigManager.log('debug', '跳过高频 DOM 变化扫描(间隔不足)');
                    return;
                }
                this.lastScanTime = now;

                // 立即执行一次扫描(处理紧急变更)
                this.scanExistingVideos();
                // 清除上一次未执行的防抖任务
                clearTimeout(this.mutationTimeout);
                // 延迟 200ms 处理 DOM 变化,合并短时间内的多次突变
                this.mutationTimeout = setTimeout(() => {
                    mutations.forEach(mutation => {
                        for (const node of mutation.addedNodes) {
                            // 检查添加的节点是否是视频
                            if (node.nodeName === 'VIDEO') {
                                const validation = this.validateVideoElement(node);
                                if (validation.valid) {
                                    this.processVideoElement(node, validation.type);
                                }
                            }
                            // 检查添加的节点内是否包含视频
                            else if (node.querySelectorAll) {
                                const videos = node.querySelectorAll('video');
                                videos.forEach(video => {
                                    const validation = this.validateVideoElement(video);
                                    if (validation.valid) {
                                        this.processVideoElement(video, validation.type);
                                    }
                                });
                            }
                        }
                    });
                }, this.mutationDebounce);
            });

            this.mutationObserver.observe(document, {
                childList: true,
                subtree: true,
                attributes: false
            });
        }

        stopScanning() {
            if (this.scanIntervalId) {
                clearInterval(this.scanIntervalId);
                this.scanIntervalId = null;
                ConfigManager.log('info', 'Stopped periodic scanning');
            }
            if (this.mutationTimeout !== null) {
                clearTimeout(this.mutationTimeout);
                this.mutationTimeout = null;
            }
            this.mutationTimeout = undefined;
        }
    }

    // 视频优化器
    class VideoOptimizer {
        constructor(video, type) {
            this.video = video;
            this.type = type;
            this.initialized = false;
            this.active = true;
            this.stallCount = 0; // 新增:记录卡顿次数
            this.lastStallTime = 0; // 新增:记录上次卡顿时间

            // 添加优化器引用
            video.optimizerInstance = this;

            ConfigManager.log('info', `Creating optimizer for ${type.toUpperCase()} video`);

            // 启动异步初始化(不阻塞构造函数)
            this.startInitialization();
        }

        // 新增:独立异步初始化方法
        async startInitialization() {
            try {
                await this.initOptimizer();
                this.initialized = true; // 初始化完成后标记
            } catch (e) {
                ConfigManager.log('error', `初始化失败: ${e.message}`);
                this.cleanup();
            }
        }

        /**
         * 初始化优化器(异步入口方法)
         * @returns {Promise<void>}
         */
        async initOptimizer() {
            if (!this.active) {
                ConfigManager.log('warn', 'Optimizer is inactive, skipping initialization');
                return;
            }

            try {
                // 新增:初始化过程中定期检查 active 状态(防止中途被清理)
                const checkActive = () => {
                    if (!this.active) {
                        throw new Error('Optimizer was deactivated during initialization');
                    }
                };

                // HLS 类型初始化(新增:加载前、加载后双重检查)
                if (this.type === 'hls') {
                    checkActive(); // 初始化前检查
                    await this.initHlsOptimizer();
                    checkActive(); // 加载完成后强制检查
                }

                // 缓冲优化器初始化(新增:类存在性检查后检查)
                if (typeof BufferOptimizer === 'undefined') {
                    throw new Error('BufferOptimizer class is not defined');
                }
                checkActive();

                // 初始化缓冲优化器(原有逻辑)
                this.bufferOptimizer = new BufferOptimizer(this.video, this.type);
                checkActive(); // 检查状态

                // 设置事件监听(原有逻辑)
                this.setupEventListeners();
                checkActive(); // 检查状态

                this.initialized = true;
                ConfigManager.log('info', '优化器初始化成功');

                // 延迟触发初始缓冲检查(原有逻辑)
                setTimeout(() => {
                    this.bufferOptimizer?.ensureBuffer();
                }, 1000);
            } catch (e) {
                ConfigManager.log('error', `优化器初始化失败: ${e.message}`);
                this.cleanup(); // 初始化失败时清理资源
            }
        }

        /**
         * 初始化 HLS 优化器(异步方法)
         * @returns {Promise<void>}
         */

        async initHlsOptimizer() {
            // 优先使用用户配置的 Hls.js 路径
            const customHlsUrl = ConfigManager.get('hlsJsUrl');
            const hlsVersion = ConfigManager.get('hlsJsVersion');
            const versionRegex = /^\d+\.\d+\.\d+$/;
            if (!versionRegex.test(hlsVersion)) {
                throw new Error(`无效的 Hls.js 版本格式: ${hlsVersion}(需为 x.y.z 格式)`);
            }

            // 新增:明确版本比较逻辑(主版本 >=1,次版本 >=3)
            const [major, minor, patch] = hlsVersion.split('.').map(Number);
            if (major < 1 || (major === 1 && minor < 3)) {
                throw new Error(`Hls.js 版本过低: ${hlsVersion}(最低要求 1.3.0)`);
            }

            const defaultHlsUrls = [
                `https://cdn.jsdelivr.net/npm/hls.js@${hlsVersion}/dist/hls.min.js`,
                `https://unpkg.com/hls.js@${hlsVersion}/dist/hls.min.js`
            ];

            const hlsUrls = customHlsUrl ? [customHlsUrl] : defaultHlsUrls;

            for (const url of hlsUrls) {
                let script; // 声明 script 变量用于后续清理
                try {
                    if (typeof window.Hls !== 'undefined') break;

                    ConfigManager.log('info', `尝试加载 Hls.js 地址: ${url}`);
                    await Promise.race([
                        new Promise((resolve, reject) => {
                            script = document.createElement('script'); // 保存 script 引用
                            script.src = url;
                            // 保存事件监听器引用(新增)
                            script.onload = () => {
                                script.onload = null; // 清理监听器
                                resolve();
                            };
                            script.onerror = (e) => {
                                script.onerror = null; // 清理监听器
                                reject(e);
                            };
                            document.head.appendChild(script);
                        }),
                        new Promise((_, reject) =>
                            setTimeout(() => reject(new Error('Script load timeout')), 5000)
                        )
                    ]);

                    ConfigManager.log('info', 'Hls.js 加载成功');
                    try {
                        this.setupHlsPlayer();
                        return;
                    } catch (setupError) {
                        ConfigManager.log('error', `HLS 播放器配置失败: ${setupError.message}`);
                    }
                } catch (e) {
                    ConfigManager.log('warn', `Hls.js 地址 ${url} 加载失败: ${e.message}(等待 500ms 后尝试下一个)`);
                    // 新增:加载失败时移除残留的 script 标签
                    if (script) {
                        // 移除前清理事件监听器(新增)
                        script.onload = null;
                        script.onerror = null;
                        document.head.removeChild(script);
                        script = null;
                    }
                    await new Promise(resolve => setTimeout(resolve, 500));
                }
            }

            throw new Error(`所有 Hls.js 地址加载失败(尝试地址: ${hlsUrls.join(', ')})`);
        }

        /**
         * 配置 HLS 播放器(依赖 Hls.js)
         */
        setupHlsPlayer() {
            // 检查库是否成功加载
            if (typeof window.Hls === 'undefined') {
                ConfigManager.log('error', 'Hls.js 库未加载');
                return;
            }

            // 新增:检查视频元素是否仍存在于DOM中
            if (!document.contains(this.video)) {
                ConfigManager.log('warn', '视频元素已被移除,跳过 HLS 播放器配置');
                return;
            }

            ConfigManager.log('info', 'Setting up Hls.js player');

            try {
                this.hls = new window.Hls({
                    maxBufferLength: ConfigManager.get('maxBufferSize'),
                    backBufferLength: 5,
                    lowLatencyMode: true,
                    maxMaxBufferLength: 30
                });

                // 附加到视频元素
                this.hls.attachMedia(this.video);

                // 加载源
                const url = this.video.currentSrc || this.video.src;
                if (url) {
                    this.hls.loadSource(url);
                    ConfigManager.log('info', `Loading HLS stream from: ${url}`);
                } else {
                    ConfigManager.log('warn', 'No video source available for HLS');
                }

                // 新增:监听 HLS 质量切换事件(记录清晰度变化)
                this.hls.on(window.Hls.Events.LEVEL_SWITCHED, (event, data) => {
                    const level = this.hls.levels[data.level];
                    ConfigManager.log('debug', `HLS 质量切换: 分辨率 ${level.width}x${level.height}, 码率 ${level.bitrate}bps`);
                });

                // 新增:监听缓冲追加事件(优化缓冲策略)
                this.hls.on(window.Hls.Events.BUFFER_APPENDED, (event, data) => {
                    if (this.bufferOptimizer) {
                        this.bufferOptimizer.handleBufferUpdate(data.details);
                    }
                });

                // 新增:监听质量加载事件(跟踪加载进度)
                this.hls.on(window.Hls.Events.LEVEL_LOADING, (event, data) => {
                    ConfigManager.log('debug', `加载质量 ${data.level}(类型: ${data.type})`);
                });

                // 监听HLS事件(优化错误记录)
                this.hls.on(window.Hls.Events.ERROR, (event, data) => {
                    const errorType = data.type || '未知类型';
                    const errorDetails = data.details || '无详细错误信息';
                    const isFatal = data.fatal ? '致命' : '非致命';

                    ConfigManager.log(
                        data.fatal ? 'error' : 'warn',
                        `HLS ${isFatal}错误(类型: ${errorType}, 详情: ${errorDetails}`
                    );
                });
            } catch (e) {
                ConfigManager.log('error', `HLS 播放器配置失败: ${e.message}`);
            }
        }

        setupEventListeners() {
            // 确保所有事件都能捕获到
            const events = [
                'play', 'pause', 'seeking', 'seeked',
                'timeupdate', 'error', 'progress',
                'waiting', 'stalled', 'canplay', 'loadedmetadata',
                'loadeddata', 'ended'
            ];
            this.eventHandlers = this.eventHandlers || {};
            const playHandler = () => {
                this.bufferOptimizer?.onPlay && this.bufferOptimizer.onPlay();
            };
            this.video.addEventListener('play', playHandler);
            this.eventHandlers['play'] = playHandler;
            const stallHandler = () => {
                this.handleStall();
            };
            this.video.addEventListener('stalled', stallHandler);
            this.eventHandlers['stalled'] = stallHandler;
            events.forEach(eventName => {
                const handler = (e) => this.handlePlayerEvent(eventName, e);
                this.video.addEventListener(eventName, handler);
                this.eventHandlers[eventName] = handler;
            });
            ConfigManager.log('debug', 'Event listeners set up');
        }

        /**
         * 处理播放器事件(核心逻辑)
         * @param {string} type 事件类型
         * @param {Event} event 事件对象
         */
        handlePlayerEvent(type, event) {
            switch(type) {
                case 'seeking':
                    ConfigManager.log('info', `Seeking to ${this.video.currentTime.toFixed(2)}s`);
                    break;

                case 'play':
                    ConfigManager.log('info', 'Playback started');
                    if (this.bufferOptimizer) {
                        this.bufferOptimizer.ensureBuffer();
                    }
                    break;

                case 'pause':
                    ConfigManager.log('debug', 'Playback paused');
                    break;

                case 'timeupdate': {
                    // 根据日志级别调整记录频率:debug 全量记录,info 抽样(10%)
                    const shouldLog = ConfigManager.get('logLevel') === 'debug'
                        ? true
                        : Math.random() < 0.1;
                    if (shouldLog) {
                        ConfigManager.log('debug', `当前播放时间: ${this.video.currentTime.toFixed(2)}s`);
                    }
                    break;
                }

                case 'error':
                    ConfigManager.log('warn', 'Video error detected: ' + (this.video.error ? this.video.error.message : 'Unknown error'));
                    break;

                case 'seeked':
                    ConfigManager.log('debug', `Seeked to ${this.video.currentTime.toFixed(2)}s`);
                    break;

                case 'progress': {
                    if (this.video.buffered.length === 0) break;

                    // 根据日志级别调整记录频率:debug 全量记录,info 抽样(5%)
                    const shouldLog = ConfigManager.get('logLevel') === 'debug'
                        ? true
                        : Math.random() < 0.05;
                    if (shouldLog) {
                        const bufferedEnd = this.video.buffered.end(this.video.buffered.length - 1);
                        ConfigManager.log('debug', `已缓冲至: ${bufferedEnd.toFixed(2)}s`);
                    }
                    break;
                }

                case 'ended':
                    ConfigManager.log('info', '视频播放结束,清理缓冲资源');
                    this.bufferOptimizer?.stopOptimization(); // 触发缓冲优化器停止
                    break;

                case 'waiting':
                case 'stalled': {
                    const now = Date.now();
                    const stallWarningThreshold = ConfigManager.get('suppressStallWarningsAfter');
                    if (now - this.lastStallTime > 1000) {
                        this.stallCount++;
                        this.lastStallTime = now;
                    }
                    const logLevel = this.stallCount > stallWarningThreshold ? 'debug' : 'warn';
                    ConfigManager.log(
                        logLevel,
                        `播放卡顿(类型: ${type}, 累计次数: ${this.stallCount}, 阈值: ${stallWarningThreshold})`
                    );
                    break;
                }

                case 'canplay':
                    ConfigManager.log('debug', 'Enough data available to play');
                    break;

                case 'loadedmetadata':
                    ConfigManager.log('debug', `Video metadata loaded. Duration: ${this.video.duration.toFixed(1)}s`);
                    break;
            }
        }

        cleanup() {
            ConfigManager.log('info', '清理优化器资源(开始)');
            if (this.eventHandlers && typeof this.eventHandlers === 'object') {
                Object.entries(this.eventHandlers).forEach(([eventName, handler]) => {
                    this.video.removeEventListener(eventName, handler);
                });
                this.eventHandlers = null;
            }
            if (this.hls) {
                this.hls.destroy();
                this.hls = null;
            }
            if (this.bufferOptimizer) {
                this.bufferOptimizer.stopOptimization && this.bufferOptimizer.stopOptimization();
                this.bufferOptimizer = null;
            }
            if (this.video.optimizerInstance) {
                delete this.video.optimizerInstance;
            }
            // 移除 hasEventListener 检查(非标准 API)
            this.stallCount = 0;
            this.lastStallTime = 0;
            this.active = false;
            this.initialized = false;
            ConfigManager.log('info', '清理优化器资源(完成)');
        }
    }

    /**
     * 缓冲优化器(核心性能模块)
     * 负责根据网络速度动态调整视频缓冲大小,平衡加载速度与播放流畅性。
     * 支持 HLS 等流媒体协议的缓冲策略优化,通过采样网络速度、监听缓冲事件实现智能调整。
     */
    class BufferOptimizer {
        /**
         * 初始化缓冲优化器
         * @param {HTMLVideoElement} video 目标视频元素
         * @param {string} type 视频类型(hls/mp4/dash)
         */
        constructor(video, type) {
            this.video = video;
            this.type = type;
            this.optimizationInterval = null;
            this.networkSpeedKBps = 0;
            this.speedSamples = [];
            this.targetBuffer = ConfigManager.get('maxBufferSize');
            this.minBuffer = ConfigManager.get('minBufferSize');
            this.active = true;
            const bufferRatios = ConfigManager.get('bufferRatios') || {};
            const defaultRatios = { hls: 1.3, mp4: 0.8, dash: 1.0, webm: 1.0 };
            this.bufferRatio = typeof bufferRatios[type] === 'number' && bufferRatios[type] > 0
                ? bufferRatios[type]
                : defaultRatios[type];
            const baseConfig = ConfigManager.getConfig();
            this.maxBufferSize = Math.max(Math.round(baseConfig.maxBufferSize * this.bufferRatio), 1);
            this.minBufferSize = Math.max(Math.round(baseConfig.minBufferSize * this.bufferRatio), 1);
            ConfigManager.log('info', `Creating buffer optimizer for ${type.toUpperCase()} video`);
            this.startOptimizationLoop();
        }

        /**
         * 动态调整缓冲阈值(示例逻辑:HLS增加30%,MP4减少20%)
         * @param {number} baseSize 基础阈值
         * @returns {number} 调整后的阈值
         */
        getDynamicBufferSize(baseSize) {
            switch (this.type) {
                case 'hls':
                    return Math.round(baseSize * 1.3);
                case 'mp4':
                    return Math.round(baseSize * 0.8);
                default:
                    return baseSize;
            }
        }

        /**
         * 启动缓冲优化循环(定期检查缓冲状态)
         */
        startOptimizationLoop() {
            ConfigManager.log('debug', '启动缓冲优化循环');
            this.optimizationInterval = setInterval(() => {
                this.ensureBuffer();
                this.adjustBufferSize();
            }, 2000);
        }

        /**
         * 确保当前缓冲满足最小阈值(播放前/恢复播放时调用)
         * 若当前缓冲小于最小阈值,触发缓冲策略调整(如降低清晰度、增加预加载)
         * @returns {void}
         */
        ensureBuffer() {
            if (this.video.buffered.length === 0) {
                ConfigManager.log('info', 'Starting buffer preload');
                this.preloadNextSegment(this.video.currentTime);
            } else {
                const end = this.video.buffered.end(this.video.buffered.length - 1);
                const bufferSize = end - this.video.currentTime;
                ConfigManager.log('debug', `Current buffer: ${bufferSize.toFixed(1)}s`);
            }
        }

        /**
         * 动态调整目标缓冲大小(根据网络速度和播放状态)
         * @returns {void}
         */
        adjustBufferSize() {
            // 使用带时间戳的采样计算平均速度
            const validSamples = this.speedSamples.map(s => s.speed);
            const avgSpeed = validSamples.reduce((sum, val) => sum + val, 0) / validSamples.length || 0;

            // 网络速度越快,允许更大的缓冲(最大不超过 maxBufferSize)
            this.targetBuffer = Math.min(
                ConfigManager.get('maxBufferSize'),
                this.minBuffer + (avgSpeed / 100) * 2 // 示例公式:每100KB/s增加2秒缓冲
            );

            // 新增:确保目标缓冲不低于最小阈值(避免弱网下缓冲过小)
            this.targetBuffer = Math.max(this.targetBuffer, this.minBuffer);

            ConfigManager.log('info', `优化:动态调整目标缓冲至 ${this.targetBuffer.toFixed(1)}s(当前网速: ${avgSpeed.toFixed(1)}KB/s)`);
        }

        /**
         * 处理缓冲更新事件(带空采样防御)
         * @param {Object} bufferDetails 缓冲详细信息(包含 chunkSize、duration 等)
         */
        handleBufferUpdate(bufferDetails) {
            if (this.type !== 'hls') return;
            if (!bufferDetails) {
                ConfigManager.log('debug', 'Buffer details is undefined, skipping update');
                return;
            }
            const isChunkSizeValid = typeof bufferDetails.chunkSize === 'number' && !isNaN(bufferDetails.chunkSize);
            const isDurationValid = typeof bufferDetails.duration === 'number' && !isNaN(bufferDetails.duration);
            const chunkSize = isChunkSizeValid ? Math.abs(bufferDetails.chunkSize) : 1;
            const chunkDuration = isDurationValid ? Math.abs(bufferDetails.duration) : 0.1;
            if (chunkDuration === 0) {
                ConfigManager.log('warn', 'chunkDuration 为0,跳过速度计算');
                return;
            }
            const speed = chunkSize / 1024 / chunkDuration;
            this.speedSamples.push({
                time: Date.now(),
                speed: speed
            });
            const now = Date.now();
            this.speedSamples = this.speedSamples.filter(sample => now - sample.time <= 30000);
            if (this.speedSamples.length > 100) {
                this.speedSamples = this.speedSamples.slice(-100);
            }
            if (this.speedSamples.length === 0) {
                ConfigManager.log('debug', 'No speed samples available, skipping buffer check');
                return;
            }
        }

        /**
         * 触发额外缓冲加载(通过调整播放器属性或HLS配置)
         */
        triggerBufferLoad() {
            if (this.type === 'hls') {
                // 优先通过 optimizerInstance.hls 获取 hls 实例
                const hlsInstance = (this.video.optimizerInstance && this.video.optimizerInstance.hls) ? this.video.optimizerInstance.hls : this.video.hls;
                if (hlsInstance) {
                    hlsInstance.config.maxBufferLength = this.targetBuffer;
                    ConfigManager.log('info', `优化:调整HLS maxBufferLength至 ${this.targetBuffer}`);
                } else {
                    ConfigManager.log('warn', 'HLS 实例未找到,无法调整缓冲长度');
                }
            } else {
                // 非HLS类型尝试手动触发加载(兼容性处理)
                this.video.load();
                ConfigManager.log('info', '优化:触发非HLS视频的手动缓冲加载');
            }
        }

        /**
         * 停止缓冲优化(清理资源)
         * @returns {void}
         */
        stopOptimization() {
            this.speedSamples = []; // 清空采样数据
            this.active = false; // 标记为非活跃状态
            ConfigManager.log('debug', 'Buffer optimizer stopped');
        }

        startNetworkSpeedMonitor() {
            // 每30秒测量一次网络速度
            this.networkMonitorInterval = setInterval(() => {
                this.measureNetworkSpeed();
            }, 30000);

            // 初始测量
            setTimeout(() => this.measureNetworkSpeed(), 5000);
        }

        measureNetworkSpeed() {
            const img = new Image();
            const startTime = Date.now();
            const testFileUrl = `https://via.placeholder.com/10?r=${Math.random()}`;

            img.onload = () => {
                const duration = (Date.now() - startTime) / 1000;
                const sizeKB = 0.01; // 10像素PNG大约是10字节
                const speedKBps = sizeKB / duration;

                if (speedKBps > 0) {
                    this.networkSpeedKBps = speedKBps;

                    // 平滑更新值
                    if (this.prevNetworkSpeed) {
                        this.networkSpeedKBps = (this.prevNetworkSpeed * 0.7 + speedKBps * 0.3);
                    }

                    this.prevNetworkSpeed = this.networkSpeedKBps;
                    ConfigManager.log('debug', `Network speed: ${this.networkSpeedKBps.toFixed(1)} KB/s`);
                }
            };

            img.onerror = () => {
                ConfigManager.log('debug', 'Network speed test failed');
            };

            img.src = testFileUrl;
        }

        optimize() {
            const now = Date.now();

            // 确保有足够的时间间隔
            if (now - this.lastOptimizeTime < 1900) return;
            this.lastOptimizeTime = now;

            if (!this.video.readyState || this.video.readyState < 1) return;

            const position = this.video.currentTime;
            const buffered = this.video.buffered;

            if (buffered.length === 0) {
                ConfigManager.log('debug', 'No buffered data available');
                this.preloadNextSegment(position);
                return;
            }

            const currentBufferEnd = buffered.end(buffered.length - 1);
            const bufferSize = currentBufferEnd - position;

            // 添加到历史记录
            this.bufferHistory.push({
                time: now,
                size: bufferSize,
                position
            });

            // 保留最近10条记录
            if (this.bufferHistory.length > 10) {
                this.bufferHistory.shift();
            }

            // 动态调整缓冲大小
            const targetSize = this.calculateTargetBufferSize(bufferSize);

            // 需要预加载更多数据
            if (bufferSize < targetSize) {
                ConfigManager.log('info', `Buffer too small (${bufferSize.toFixed(1)}s < ${targetSize.toFixed(1)}s)`);
                this.preloadNextSegment(position);
            } else {
                ConfigManager.log('debug', `Buffer ${bufferSize.toFixed(1)}s ≥ target ${targetSize.toFixed(1)}s`);
            }

            // 检查卡顿
            if (position === this.lastPosition && position > 0) {
                // 仅在缓冲区有足够大小时才标记为卡顿
                if (bufferSize > 1.0) {
                    ConfigManager.log('warn', 'Playback stalled despite sufficient buffer');
                    this.handleStall(position);
                }
            }
            this.lastPosition = position;
        }

        calculateTargetBufferSize(currentSize) {
            const minSize = ConfigManager.get('minBufferSize');
            const maxSize = ConfigManager.get('maxBufferSize');

            // 基本值范围限制
            let targetSize = Math.max(minSize, Math.min(currentSize, maxSize * 0.9));

            // 根据网络状况动态调整
            if (this.networkSpeedKBps > 0) {
                if (this.networkSpeedKBps < 100) { // 低速网络 < 100KB/s
                    targetSize = Math.max(targetSize, maxSize * 0.8);
                    ConfigManager.log('debug', 'Slow network detected, increasing buffer target');
                } else if (this.networkSpeedKBps > 500) { // 高速网络 > 500KB/s
                    targetSize = Math.max(minSize, targetSize * 0.7);
                    ConfigManager.log('debug', 'Fast network detected, reducing buffer target');
                }
            }

            // 根据历史趋势调整
            if (this.bufferHistory.length >= 3) {
                const recent = this.bufferHistory.slice(-3);
                const sizeSum = recent.reduce((sum, item) => sum + item.size, 0);
                const avgSize = sizeSum / recent.length;

                // 如果缓冲区在减少,增加目标值
                if (avgSize < targetSize * 0.9) {
                    targetSize *= 1.2;
                    ConfigManager.log('debug', 'Buffer decreasing, increasing target');
                } else if (avgSize > targetSize * 1.2) {
                    targetSize *= 0.9;
                    ConfigManager.log('debug', 'Buffer increasing, reducing target');
                }
            }

            return Math.min(maxSize, Math.max(minSize, targetSize));
        }

        // 增强的卡顿处理
        handleStall(position) {
            const now = Date.now();

            // 记录当前播放状态
            const playState = this.video.paused ? "paused" : "playing";

            // 检查卡顿位置是否在可用缓冲区内
            let inBufferedRange = false;

            if (this.video.buffered.length > 0) {
                const currentBufferStart = this.video.buffered.start(0);
                const currentBufferEnd = this.video.buffered.end(this.video.buffered.length - 1);
                inBufferedRange = (position >= currentBufferStart && position <= currentBufferEnd);
            }

            ConfigManager.log('warn',
                `优化:检测到卡顿,位置 ${position.toFixed(2)}s(状态: ${playState}, inBuffer: ${inBufferedRange})`);

            // 尝试跳过卡顿点(频率限制)
            if (!this.video.paused && !inBufferedRange && (now - this.lastSkipTime) > 5000) {
                const skipPosition = Math.min(
                    (this.video.duration || 1000000) - 0.5,
                    position + 0.5
                );

                ConfigManager.log('info', `优化:自动跳过卡顿点,跳转到 ${skipPosition.toFixed(2)}s`);
                this.video.currentTime = skipPosition;
                this.lastSkipTime = now;
            }

            // 总是尝试预加载当前位置数据
            this.preloadNextSegment(position);
        }

        preloadNextSegment(position) {
            // HLS特定处理
            if (this.type === 'hls' && window.Hls && this.hls) {
                try {
                    ConfigManager.log('info', 'Preloading next HLS segment');

                    // 检查当前播放列表
                    if (this.hls.levels && this.hls.currentLevel >= 0) {
                        // 获取下一个片段
                        const frag = this.hls.getNextFragment(position);
                        if (frag) {
                            this.hls.loadFragment(frag);
                            ConfigManager.log('debug', `Loading fragment ${frag.sn} from level ${frag.level}`);
                        }
                    } else {
                        // 简单重新加载
                        this.hls.startLoad(position);
                    }
                } catch (e) {
                    ConfigManager.log('warn', 'HLS preloading failed: ' + e.message);
                }
                return;
            }

            // 通用预加载处理
            const rangeSize = this.calculateTargetBufferSize(0);
            ConfigManager.log('info', `Preloading ${rangeSize.toFixed(1)}s of data`);

            // 模拟预加载行为
            if (this.video.networkState === HTMLMediaElement.NETWORK_IDLE) {
                this.video.dispatchEvent(new Event('progress'));
            }
        }

        ensureBuffer() {
            if (this.video.buffered.length === 0) {
                ConfigManager.log('info', 'Starting buffer preload');
                this.preloadNextSegment(this.video.currentTime);
            } else {
                const end = this.video.buffered.end(this.video.buffered.length - 1);
                const bufferSize = end - this.video.currentTime;
                ConfigManager.log('debug', `Current buffer: ${bufferSize.toFixed(1)}s`);
            }
        }

        cleanup() {
            this.stopOptimization();

            if (this.networkMonitorInterval) {
                clearInterval(this.networkMonitorInterval);
            }
        }
    }

    // 资源回收管理器
    class ResourceManager {
        static setup() {
            // 页面可见性回收
            document.addEventListener('visibilitychange', () => {
                if (document.hidden) {
                    this.downgradeMedia();
                }
            });

            // 确保DOM准备好
            if (document.readyState === 'loading') {
                document.addEventListener('DOMContentLoaded', () => {
                    this.setupRemovedNodeTracking();
                });
            } else {
                this.setupRemovedNodeTracking();
            }
        }

        static setupRemovedNodeTracking() {
            // 确保document.body存在
            if (!document.body) {
                ConfigManager.log('warn', 'document.body not available for tracking');
                return;
            }

            const observer = new MutationObserver(mutations => {
                mutations.forEach(mutation => {
                    if (!mutation.removedNodes) return;

                    for (let i = 0; i < mutation.removedNodes.length; i++) {
                        const node = mutation.removedNodes[i];
                        if (node.nodeName === 'VIDEO' && node.optimizerInstance) {
                            ConfigManager.log('info', 'Cleaning up removed video element');
                            node.optimizerInstance.cleanup();
                            delete node.optimizerInstance;
                        }
                    }
                });
            });

            try {
                observer.observe(document.body, { childList: true, subtree: true });
                ConfigManager.log('info', 'Node removal tracking enabled');
            } catch (e) {
                ConfigManager.log('error', `Node removal tracking failed: ${e.message}`);
            }
        }

        static downgradeMedia() {
            ConfigManager.log('info', 'Page hidden - downgrading media resources');

            // 查找所有活动优化器
            const optimizers = [];
            const videoElements = document.querySelectorAll('video');

            videoElements.forEach(video => {
                if (video.optimizerInstance) {
                    optimizers.push(video.optimizerInstance);
                }
            });

            // 释放资源
            optimizers.forEach(optimizer => {
                if (optimizer.bufferOptimizer) {
                    optimizer.bufferOptimizer.stopOptimization();
                    ConfigManager.log('info', '优化:页面隐藏,已停止缓冲优化');
                }
                // 减少视频质量(HLS)
                if (optimizer.hls && optimizer.hls.levels?.length > 1) {
                    optimizer.hls.nextLevel = Math.max(0, Math.floor(optimizer.hls.levels.length / 2));
                    ConfigManager.log('info', `优化:页面隐藏,自动降低HLS视频质量到 level ${optimizer.hls.nextLevel}`);
                }
            });
        }
    }

    // 内存保护
    class MemoryGuard {
        static setup() {
            if ('memory' in performance && performance.memory) {
                setInterval(() => this.checkMemoryStatus(), 30000);
                ConfigManager.log('info', 'Memory guard activated');
            } else {
                ConfigManager.log('info', 'Browser does not support memory monitoring');
            }
        }

        static checkMemoryStatus() {
            const mem = performance.memory;
            const usedMB = mem.usedJSHeapSize / (1024 * 1024);
            const threshold = 100; // 100MB 阈值

            if (usedMB > threshold * 1.5) {
                this.freeResources(0.5); // 严重情况释放50%
                ConfigManager.log('warn', `Critical memory usage (${usedMB.toFixed(1)}MB)`);
            } else if (usedMB > threshold) {
                this.freeResources(0.3); // 警告情况释放30%
                ConfigManager.log('info', `High memory usage (${usedMB.toFixed(1)}MB)`);
            }
        }

        static freeResources(percent) {
            ConfigManager.log('info', `Freeing ${percent*100}% of resources`);

            // 查找所有活动优化器
            const optimizers = [];
            const videoElements = document.querySelectorAll('video');

            videoElements.forEach(video => {
                if (video.optimizerInstance && video.optimizerInstance.bufferOptimizer) {
                    optimizers.push(video.optimizerInstance.bufferOptimizer);
                }
            });

            // 释放缓冲资源
            optimizers.forEach(optimizer => {
                optimizer.stopOptimization();
            });
        }
    }

    // 主控制器
    class Main {
        static init() {
            ConfigManager.log('info', 'Script initializing...');

            // 初始化系统
            ResourceManager.setup();
            MemoryGuard.setup();

            // 启动视频检测
            this.videoDetector = new VideoDetector();

            ConfigManager.log('info', 'Script ready');

            // 注册全局清理钩子
            window.addEventListener('beforeunload', Main.cleanupAllOptimizers, { once: true });
            window.addEventListener('unload', Main.cleanupAllOptimizers, { once: true });
        }

        /**
         * 清理所有 video 元素上的优化器实例,防止内存泄漏
         */
        static cleanupAllOptimizers() {
            const videos = document.querySelectorAll('video');
            videos.forEach(video => {
                if (video.optimizerInstance && typeof video.optimizerInstance.cleanup === 'function') {
                    try {
                        video.optimizerInstance.cleanup();
                    } catch (e) {
                        ConfigManager.log('warn', '全局清理优化器时出错: ' + e.message);
                    }
                    delete video.optimizerInstance;
                }
            });
            ConfigManager.log('info', '已执行全局优化器清理');
        }
    }

    // 启动主控制器
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => {
            Main.init();
        });
    } else {
        Main.init();
    }
})();