// ==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
// ==/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);
});
});
})();