1
1
5
mengumpul
Lapor
berkongsi
HTML5播放工具脚本
Fail boleh laku yang disebut dalam artikel ini mungkin memerlukan pemalam emulator ons untuk dijalankan pada peranti mudah alih (Android, iOS, HarmonyOS, dll.) atau platform lain. Jika perlu, sila muat turun pemalam atau ciri yang diperlukan dari program mini Plugin Biasa dalam aplikasi VikACG.
// ==UserScript==
// @name 视频网HTML5播放小工具
//@description 需要配合油猴插件使用
// @homepage Pautan Web(bbs.kafan.cn)
// @include https://*.qq.com/*
// @exclude https://user.qzone.qq.com/*
// @include https://www.weiyun.com/video_*
// @include https://www.youku.com/
// @include https://v.youku.com/v_show/id_*
// @include https://vku.youku.com/live/*
// @include https://video.tudou.com/v/*
// @include https://www.bilibili.com/*
// @include https://www.acfun.cn/*
// @include http://v.pptv.com/show/*
// @include https://tv.sohu.com/v/*
// @include https://film.sohu.com/album/*
// @include https://www.mgtv.com/*
// @include *://www.fun.tv/vplay/*
// @include *://m.fun.tv/*
// @include *://*.mtime.com/*
// @include *://www.miaopai.com/*
// @version 1.5.3
// @include *://*.163.com/*
// @include *://*.icourse163.org/*
// @include *://*.sina.com.cn/*
// @include *://video.sina.cn/*
// @include *://weibo.com/*
// @include *://*.weibo.com/*
// @include https://pan.baidu.com/*
// @include https://yun.baidu.com/*
// @include *://v.yinyuetai.com/video/h5/*
// @include *://v.yinyuetai.com/playlist/h5/*
// @include *://www.365yg.com/*
// @include *://v.ifeng.com/*
// @GM_info
// @include https://www.youtube.com/watch?v=*
// @include https://www.ted.com/talks/*
// @noframes
// @include *://www.yy.com/*
// @include *://v.huya.com/play/*
// @include https://www.huya.com/*
// @include https://v.douyu.com/*
// @include https://www.douyu.com/*
// @include *://star.longzhu.com/*
// @include https://www.zhanqi.tv/*
// @include https://www.yunbtv.com/vodplay/*
// @include http://www.dililitv.com/vplay/*
// @include http://www.dililitv.com/gresource/*?Play=*
// @include http://www.vtuapp.com/tv-play-*
// @include https://www.66s.cc/*/play/*
// @grant unsafeWindow
// @grant GM_addStyle
// @grant GM_registerMenuCommand
// @grant GM_setValue
// @grant GM_getValue
// @run-at document-start
// @namespace https://greasyfork.org/users/7036
// ==/UserScript==
'use strict';
const isEdge = navigator.userAgent.includes('Edge');
const w = isEdge ? window : unsafeWindow;
const observeOpt = {childList : true, subtree : true};
const q = (css, p = document) => p.querySelector(css);
const delElem = e => e.remove();
const $$ = (c, cb = delElem, doc = document) => {
if (!c || !c.length) return;
if (typeof c === 'string') c = doc.querySelectorAll(c);
if (!cb) return c;
for (let e of c) {
if (e && cb(e)===false) break;
}
};
const gmFuncOfCheckMenu = (title, saveName, defaultVal = true) => {
const r = GM_getValue(saveName, defaultVal);
if (r) title += ' √';
GM_registerMenuCommand(title, () => {
GM_setValue(saveName, !r);
location.reload();
});
return r;
};
const r1 = (regp, s) => regp.test(s) && RegExp.$1;
const log = console.log.bind(console, '%c脚本[%s] 反馈:%sn%s', 'color:#c3c;font-size:1.5em',
GM_info.script.name, GM_info.script.homepage);
const sleep = ms => new Promise(resolve => {
setTimeout(resolve, ms);
});
const getStyle = (o, s) => {
if (o.style[s]) return o.style[s];
if (getComputedStyle) {//DOM
var x = getComputedStyle(o, '');
//s = s.replace(/([A-Z])/g,'-$1').toLowerCase();
return x && x.getPropertyValue(s);
}
};
const doClick = e => {
if (typeof e === 'string') e = q(e);
if (e) { e.click ? e.click() : e.dispatchEvent(new MouseEvent('click')) };
};
const firefoxVer = r1(/Firefox/(d+)/, navigator.userAgent);
const fakeUA = ua => Object.defineProperty(navigator, 'userAgent', {
value: ua,
writable: false,
configurable: false,
enumerable: true
});
const getMainDomain = host => {
const re = /com|tv|net|org|gov|edu/;
const a = host.split('.');
let i = a.length - 2;
if (re.test(a[i])) i--;
return a[i];
};
const ua_chrome = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3626.121 Safari/537.36';
const ua_ipad2 = 'Mozilla/5.0 (iPad; CPU OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3';
class FullScreen {
constructor(video) {
this._video = video;
const d = document, e = video;
this._exitFn = d.exitFullscreen || d.webkitExitFullscreen || d.mozCancelFullScreen || d.msExitFullscreen;
this._enterFn = e.requestFullscreen || e.webkitRequestFullScreen || e.mozRequestFullScreen || e.msRequestFullScreen;
}
static isFull() {
const d = document;
return !!(d.fullscreen || d.webkitIsFullScreen || d.mozFullScreen ||
d.fullscreenElement || d.webkitFullscreenElement || d.mozFullScreenElement);
}
enter() {
this._enterFn && this._enterFn.call(this._video);
}
exit() {
this._exitFn && this._exitFn.call(document);
}
toggle() {
FullScreen.isFull() ? this.exit() : this.enter();
}
}
//万能网页全屏, CSS代码参考了:https://github.com/gooyie/ykh5p
class FullPage {
constructor(video, isFixView, onSwitch) {
this._video = video;
this._isFixView = isFixView;
this._isFull = !1;
this._onSwitch = onSwitch;
this._rects = new Map();
this._checkContainer();
GM_addStyle(
`.z-top {
position: relative !important;
z-index: 23333333 !important;
}
.webfullscreen {
display: block !important;
position: fixed !important;
width: 100% !important;
height: 100% !important;
top: 0 !important;
left: 0 !important;
background: #000 !important;
z-index: 23333333 !important;
}`
);
}
getPlayerContainer(video) {
let e = video, p = e.parentNode;
const { clientWidth: wid, clientHeight: h } = e;
for (;;) {
this._rects.set(e, {
width: e.clientWidth + 'px',
height: e.clientHeight + 'px'
});
if (e.style.maxWidth) e.style.maxWidth = '100%';
if (e.style.maxHeight) e.style.maxHeight = '100%';
if (p==document.body || p.clientWidth-wid >3 || p.clientHeight-h >3) return e;
e = p;
p = e.parentNode;
}
}
_checkContainer() {
const c = this._container, e = this._video;
if (!c || c === e) this._container = this.getPlayerContainer(e);
}
get container() {
this._checkContainer();
return this._container;
}
fixView() {
if (!this._isFixView && !this._isFull) return;
if (this._video === this._container) return;
for (let [e, v] of this._rects) {
if (this._isFull) {
e.style.width = e.style.height = '100%';
} else {
e.style.width = v.width;
e.style.height = v.height;
}
}
}
static isFull(e) {
return w.innerWidth - e.clientWidth <5 && w.innerHeight - e.clientHeight <5;
}
toggle() {
const cb = this._onSwitch;
if (!this._isFull && cb) cb(true);
const d = document.body;
d.style.overflow = this._isFull ? '' : 'hidden';
this.container.classList.toggle('webfullscreen');
let p = this.container.parentNode;
while (p !== d) {
p.classList.toggle('z-top');
p = p.parentNode;
}
this._isFull = !this._isFull;
setTimeout(this.fixView.bind(this), 9);
if (!this._isFull && cb) setTimeout(cb, 199, !1);
}
}
let v, _fp, _fs;
const { host, pathname: path } = location;
const u = getMainDomain(host);
const events = {
on(name, fn) {
this[name] = fn;
}
};
const app = {
isLive: !1,
disableSpace: !1,
multipleV: !1, //单页面多视频
isFixFPView: !1, //退出网页全屏时是否修正DOM视图
checkMVVisible() {
if (this.vList.length < 2 || v.offsetWidth>1) return v;
let e = this._findList(k => k.offsetWidth>1);
if (e) {
e.playbackRate = v.playbackRate;
e.volume = v.volume;
}
v = e;
return v;
},
checkDPlayer() {
if (v && !this.DPlayer_el && v.closest('.dplayer-video-wrap')) {
this.DPlayer_el = v.closest('.dplayer');
_fp = new FullPage(v, this.isFixFPView, this.switchFP);
_fs = null;
this.btnFS = q('.dplayer-full-icon', this.DPlayer_el);
this.fullScreen = () => this._convertButton(this.btnFS);
this.btnWFS = null;
this.btnPlay = null;
this.btnNext = null;
}
return this.DPlayer_el;
},
_convertButton(btn) {
(!btn.nextSibling || btn.clientWidth >1 || getStyle(btn, 'display') !== 'none') ?
doClick(btn) : doClick(btn.nextSibling);
},
hotKey(e) {
if (e.ctrlKey || e.altKey || e.target.contentEditable=='true' ||
/INPUT|TEXTAREA|SELECT/.test(e.target.nodeName)) return;
if (e.shiftKey && ![13,37,39].includes(e.keyCode)) return;
if (this.isLive && [37,39,78,88,67,90].includes(e.keyCode)) return;
if (this.extPlayer && this.extPlayer.contains(e.target) &&
[32,37,39].includes(e.keyCode)) return;
if (!this.checkMVVisible()) return;
!this.checkDPlayer() && this.checkUI();
if (events.keydown && events.keydown(e)) return;
let n;
switch (e.keyCode) {
case 32: //space
if (this.disableSpace) return;
if (e.shiftKey) {
v.scrollIntoView();
v.focus();
} else {
if (this.btnPlay) this.play();
else v.paused ? v.play() : v.pause();
}
e.preventDefault();
break;
case 37: n = e.shiftKey ? -20 : -5; //left 快退5秒,shift加速
case 39: //right
n = n || (e.shiftKey ? 20 : 5); //快进5秒,shift加速
v.currentTime += n;
break;
//case 80: // P 上一首
case 78: // N 下一首
this.btnNext && getStyle(this.btnNext, 'display') !== 'none' && doClick(this.btnNext);
break;
case 38: n = 0.1; //加音量
case 40: //降音量
n = n || -0.1;
n += v.volume;
if (0 <= n && n <= 1) v.volume = n;
e.preventDefault();
break;
case 13: //回车键。 全屏
if (e.shiftKey) {
_fp ? _fp.toggle() : this.fullPage();
} else {
_fs ? _fs.toggle() : this.fullScreen();
}
break;
case 27: //esc
if (FullScreen.isFull()) {
_fs ? _fs.exit() : this.fullScreen();
} else if (FullPage.isFull(v)) {
_fp ? _fp.toggle() : this.fullPage();
}
break;
case 67: n = 0.1; //按键C:加速播放 +0.1
case 88: //按键X:减速播放 -0.1
n = n || -0.1;
n += v.playbackRate;
if (0 < n && n <= 16) v.playbackRate = n;
break;
case 90: //按键Z:正常速度播放
v.playbackRate = 1;
break;
case 70: n = 0.03; //按键F:下一帧
case 68: //按键D:上一帧
n = n || -0.03;
if (!v.paused) v.pause();
v.currentTime += n;
break;
default: return;
}
e.stopPropagation();
},
checkUI() {
if (this.webfullCSS && !this.btnWFS) this.btnWFS = q(this.webfullCSS);
if (this.btnWFS) {
this.fullPage = () => this._convertButton(this.btnWFS);
if (_fp) _fp = null;
} else {
_fp = _fp || new FullPage(v, this.isFixFPView, this.switchFP);
}
if (this.fullCSS && !this.btnFS) this.btnFS = q(this.fullCSS);
if (!this.btnFS) {
_fs = _fs || new FullScreen(v);
} else {
this.fullScreen = () => this._convertButton(this.btnFS);
if (_fs) _fs = null;
}
if (this.nextCSS && !this.btnNext) this.btnNext = q(this.nextCSS);
if (this.playCSS && !this.btnPlay) this.btnPlay = q(this.playCSS);
if (this.btnPlay) this.play = () => this._convertButton(this.btnPlay);
},
switchFP(toFull) {
if (toFull) {
for (let e of this.vSet) this.viewObserver.unobserve(e);
} else {
for (let e of this.vList) this.viewObserver.observe(e);
}
},
onGrowVList() {
if (this.vList.length > this.vCount) {
if (this.viewObserver) {
for (let e of this.vList) {
if (!this.vSet.has(e)) this.viewObserver.observe(e);
}
} else {
const config = {
rootMargin: '0px',
threshold: 0.9
};
this.viewObserver = new IntersectionObserver(this.onIntersection.bind(this), config);
for (let e of this.vList) this.viewObserver.observe(e);
}
this.vSet = new Set(this.vList);
this.vCount = this.vList.length;
}
},
onIntersection(entries) {
for (let entry of entries) {
if (entry.isIntersecting && v != entry.target) {//intersectionRatio
v = entry.target;
_fs = new FullScreen(v);
_fp = new FullPage(v, this.isFixFPView, this.switchFP);
events.switchMV && events.switchMV();
break;
}
}
},
bindEvent() {
log('bind eventn', v);
events.foundMV && events.foundMV();
const fn = ev => {
events.canplay && events.canplay();
v.removeEventListener('canplaythrough', fn);
};
if (v.readyState > 3) fn();
else v.addEventListener('canplaythrough', fn);
document.body.addEventListener('keydown', this.hotKey.bind(this));
if (this.extPlayerCSS) {
this.extPlayer = v.closest(this.extPlayerCSS);
this.extPlayer && this.extPlayer.addEventListener('keydown', this.hotKey.bind(this));
}
if (this.multipleV) {
new MutationObserver(this.onGrowVList.bind(this))
.observe(document.body, observeOpt);
this.vCount = 0;
this.onGrowVList();
}
},
findMV() {
return !this.cssMV ? this.vList[0] : this._findList(e => e.matches(this.cssMV));
},
init() {
this.switchFP = this.multipleV ? this.switchFP.bind(this) : null;//多视频页面
this.vList = document.getElementsByTagName('video');
this._findList = [].find.bind(this.vList);
const t = setInterval(() => {
if (v = this.findMV()) {
clearInterval(t);
$$(this.adsCSS);
this.bindEvent();
}
}, 300);
}
};
let router = {
youtube() {
app.fullCSS = '.ytp-fullscreen-button';
app.webfullCSS = '.ytp-size-button';
app.nextCSS = '.ytp-next-button';
app.extPlayerCSS = '#ytp-player';
},
ted() {
app.fullCSS = 'button[title="Enter Fullscreen"]';
app.playCSS = 'button[title="play video"]';
const forceHD = gmFuncOfCheckMenu('TED强制高清', 'ted_forceHD');
const getHDSource = async () => {
const pn = r1(/^(/talks/w+)/, path);
const resp = await fetch(`https://www.ted.com${pn}/metadata.json`);
const data = await resp.json();
return data.talks[0].downloads.nativeDownloads.high;
};
const check = async (rs) => {
if (!v.src || v.src.startsWith('http')) return;
$$(app.vList, e => { e.removeAttribute('src') }); // 取消多余的媒体资源请求
try {
v.src = await getHDSource();
} catch(ex) {
console.error(ex);
}
};
forceHD && events.on('foundMV', () => {
new MutationObserver(check).observe(v, {
attributes: true,
attributeFilter: ['src']
});
check();
});
},
qq() {
Object.assign(app, {
nextCSS: '.txp_btn_next',
webfullCSS: '.txp_btn_fake',
fullCSS: '.txp_btn_fullscreen',
extPlayerCSS: '#mod_player'
});
},
youku() {
if (host.startsWith('vku.')) {
events.on('canplay', () => {
app.isLive = !q('.spv_progress');
});
app.fullCSS = '.live_icon_full';
} else {
events.on('foundMV', () => {
app.btnFS = q(app.fullCSS);
if (!app.btnFS) {//使用了优酷播放器YAPfY扩展
app.webfullCSS = '.ABP-Web-FullScreen';
app.fullCSS = '.ABP-FullScreen';
app.nextCSS = '.ABP-Next';
} else {
w.$('.settings-item.disable').replaceWith('<div data-val=1080p class=settings-item data-eventlog=xsl>1080p</div>');
}
});
app.fullCSS = '.control-fullscreen-icon';
app.nextCSS = '.control-next-video';
app.extPlayerCSS = '#player';
}
},
bilibili() {
app.nextCSS = '.bilibili-player-video-btn-next';
app.webfullCSS = '.bilibili-player-video-web-fullscreen';
app.fullCSS = '.bilibili-player-video-btn-fullscreen';
app.extPlayerCSS = '#playerWrap';
const danmu = gmFuncOfCheckMenu('弹幕', 'bili_danmu');
const autoPlay = gmFuncOfCheckMenu('自动播放', 'bili_autoPlay');
const _setPlayer = () => {
const x = q('.bilibili-player-video-danmaku-switch input');
if (!x) return setTimeout(_setPlayer, 300);
if (x.checked != danmu) x.click();
if (v.paused == autoPlay) autoPlay ? v.play() : v.pause();
v.focus();
doClick('i.bilibili-player-iconfont-repeat.icon-24repeaton'); //关循环播放
};
const setPlayer = () => {
const x = app.findMV();
if (!x || x == v || x.readyState < 4) return; //等待视频加载完成
v = x;
app.btnNext = app.btnWFS = app.btnFS = null;
_setPlayer();
};
events.on('canplay', () => {
_setPlayer();
setInterval(setPlayer, 500);
});
},
pptv() {
if (!w.chrome) fakeUA(ua_chrome);
app.fullCSS = '.w-zoomIn';
app.nextCSS = '.w-next';
app.playCSS = '.w-play';
//app.extPlayerCSS = '#playerWrap';
},
sina() {
fakeUA(ua_ipad2);
},
weibo() {
app.isFixFPView = true;
app.multipleV = path.startsWith('/u/');
},
miaopai() {
app.multipleV = path.startsWith('/u/');
},
baidu() {
events.on('keydown', e => {
if (!videojs) return;
let n, p = videojs.getPlayers("video-player").html5player;
switch (e.keyCode) {
case 67: n = 0.1;
case 88:
n = n || -0.1;
n += + p.tech_.playbackRate().toFixed(1);
if (0 < n && n <= 16) p.tech_.setPlaybackRate(n);
return true;
case 90:
p.tech_.setPlaybackRate(1);
return true;
}
});
app.extPlayerCSS = '.video-content';
},
mgtv() {
app.nextCSS = 'mango-control-playnext';
app.webfullCSS = 'mango-webscreen';
app.fullCSS = 'mango-screen.control-item';
app.extPlayerCSS = '#mgtv-player-wrap';
},
acfun() {
app.webfullCSS = '.fullscreen-web';
app.fullCSS = '.fullscreen-screen';
},
['163']() {
app.multipleV = host.startsWith('news.');
if ('open.163.com' == host) {
app.extPlayerCSS = '#playerWrap';
}
return host.split('.').length > 3;
},
sohu() {
app.nextCSS = 'li.on[data-vid]+li a';
app.fullCSS = '.x-fullscreen-btn';
},
mtime() {
fakeUA(ua_ipad2);
events.on('foundMV', () => {
v.preload = 'auto';
v.autoplay = true;
});
},
fun() {
if (host.startsWith('m.')) {
if (!path.includes('play')) return true;//非播放页,不执行init()
/^/[mv]/.test(path) && location.assign(path.replace('/', '/i') + location.search);
app.nextCSS = 'a.btn.next-btn';
app.fullCSS = 'a.btn.full-btn';
GM_addStyle('div.p-ip-wrap{overflow-y: auto !important;}');
return;
}
let vid = r1(/bv-(d+)/, path);
let mid = r1(/bg-(d+)/, path);
//剧集path: /implay/,单视频path: /ivplay/
if (vid) {
mid && location.assign(`//m.fun.tv/implay/?mid=${mid}&vid=${vid}`);
location.assign('//m.fun.tv/ivplay/?vid='+vid);
}
mid && setTimeout(() => {
vid = w.vplay.videoid;
vid && location.assign(`//m.fun.tv/implay/?mid=${mid}&vid=${vid}`);
}, 99);
r1(/bt-(d+)/, path) && setTimeout(() => {
vid = w.vplay.videoid;
location.assign('//m.fun.tv/ivplay/?vid='+vid);
}, 99);
return true;
}
};
app.disableSpace = /youtube|qq|pptv|365yg/.test(u);
if (!router[u]) { //直播站点
router = {
douyu() {
const inRoom = host.startsWith('www.');
events.on('canplay', () => {
setTimeout(doClick, 2e3, '.roomSmallPlayerFloatLayout-closeBtn');
$$(app.adsCSS);
if (inRoom) q('#js-player-aside-state').checked = true;
else w.$(document).unbind('keydown');
});
app.cssMV = '[src^=blob]';
app.playCSS = inRoom ? 'div[title="播放"]' : 'input[title="播放"]';
app.webfullCSS = inRoom ? 'div[title="网页全屏"]' : 'input[title="进入网页全屏"]';
app.fullCSS = inRoom ? 'div[title="窗口全屏"]' : 'input[title="进入全屏"]';
app.adsCSS = '[data-dysign],a[href*="wan.douyu.com"]';
},
yy() {
app.isLive = !path.startsWith('/x/');
if (app.isLive) {
app.fullCSS = '.yc__fullscreen-btn';
app.webfullCSS = '.yc__cinema-mode-btn';
app.playCSS = '.yc__play-btn';
}
},
huya() {
if (firefoxVer && firefoxVer < 57) return true;
app.webfullCSS = '.player-fullpage-btn';
app.fullCSS = '.player-fullscreen-btn';
app.playCSS = '#player-btn';
app.adsCSS = '#player-subscribe-wap,#wrap-income,#hy-ad';
},
longzhu() {
app.fullCSS = 'a.ya-screen-btn';
},
zhanqi() {
localStorage.lastPlayer = 'h5';
app.fullCSS = '.video-fullscreen';
}
};
if (router[u]) {
app.isLive = app.isLive || !host.startsWith('v.');
!w.chrome && fakeUA(ua_chrome);
}
}
!/pptv|douyu/.test(u) && Object.defineProperty(navigator, 'plugins', {
get() { return { length: 0 } }
});
if (!router[u] || !router[u]()) app.init();
作者:衔玉教教主 https://www.bilibili.com/read/cv3961572 出处:bilibili
PengisytiharanSemua artikel di laman web ini, melainkan dinyatakan atau ditandakan sebaliknya, adalah penerbitan asal laman web ini. Mana-mana individu atau organisasi dilarang menyalin, mencuri, mengumpul, atau menerbitkan kandungan laman web ini ke mana-mana laman web, buku, atau platform media lain tanpa kebenaran daripada UP master. Jika kandungan laman web ini melanggar hak dan kepentingan sah pengarang asal, sila hubungi kami untuk pemprosesan: Laporan DMCA













OWO
Lelaki ini nampaknya sangat pemalu (Bushi
Lelaki ini nampaknya sangat pemalu (Bushi
Lelaki ini nampaknya sangat pemalu (Bushi
Lelaki ini nampaknya sangat pemalu (Bushi