Greasy Fork

媒体播放缓存优化(Media Playback Cache Optimizer)

Optimize media playback cache based on network conditions.

目前为 2025-03-11 提交的版本。查看 最新版本

// ==UserScript==
// @name         媒体播放缓存优化(Media Playback Cache Optimizer)
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  Optimize media playback cache based on network conditions.
// @author       KiwiFruit
// @match        *://*/*
// @grant        none
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    const N = 10; // Number of video segments
    let D = 5; // Maximum allowed total delay, adjustable based on network speed
    let C = 3; // Cache capacity limit

    function getNetworkStatus() {
        return navigator.connection ? navigator.connection.downlink : 15; // Default to 15Mbps if not available
    }

    function u(x, di, videoQuality) {
        // Assume higher video quality brings more utility but needs to consider download delay
        return x === 1 ? (videoQuality / Math.max(di, 0.02)) : 0; // Assuming 20ms as 0.02 seconds
    }

    function clearCache() {
        console.log("Cache cleared.");
        // Implement actual cache clearing logic here if needed
    }

    function fetchWithRetry(url, retries) {
        fetch(url)
            .then(response => response.blob())
            .then(blob => {
                console.log(`Cached segment ${url}:`, blob);
            })
            .catch(error => {
                if (retries > 0) {
                    console.warn(`Failed to cache segment ${url}, retrying...`);
                    setTimeout(() => fetchWithRetry(url, retries - 1), 1000); // Wait 1 second before retrying
                } else {
                    console.error(`Failed to cache segment ${url} after retries:`, error);
                }
            });
    }

    function optimizeCache(mediaElement) {
        const currentNetworkSpeed = getNetworkStatus();
        D = currentNetworkSpeed > 15 ? 3 : 7; // Lower delay for high-speed networks
        C = currentNetworkSpeed > 15 ? 4 : 2; // More cache capacity for high-speed networks

        let optimalSolution = new Array(N).fill(0);
        let maxUtility = 0;

        // Simplified optimization process
        for (let i = 0; i < (1 << N); i++) {
            let utility = 0;
            let totalDelay = 0;
            let cacheUsed = 0;

            for (let j = 0; j < N; j++) {
                if ((i & (1 << j)) !== 0) {
                    utility += u(1, 0.02, 720); // Assuming a fixed video quality for simplicity
                    totalDelay += 0.02;
                    cacheUsed++;
                }
            }

            if (totalDelay <= D && cacheUsed <= C && utility > maxUtility) {
                maxUtility = utility;
                optimalSolution = new Array(N).fill(0);
                for (let j = 0; j < N; j++) {
                    if ((i & (1 << j)) !== 0) {
                        optimalSolution[j] = 1;
                    }
                }
            }
        }

        cacheSegments(mediaElement, optimalSolution);
    }

    function cacheSegments(mediaElement, optimalSolution) {
        for (let i = 0; i < N; i++) {
            if (optimalSolution[i] === 1) {
                const segmentUrl = `https://example.com/video-segments/segment-${i}.mp4`;
                fetchWithRetry(segmentUrl, 3); // Retry up to 3 times
            }
        }
    }

    document.addEventListener('play', function(e) {
        const mediaElement = e.target;
        if (mediaElement.tagName === 'VIDEO' || mediaElement.tagName === 'AUDIO') {
            optimizeCache(mediaElement);
        }
    }, true);

    document.addEventListener('pause', function(e) {
        const mediaElement = e.target;
        if (mediaElement.tagName === 'VIDEO' || mediaElement.tagName === 'AUDIO') {
            clearCache();
        }
    });

    document.addEventListener('ended', function(e) {
        const mediaElement = e.target;
        if (mediaElement.tagName === 'VIDEO' || mediaElement.tagName === 'AUDIO') {
            clearCache();
        }
    });
})();