Greasy Fork 支持简体中文。

DASH Video Player Optimizer(视频协议优化DASH篇)

Optimize DASH video playback on web pages with enhanced performance and ABR management

// ==UserScript==
// @name         DASH Video Player Optimizer(视频协议优化DASH篇)
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  Optimize DASH video playback on web pages with enhanced performance and ABR management
// @author       KiwiFruit
// @match        *://*/*
// @grant        none
// @license MIT
// ==/UserScript==
(function() {
    'use strict';

    // Helper function to fetch the first segment of the DASH manifest
    function fetchFirstSegment(mpdUrl) {
        return fetch(mpdUrl)
            .then(response => response.text())
            .then(text => {
                const parser = new DOMParser();
                const xmlDoc = parser.parseFromString(text, "text/xml");
                // Find the first Representation and SegmentTemplate/BaseURL
                const representation = xmlDoc.querySelector('Representation');
                const segmentTemplate = representation.querySelector('SegmentTemplate');
                if (segmentTemplate) {
                    const initialization = segmentTemplate.getAttribute('initialization');
                    const baseUrl = xmlDoc.querySelector('BaseURL').textContent;
                    return `${baseUrl}${initialization}`;
                } else {
                    console.error('Failed to find the first segment URL.');
                    return null;
                }
            })
            .catch(error => console.error('Error fetching first segment:', error));
    }

    // Preload the first segment of the video using dash.js
    function preloadFirstSegment(videoElement, player) {
        const source = videoElement.querySelector('source');
        if (source && source.src.endsWith('.mpd')) {
            fetchFirstSegment(source.src).then(segmentUrl => {
                if (segmentUrl) {
                    player.initialize(videoElement, source.src, true);
                }
            });
        }
    }

    // Buffer strategy optimization
    function optimizeBufferStrategy(player) {
        player.on(dashjs.MediaPlayer.events.BUFFER_EMPTY, () => {
            console.log('Buffer empty, pausing playback.');
            player.pause();
            // Dynamic buffer time based on average throughput
            const bufferTime = player.getAverageThroughput() < 1000000 ? 3000 : 2000; // Adjust buffer time based on average throughput
            setTimeout(() => {
                player.play();
            }, bufferTime);
        });

        player.on(dashjs.MediaPlayer.events.BUFFER_LOADED, () => {
            console.log('Buffer loaded, resuming playback.');
            player.play();
        });
    }

    // Helper function to dynamically load external scripts
    function loadExternalScript(url, callback) {
        var script = document.createElement('script');
        script.src = url;
        script.onload = function() {
            console.log(url + ' loaded successfully.');
            if (callback) callback();
        };
        script.onerror = function() {
            console.error('Failed to load script: ' + url);
        };
        document.head.appendChild(script);
    }

    // Main function to initialize optimizations
    function initializeOptimizations() {
        try {
            const videoElement = document.querySelector('video');
            if (!videoElement || !videoElement.querySelector('source[src$=".mpd"]')) return;

            // Dynamically load dashjs
            loadExternalScript('https://cdn.jsdelivr.net/npm/dashjs@latest/dist/dash.all.min.js', () => {
                const player = dashjs.MediaPlayer().create();
                preloadFirstSegment(videoElement, player);
                optimizeBufferStrategy(player);
            });
        } catch (error) {
            console.error('Error initializing optimizations:', error);
        }
    }

    // Run the initialization when the page loads
    window.addEventListener('load', initializeOptimizations);

    // Compatibility check
    if ('MediaSource' in window && MediaSource.isTypeSupported('video/mp4; codecs="avc1.42E01E, mp4a.40.2"')) {
        initializeOptimizations();
    } else {
        console.warn('Your browser does not support DASH or MSE.');
    }
})();