// ==UserScript== // @name Mediaplay缓存优化 // @namespace http://tampermonkey.net/ // @version 1.5 // @description Optimize media playback by caching video segments to minimize user waiting time and maximize cache efficiency. // @author KiwiFruit // @match *://*/* // @grant none // @license MIT // @downloadURL none // ==/UserScript== (function() { 'use strict'; // 初始化参数 const N = 10; // 假设每个视频有10个片段 const d = Array.from({ length: N }, () => Math.random()); // 下载时延模拟 const videoQuality = 720; // 假设视频分辨率为720p const userPreferences = { quality: true }; // 假设用户偏好高清视频 const D = 5; // 最大允许总时延 const C = 3; // 缓存容量限制 let lambda_val = 0; let mu_val = 0; const alpha = 0.1; const beta = 0.1; const tolerance = 1e-6; const max_iterations = 1000; // 动态加载延迟测量URL async function getLatencyCheckUrl() { return new Promise((resolve) => { setTimeout(() => { resolve('https://example.com/ping'); // 动态返回延迟测量URL }, 100); // 模拟异步加载 }); } async function measureLatency(urlForLatencyCheck, numSamples = 5) { const url = await getLatencyCheckUrl(); // 动态获取延迟测量URL let totalLatency = 0; for (let i = 0; i < numSamples; i++) { const startTime = performance.now(); try { await fetch(url); const endTime = performance.now(); totalLatency += endTime - startTime; // 累加延迟时间(毫秒) } catch (error) { console.error('Error measuring latency:', error); return null; } } return totalLatency / numSamples; // 返回平均延迟时间 } function getNetworkSpeed(latency) { let networkSpeed; if (latency !== null) { if (latency > 200) { networkSpeed = 5; // 高延迟,较低的网络速度 } else if (latency > 100) { networkSpeed = 10; // 中等延迟,中等网络速度 } else { networkSpeed = 15; // 低延迟,高速网络 } } else { // 如果延迟测量失败,则使用默认值 networkSpeed = 15; // 默认为15Mbps } console.log(`Measured latency: ${latency} ms, using network speed: ${networkSpeed} Mbps`); return networkSpeed; } async function getDownloadDelay(segmentSize) { const urlForLatencyCheck = await getLatencyCheckUrl(); // 动态获取延迟测量URL const latency = await measureLatency(urlForLatencyCheck); const networkSpeed = getNetworkSpeed(latency); // 动态获取网络速度 const bandwidth = networkSpeed * 1024 * 1024; // 将Mbps转换为字节每秒 const downloadDelay = segmentSize / bandwidth; // 计算下载延迟 console.log(`Estimated download delay: ${downloadDelay} seconds`); // 更新缓存逻辑 optimizeCache(d, D, C, alpha, beta, max_iterations, tolerance, downloadDelay); } // 效用函数 function u(x, di, videoQuality, userPreferences) { const qualityFactor = userPreferences.quality ? videoQuality : 1; return x === 1 ? (qualityFactor / Math.max(di, 0.06)) : 0; // Assuming 60ms as 0.06 seconds } // 下载时延 function getDownloadDelayForSegment(segmentSize, networkSpeed) { const bandwidth = networkSpeed * 1024 * 1024; // Convert Mbps to bytes per second return segmentSize / bandwidth; // Calculate download delay } // 优化算法 (梯度下降法) function optimizeCache(d, D, C, alpha, beta, max_iterations, tolerance, averageDownloadDelay) { let x = new Array(N).fill(0); let iteration = 0; while (iteration < max_iterations) { // 梯度下降更新 const gradLambda = d.reduce((sum, di, idx) => sum + di * x[idx], 0) - D; const gradMu = x.reduce((sum, xi) => sum + xi, 0) - C; lambda_val -= alpha * gradLambda; mu_val -= beta * gradMu; // 更新决策变量 for (let i = 0; i < N; i++) { const utility = u(x[i], d[i], videoQuality, userPreferences) - lambda_val * d[i] - mu_val; x[i] = utility > 0 ? 1 : 0; } // 检查收敛条件 if (Math.abs(gradLambda) < tolerance && Math.abs(gradMu) < tolerance) { break; } iteration++; } return x; } // 缓存策略 function cacheSegments(mediaElement, optimalSolution, averageDownloadDelay) { const sources = mediaElement.querySelectorAll('source'); sources.forEach((source, index) => { if (optimalSolution[index] === 1) { const segmentUrl = source.src; fetch(segmentUrl) .then(response => response.blob()) .then(blob => { // 将片段存储在内存或本地存储中 console.log(`Cached segment ${index}:`, blob); }) .catch(error => console.error(`Failed to cache segment ${index}:`, error)); } }); } // 缓冲停止计时器 let bufferStopTimer; const BUFFER_STOP_THRESHOLD_MS = 15000; // 缓冲停止阈值,单位为毫秒(例如5秒) function handleBufferStop(mediaElement, segmentSize) { clearTimeout(bufferStopTimer); // 清除之前的定时器 bufferStopTimer = setTimeout(async () => { console.log('Buffer has stopped for a long time, starting latency measurements...'); await getDownloadDelay(segmentSize); }, BUFFER_STOP_THRESHOLD_MS); } // 获取页面上的所有媒体元素(视频和音频) const mediaElements = document.querySelectorAll('video, audio'); mediaElements.forEach(mediaElement => { let lastTimeUpdate = performance.now(); // 上次播放进度更新的时间 mediaElement.addEventListener('play', async function() { console.log('Media element started playing:', mediaElement); // 启动缓存逻辑 const optimalSolution = optimizeCache(d, D, C, alpha, beta, max_iterations, tolerance, 0); await cacheSegments(mediaElement, optimalSolution, 0); }); mediaElement.addEventListener('waiting', function() { console.log('Media element waiting due to buffering:', mediaElement); handleBufferStop(mediaElement, 10 * 1024 * 1024); // 假设片段大小为10MB }); mediaElement.addEventListener('playing', function() { console.log('Media element resumed playing:', mediaElement); clearTimeout(bufferStopTimer); // 清除定时器,因为播放已恢复 }); mediaElement.addEventListener('timeupdate', function() { const currentTime = performance.now(); if (currentTime - lastTimeUpdate > BUFFER_STOP_THRESHOLD_MS) { console.log('Buffer has stopped updating for a long time, starting latency measurements...'); getDownloadDelay(10 * 1024 * 1024); } lastTimeUpdate = currentTime; }); mediaElement.addEventListener('ended', function() { console.log('Media element ended:', mediaElement); // 在结束时也可以进行延迟测量 getDownloadDelay(10 * 1024 * 1024); }); }); })();