1
1
5
mengumpulkan
Laporkan
membagikan
HTML5播放工具脚本
File yang dapat dieksekusi yang disebutkan dalam artikel ini mungkin memerlukan plugin emulator ons untuk berjalan di perangkat seluler (Android, iOS, HarmonyOS, dll.) atau platform lain. Jika diperlukan, silakan unduh plugin atau fitur yang diperlukan dari mini program Plugin Umum di aplikasi VikACG.
// ==UserScript==
// @name 视频网HTML5播放小工具
//@description 需要配合油猴插件使用
// @homepage Tautan 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
PernyataanSemua artikel di situs ini, kecuali dinyatakan lain atau ditandai khusus, adalah publikasi asli situs ini. Individu atau organisasi manapun dilarang menyalin, mencuri, mengumpulkan, atau menerbitkan konten situs ini ke situs web, buku, atau platform media lainnya tanpa persetujuan dari UP master. Jika konten situs ini melanggar hak dan kepentingan yang sah dari penulis asli, silakan hubungi kami untuk pemrosesan: Laporan DMCA













OWO
Orang ini sepertinya sangat pemalu (Bushi
Orang ini sepertinya sangat pemalu (Bushi
Orang ini sepertinya sangat pemalu (Bushi
Orang ini sepertinya sangat pemalu (Bushi