Greasy Fork is available in English.
使视频元素支持长按倍速、上/下滑调节音量、左/右滑调节进度
// ==UserScript== // @name H5移动视频播放器增强 // @namespace http://tampermonkey.net/ // @version 1.1 // @description 使视频元素支持长按倍速、上/下滑调节音量、左/右滑调节进度 // @author tutu辣么可#(greasyfork)/IcedWatermelonJuice(github) // @run-at document-start // @match *://*/* // @require https://greasyfork.org/scripts/455704-js-extensions-touchjs/code/js-Extensions-touchJS.js?version=1123827 // @grant GM_getValue // @grant GM_setValue // @grant GM_setClipboard // @grant GM_notification // @grant GM_registerMenuCommand // @grant GM_info // @icon https://icedwatermelonjuice.github.io/Tools-Hub/favicon.ico // @license MIT // ==/UserScript== (function() { 'use strict'; const dataKey = "h5VideoMPlayerExtend"; const scriptName = GM_info.script.name; var config = Object.assign({ darkList: [], }, GM_getValue(dataKey) ? JSON.parse(GM_getValue(dataKey)) : {}) var enable = true; var tempClose=false; var timer = -1; function vControl(target, v0, v1, cb) { var t = target, r = undefined; if (!target || typeof target !== "object" || !/video/i.test(t.tagName)) { return false } switch (v0) { case "p+": t.play(); setTimeout(() => { t.play(); }, 100); r = true; break; case "p-": t.pause(); setTimeout(() => { t.pause(); }, 100) r = false; break; case "p": r = !t.paused; break; case "v+": v1 = v1 ? parseFloat(v1) : 0.1; t.volume = (t.volume + v1).toFixed(2) <= 1 ? (t.volume + v1).toFixed(2) : 1; r = t.volume; break; case "v-": v1 = v1 ? parseFloat(v1) : 0.1; t.volume = (t.volume - v1).toFixed(2) >= 0 ? (t.volume - v1).toFixed(2) : 0; r = t.volume; break; case "v": if (parseFloat(v1)) { t.volume = v1; } r = t.volume; break; case "t+": v1 = parseFloat(v1) ? parseFloat(v1) : 0.1; t.currentTime = (t.currentTime + v1) <= t.duration ? (t.currentTime + v1) : t.duration; r = t.currentTime; break; case "t-": v1 = parseFloat(v1) ? parseFloat(v1) : 0.1; t.currentTime = (t.currentTime - v1) >= 0 ? (t.currentTime - v1) : 0; r = t.currentTime; break; case "t": if (parseFloat(v1)) { t.currentTime = v1; } r = t.currentTime; break; case "f+": t.webkitEnterFullScreen(); r = true; break; case "f-": t.webkitExitFullScreen(); r = false; break; case "f": r = (document.fullscreenElement === t); break; case "r": t.playbackRate = parseFloat(v1) ? parseFloat(v1) : 1; r = t.playbackRate; break; default: console.log(t); r = t; break; } typeof cb === "function" && cb(r) return r; } function videoExtend(target) { var longPressTimer = -1; target.setAttribute("mplayer-extended", ""); touchJS.bind(target, "left", () => { enable && vControl(target, "t-"); }) touchJS.bind(target, "right", () => { enable && vControl(target, "t+"); }) touchJS.bind(target, "up", () => { enable && vControl(target, "v+"); }) touchJS.bind(target, "down", () => { enable && vControl(target, "v-"); }) touchJS.bind(target, "longPress", () => { longPressTimer = setInterval(() => { enable && vControl(target, "r", 3); }, 200) }) touchJS.bind(target, "longPressCancel", () => { longPressTimer !== -1 && clearInterval(longPressTimer) longPressTimer = -1; enable && vControl(target, "r"); }) } try { if(config.darkList){ config.darkList.forEach((url) => { if (location.href.search(url) !== -1) { throw Error() } }) } } catch (e) { enable = false; } GM_registerMenuCommand('临时关闭功能', function() { if(enable){ enable=false; tempClose=true; GM_notification(`临时关闭脚本功能,刷新网页恢复`, scriptName); }else{ alert("此域名已经在黑名单内"); } }); GM_registerMenuCommand('添加到黑名单', function() { enable = false; tempClose=false; config.darkList.push(location.hostname); GM_setValue(dataKey, JSON.stringify(config)); GM_notification(`已添加 ${location.hostname} 到黑名单,脚本功能关闭`, scriptName); }); GM_registerMenuCommand('清空已有黑名单', function() { config.darkList = []; GM_setValue(dataKey, JSON.stringify(config)); GM_notification(`清空域名黑名单成功,请刷新网页以应用新配置`, scriptName); }); GM_registerMenuCommand('导出配置信息', function() { GM_setClipboard(JSON.stringify(config), "text"); GM_notification(`导出配置信息成功`, scriptName); }); GM_registerMenuCommand('导入配置信息', function() { let data = prompt("请粘贴配置信息"); if (data && data.trim()) { try { data = JSON.parse(data); config = Object.assign(config, data); GM_setValue(dataKey, JSON.stringify(config)); } catch (e) { GM_notification(`导入配置信息失败`, scriptName); return false } GM_notification(`导入配置信息成功`, scriptName); } }); GM_registerMenuCommand('重置脚本配置', function() { config={} GM_setClipboard(JSON.stringify(config), "text"); GM_notification(`重置脚本配置成功`, scriptName); }); GM_registerMenuCommand('脚本相关信息', function() { let data=`脚本相关信息:\n名称:${scriptName}\n作者:${GM_info.script.author}\n版本:${GM_info.script.version}\n状态:${enable?"正常启用":(tempClose?"临时关闭":"黑名单")}` alert(data) }); timer = setInterval(() => { let v = document.querySelectorAll("video:not([mplayer-extended])"); v.forEach((e) => { videoExtend(e); }) }, 500) console.log(`${scriptName} 主程序500ms定时器ID:${timer}`) })();