您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
自动升级到720P+预取Key减少缓冲
// ==UserScript== // @name 人卫慕课播放助手 // @namespace https://qinlili.bid // @version 0.1.2 // @description 自动升级到720P+预取Key减少缓冲 // @author 琴梨梨 // @match *://www.pmphmooc.com/* // @icon https://www.pmphmooc.com/static/favicon.ico // @require https://lib.baomitu.com/m3u8-parser/4.7.0/m3u8-parser.min.js#sha512-k+LQLfQIGmuQTgjCfnE/iU3jdv+J9sdykVF5SgKtc+aMiKWPZqGjs60Bp3lug6rh9DVhcSZefpetyVXwUny48w== // @grant none // @license WTFPL // ==/UserScript== (function() { 'use strict'; (function(appendChild) { Node.prototype.appendChild = function(ele,loc) { if(ele.src&&ele.src.startsWith("http://")>0){ console.log(ele) ele.src=ele.src.replace("http://","https://") } return appendChild.call(this, ele,loc); }; })(Node.prototype.appendChild); //https://stackoverflow.com/a/52171480 const cyrb53 = function(str, seed = 0) { let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed; for (let i = 0, ch; i < str.length; i++) { ch = str.charCodeAt(i); h1 = Math.imul(h1 ^ ch, 2654435761); h2 = Math.imul(h2 ^ ch, 1597334677); } h1 = Math.imul(h1 ^ (h1>>>16), 2246822507) ^ Math.imul(h2 ^ (h2>>>13), 3266489909); h2 = Math.imul(h2 ^ (h2>>>16), 2246822507) ^ Math.imul(h1 ^ (h1>>>13), 3266489909); return 4294967296 * (2097151 & h2) + (h1>>>0); }; //https://stackoverflow.com/a/61226119 const blobToBase64 = blob => { const reader = new FileReader(); reader.readAsDataURL(blob); return new Promise(resolve => { reader.onloadend = () => { resolve(reader.result); }; }); }; let cacheKey={} const makeCache=async(url,hashKey)=>{ let cache=await blobToBase64(await (await fetch(url)).blob()) cacheKey[hashKey]=cache document.getElementsByClassName("videoTitle")[0].innerText+="[缓冲加速已开启]" } const m3u8Prefetch=async(m3u8)=>{ console.log("Begin prefetch, getting m3u8 info...-Qinlili") const m3u8Text=await (await fetch(m3u8)).text(); const parser = new m3u8Parser.Parser(); parser.push(m3u8Text); const segments=parser.manifest.segments; console.log("Success fetch m3u8 info. -Qinlili") console.log(segments); segments.forEach(async part=>{ const controller = new AbortController(); const signal = controller.signal; await fetch(part.uri.replace("http://","https://"),{ method:"GET", signal:signal }) controller.abort(); }) console.log("Prefetch done. -Qinlili") } (open=> { XMLHttpRequest.prototype.open = function (method, url, async, user, pass) { if(url.startsWith("http://")){ url=url.replace("http://","https://") } if (url.indexOf("index.m3u8")>0) { console.log("Get m3u8 link: " + url + " -Qinlili"); url = url.replace("480P","720P"); m3u8Prefetch(url); } if (url.indexOf("/api/m3u8/getUri")>0) { let hashKey=cyrb53(url) if(cacheKey[hashKey]){ console.log("Use local cache key-Qinlili") url=cacheKey[hashKey] }else{ console.log("No key cache, use async fetch: " + url + " -Qinlili") makeCache(url,hashKey) } } return open.call(this, method, url, async, user, pass); }; })(XMLHttpRequest.prototype.open); })();