// ==UserScript==
// @name Pornhub 增强
// @icon data:image/x-icon;base64,AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAAABorAAACAwAAwP8AAG+5AAA0VgAAUYkAAInkAAA/aQAAMFEAAJf/AABZlAAAmv8AAGSnAAAaLAAAERwAAKP/AABHZAAABAcAAC0xAACp/wAArP8AALL/AABDcAAAbowAAI/uAAAKEAAAht4AALv/AAAtSwAAiOEAAI3sAACV/wAAmP8AAJv/AAABAQAAnv8AAHrHAABlpwAA//8AAND/AACh/wAAiOIAAC9PAABqsgAApP8AAEVkAABJegAAp/8AADFSAACq/wAAGSoAAAECAACt/wAAM1UAAIjjAAA+aAAAfcgAALb/AAAdMAAAT4MAADpjAABAawAAuf8AAAsQAAC//wAAAAYAAML/AAADBgAACQ4AAMX/AACW/wAAmf8AADdcAACc/wAAn/8AABAcAABRhwAAov8AAIXdAADX/wAAqP8AAKv/AACQ8AAAWI0AAC5NAACx/wAAIEMAALT/AACF3gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISAxISEhISCIiSEgMIkhICkpWLSBIIUg1MEcgEDUiCk4ZCAQUSCQiMTwUNQ0xHxBSTwAvQ0sQSgAzWBw4AFkyUSoABjpOPykANihQCwA3UVEHAjRCRVQyD0wuETs0B1FRNyNVGAkAJh0CGkASAgdRUR4ALCdOAD0BVUFGTQA3UVIbAEQTAAA5AA4/Az4AWTJOUxcFV0klNSs8FDUNMR8QCkoWFhZYNSEVMEcgEDUiCkhIDAwMSEhIIiJISAwiSEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
// @namespace github.com/hmjz100
// @version 0.1.7
// @description 《也许同类型中最好用?》系列 - Pornhub 视频替换 Artplayer,不显示视频广告,支持进度条热力图,显示视频多分辨率 m3u8/mp4 下载链接,可直接下载 免费/付费/禁下 的视频
// @author hmjz100,liuwanlin
// @license MIT
// @match *://*.pornhub.org/*
// @match *://*.pornhub.com/*
// @match *://*.pornhubpremium.com/*
// @match *://*/*/hvtrs8%2F-cl.ropnju%60.aoo%2Ftigw%5Dvkdgo%2Cpjp%3Dvkeukgy%3F*
// @grant unsafeWindow
// @grant GM_addStyle
// @grant GM_setClipboard
// @grant GM_openInTab
// @grant GM_xmlHttpRequest
// @grant GM.xmlHttpRequest
// @connect pornhub.org
// @connect pornhub.com
// @connect pornhubpremium.com
// @connect phncdn.com
// @require https://unpkg.com/jquery@3.6.3/dist/jquery.min.js
// @require https://unpkg.com/hls.js@1.5.10/dist/hls.min.js
// @require https://unpkg.com/artplayer@5.1.6/dist/artplayer.legacy.js
// ==/UserScript==
(function () {
Artplayer.LOG_VERSION = false;
'use strict';
let url = new URL(unsafeWindow.location.href)
// 空白间距
waitForKeyElements("li.emptyBlockSpace", function (element) {
if (element.attr('removed')) return;
element.attr('removed', true);
element.fadeOut()
})
// 顶栏广告
waitForKeyElements("#headerUpgradePremiumBtn", function (element) {
if (element.parent().attr('removed')) return;
element.parent().attr('removed', true);
element.parent().fadeOut()
})
// 年龄认证
waitForKeyElements('[id^="age-verification"]', function (element) {
if (element.attr('removed')) return;
element.attr('removed', true);
element.fadeOut()
})
// 删除页面 iframe 广告
waitForKeyElements('iframe[allowtransparency][data-embeddedads][data-spot-id], ins[class*="adsby"]', function (element) {
function findParentWithClass(el) {
if (el.length > 0) {
if (el.parent().attr("class")) {
if (el.parent().attr('removed') || el.parent().parent().parent().attr('removed')) return;
if (el.parent().parent().parent().prop('tagName') === "LI") {
el.parent().parent().parent().attr('removed', true);
console.log(`【Pornhub增强】AD\n`, el.parent().parent().parent().attr("class"), "有class且有li,隐藏!")
el.parent().parent().parent().fadeOut();
} else {
el.parent().attr('removed', true);
console.log(`【Pornhub增强】AD\n`, el.parent().attr("class"), "有class,隐藏!")
el.parent().fadeOut();
}
} else {
console.log(`【Pornhub增强】AD\n`, "没有class,继续查找...")
findParentWithClass(el.parent());
}
}
}
findParentWithClass(element);
})
waitForKeyElements('.bg-spice-badge', function (element) {
function findParentWithClass(el) {
if (el.length > 0) {
if (el.parent().prop('tagName') === "LI") {
if (el.parent().attr('removed')) return;
el.parent().attr('removed', true);
console.log(`【Pornhub增强】AD\n`, el.parent().attr("class"), "有li,隐藏!")
el.parent().fadeOut();
} else {
console.log(`【Pornhub增强】AD\n`, "没有class,继续查找...")
findParentWithClass(el.parent());
}
}
}
findParentWithClass(element);
})
waitForKeyElements("body div.bottomNav, div#js-abContainterMain", function (element) {
element.fadeOut()
})
if (!url.pathname.includes("view_video.php") && !url.searchParams.get("viewkey") && !url.pathname.includes("vkeukgy")) return;
// 暂停原始播放器的播放,避免替换后没法暂停
waitForKeyElements("div.mgp_videoWrapper video", function (element) {
setInterval(() => {
element[0].pause()
}, 1)
})
// 等待页面信息出现
let flashvarsRequireTimer = setInterval(async () => {
let flashvars = {};
for (let prop in unsafeWindow) {
if (prop.startsWith('flashvars_')) {
clearInterval(flashvarsRequireTimer)
flashvars = unsafeWindow[prop];
} else continue
}
if (!flashvars.length && !flashvars.mediaDefinitions) return;
GM_addStyle(`
a, button, ul li, ui, label, input, select {
transition: all 0.25s !important;
-webkit-transition: all 0.25s !important;
}
.no-scroll {
overflow: hidden !important;
}
.download-urls {
margin-top: 10px !important;
}
.download-urls ul {
padding: 0 10px 15px;
font-weight: bold;
line-height: 1.5;
}
.download-urls ul li {
display: flex;
align-items: center;
height: auto;
}
.download-url.label {
width: 10%;
text-align: center;
}
.download-url {
width: 5%;
text-align: center;
}
.download-url.download {
border: none;
border-radius: 5px;
font-size: 12px;
background: #ff9000;
color: #fff;
}
.download-url.download:hover, .download-url.download:disabled {
background: #ff9000D0;
}
.download-url.input {
width: 80%;
font-size: 12px;
padding: 0 5px;
border: 1px solid #fff;
margin: 0 5px;
}
.art-contextmenu svg, .art-contextmenu img {
vertical-align: top;
margin-right: 5px
}
header {
z-index: 999999999999 !important;
}
`);
console.log(`【Pornhub增强】info\n`, flashvars);
let data = {
id: flashvars.link_url,
title: flashvars.video_title,
url: null,
hls: [],
mp4: [],
title: flashvars.video_title,
cover: flashvars.image_url,
hotspots: flashvars.hotspots
}
let maxQuality = null;
let promises = [];
flashvars.mediaDefinitions.forEach(item => {
if (item.format === 'hls') {
let quality = Number(item.quality);
if (maxQuality === null || quality < maxQuality) {
maxQuality = quality;
}
let video = {
"url": item.videoUrl,
"html": quality <= 1080 ? `${quality}P` : quality <= 1440 ? `2K` : quality <= 2160 ? `4K` : `${quality}P`,
"quality": quality
};
data.hls.push(video);
} else if (item.format === 'mp4') {
let url = new URL(item.videoUrl)
if (location.host.includes("pornhub")) url.host = location.host
let promise = unsafeWindow.fetch(url.href)
.then(response => response.json())
.then(res => {
res.forEach(item => {
let quality = Number(item.quality);
if (maxQuality === null || quality < maxQuality) {
maxQuality = quality;
}
let video = {
"url": item.videoUrl,
"html": quality <= 1080 ? `${quality}P` : quality <= 1440 ? `2K` : quality <= 2160 ? `4K` : `${quality}P`,
"quality": quality
};
data.mp4.push(video);
});
})
.catch(error => {
console.error('Fetch 发生错误:', error);
});
promises.push(promise); // 将 Promise 存入数组
}
});
data.hls.sort((a, b) => (b.quality || 0) - (a.quality || 0));
data.hls.forEach(url => {
if (url.quality === maxQuality) {
url.default = true;
data.url = url.url
}
});
waitForKeyElements("div.video-wrapper div#player", function (element) {
let player = $('<div class="index-module_art-player" style="overflow: hidden; aspect-ratio: 16/9; border-radius: 10px;"></div>')
element.after(player);
element.fadeOut();
play(data.id, data.url, data.hls, data.cover, (art) => {
art.controls.add({
name: 'hideList',
index: 50,
position: 'right',
html: '<i class="art-icon"><svg width="18" height="18" viewBox="0 0 1152 1024"><path fill="#fff" d="M1075.2 0H76.8A76.8 76.8 0 0 0 0 76.8v870.4a76.8 76.8 0 0 0 76.8 76.8h998.4a76.8 76.8 0 0 0 76.8-76.8V76.8A76.8 76.8 0 0 0 1075.2 0zM1024 128v768H128V128h896zm-576"></path></svg></i>',
tooltip: '宽屏模式',
click: function () {
$('#hd-rightColVideoPage').fadeToggle();
if ($('#vpContentContainer').attr("style")) {
$('#vpContentContainer').removeAttr("style");
} else {
$('#vpContentContainer').css({ "grid-template-columns": "auto" });
}
}
})
art.on('fullscreen', () => {
$('header').fadeToggle();
$(art.controls.fullscreenWeb).toggle();
$(art.controls.hideList).toggle();
});
art.on('fullscreenWeb', () => {
$(art.controls.fullscreen).toggle();
$(art.controls.hideList).toggle();
});
if (data.hotspots) {
// 平滑函数,使用简单的移动平均
function smoothData(data, windowSize) {
var smoothed = [];
for (let i = 0; i < data.length; i++) {
let sum = 0;
let count = 0;
for (let j = Math.max(0, i - windowSize); j <= Math.min(data.length - 1, i + windowSize); j++) {
sum += data[j];
count++;
}
smoothed.push(sum / count);
}
return smoothed;
}
let hotspots = smoothData(data.hotspots.slice(5), 2);
var svgWidth = 1000;
var svgHeight = 100;
var max = Math.max(...hotspots);
let points = `0,${svgHeight} `; // 从左下角开始
hotspots.forEach((value, index) => {
var x = (index / (hotspots.length - 1)) * svgWidth;
var y = svgHeight - (value / max) * svgHeight;
points += `${x},${y} `;
});
points += `${svgWidth},${svgHeight}`; // 到右下角
$(art.template.$layer).css({ "z-index": "61" })
$(art.template.$progress).prepend(`
<svg viewBox="0 0 1000 100" preserveAspectRatio="none" style="height: 30px; width: 100%; transform: translateY(5.6px); pointer-events: none;">
<polygon id="heatmap" points="${points}" fill="var(--art-progress-color)" stroke="var(--art-progress-color)" />
</svg>
`)
}
});
})
waitForKeyElements("div.playerWrapper", function (element) {
let player = $('<div class="index-module_art-player" style="overflow: hidden; aspect-ratio: 16/9; margin-top: 60px;"></div>')
element.after(player);
element.fadeOut();
play(data.id, data.url, data.hls, data.cover, (art) => {
art.on('fullscreen', () => {
$('header').fadeToggle();
$(art.controls.fullscreenWeb).toggle();
$(art.controls.hideList).toggle();
});
art.on('fullscreenWeb', () => {
$(art.controls.fullscreen).toggle();
$(art.controls.hideList).toggle();
});
if (data.hotspots) {
// 平滑函数,使用简单的移动平均
function smoothData(data, windowSize) {
var smoothed = [];
for (let i = 0; i < data.length; i++) {
let sum = 0;
let count = 0;
for (let j = Math.max(0, i - windowSize); j <= Math.min(data.length - 1, i + windowSize); j++) {
sum += data[j];
count++;
}
smoothed.push(sum / count);
}
return smoothed;
}
let hotspots = smoothData(data.hotspots.slice(5), 2);
var svgWidth = 1000;
var svgHeight = 100;
var max = Math.max(...hotspots);
let points = `0,${svgHeight} `; // 从左下角开始
hotspots.forEach((value, index) => {
var x = (index / (hotspots.length - 1)) * svgWidth;
var y = svgHeight - (value / max) * svgHeight;
points += `${x},${y} `;
});
points += `${svgWidth},${svgHeight}`; // 到右下角
$(art.template.$progress).prepend(`
<svg viewBox="0 0 1000 100" preserveAspectRatio="none" style="height: 30px; width: 100%; transform: translateY(5.1px);">
<polygon id="heatmap" points="${points}" fill="var(--art-progress-color)" stroke="var(--art-progress-color)" />
</svg>
`)
}
});
})
waitForKeyElements("div.video-wrapper div.video-actions-menu,div.categoryTags div.tooltipWrapper", function (element) {
let downloadContent = $(`<div class="download-urls"><ul></ul><li><span style="width:100%; text-align: center;">小贴士:MP4 下载总是失败?复制 HLS 链接到猫抓插件(需单独安装)的 M3U8 解析器里再下载吧</span></li></div>`);
element.after(downloadContent);
data.hls.forEach(item => {
let downloadItem = $(`
<li>
<span class="download-url label">HLS ${item.html}</span>
<input class="download-url input" value="${item.url}" />
<a class="download-url copy" data-href="${item.url}" href="javascript: void(0);" style="width: 10%;">复制</a>
</li>
`);
downloadItem.find('.download-url.copy').on('click', function (element) {
element.preventDefault();
element = $(this)
GM_setClipboard(element.data('href'));
element.text("成功")
setTimeout(() => { element.text("复制") }, 1000)
})
element.parent().find(".download-urls ul").append(downloadItem);
});
Promise.all(promises).then(() => {
data.mp4.sort((a, b) => (b.quality || 0) - (a.quality || 0));
data.mp4.forEach(item => {
let downloadItem
// 对于原始站点显示下载按钮
if (location.host.includes("pornhub")) {
downloadItem = $(`
<li>
<span class="download-url label">MP4 ${item.html}</span>
<input class="download-url input" value="${item.url}" />
<button class="download-url download" data-href="${item.url}" data-name="${data.title} ${item.html}">下载</button>
<a class="download-url copy" data-href="${item.url}" href="javascript: void(0);">复制</a>
</li>
`)
downloadItem.find('.download-url.download').on('click', async function (event) {
if (!$(this).data('href')) return;
event.preventDefault();
let element = $(this);
let index = element.data('index');
let ins = {};
let progress = {};
let totalSize = 0;
element.prop('disabled', true);
ins[index] = setInterval(() => {
let prog = +progress[index] || 0;
element.text(prog.toFixed(1) + "%"); // 显示下载进度,保留一位小数
}, 100);
const httpRequest = typeof GM_xmlhttpRequest !== "undefined" ? GM_xmlhttpRequest : GM.xmlHttpRequest;
const handleProgress = (event) => {
if (event.lengthComputable) {
totalSize = event.total;
let currentLoaded = event.loaded;
progress[index] = ((currentLoaded / totalSize) * 100).toFixed(1); // 计算百分比
}
};
const handleLoad = (response) => {
clearInterval(ins[index]);
if (response.status !== 200) {
handleError(new Error(`请求失败,状态码:${response.status}`));
return;
}
const arrayBuffer = response.response;
progress[index] = 100;
element.text("完成");
// 创建 Blob
const blob = new Blob([new Uint8Array(arrayBuffer)]);
const url = URL.createObjectURL(blob);
// 创建下载链接
const a = document.createElement('a');
a.href = url;
a.download = `${element.data('name')}.mp4`;
document.body.appendChild(a);
a.click();
setTimeout(() => {
URL.revokeObjectURL(url);
document.body.removeChild(a);
element.text("下载");
element.prop('disabled', false);
}, 1000);
};
const handleError = (error) => {
clearInterval(ins[index]);
console.error("下载失败:", error);
element.text("重试?");
element.prop('disabled', false).one('click', () => {
element.trigger('click');
});
};
try {
httpRequest({
method: 'GET',
url: element.data('href'),
headers: {
"referer": "https://www.pornhub.com/",
"user-agent": navigator.userAgent
},
responseType: 'arraybuffer',
onprogress: handleProgress,
onload: handleLoad,
onerror: handleError
});
} catch (error) {
handleError(error);
}
});
} else {
// 对于镜像站点显示直链按钮
downloadItem = $(`
<li>
<span class="download-url label">MP4 ${item.html}</span>
<input class="download-url input" value="${item.url}" />
<a class="download-url download" href="${item.url}" target="_blank">直链</a>
<a class="download-url copy" data-href="${item.url}" href="javascript: void(0);">复制</a>
</li>
`)
}
downloadItem.find('.download-url.copy').on('click', function (element) {
if (!$(this).data('href')) return;
element.preventDefault();
element = $(this)
GM_setClipboard(element.data('href'));
element.text("完成")
setTimeout(() => { element.text("复制") }, 1000)
})
element.parent().find(".download-urls ul").append(downloadItem);
});
})
}, true);
}, 1)
function play(id, url, urls, cover, actionFunction) {
var art = new Artplayer({
id: id,
container: '.index-module_art-player',
url: url,
volume: 1,
autoPlayback: true,
theme: '#ff9000',
customType: {
m3u8: function (video, url, art) {
if (Hls.isSupported()) {
if (art.hls) art.hls.destroy();
let hls = new Hls();
hls.loadSource(url);
hls.attachMedia(video);
art.hls = hls;
art.on('destroy', () => hls.destroy());
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = url;
} else {
art.notice.show = 'Unsupported playback format: m3u8';
}
},
},
controls: [
{
name: 'goodRing',
index: 21,
position: 'left',
html: '<i class="art-icon ph-icon-thumb-up"></i>',
tooltip: '赏个好评',
click: function () {
GM_openInTab('https://greasyfork.org/scripts/501537/feedback', { active: true });
},
}
],
icons: {
state: '<svg width="100" height="100" fill="none"><g opacity=".9"><path opacity=".5" d="M50 4.167C24.687 4.167 4.167 24.687 4.167 50c0 25.314 20.52 45.834 45.833 45.834 25.314 0 45.834-20.52 45.834-45.834 0-25.313-20.52-45.833-45.834-45.833Z" fill="#000"/><path d="M69.194 53.043 43.153 70.231a3.646 3.646 0 0 1-5.653-3.043V32.816a3.646 3.646 0 0 1 5.654-3.043l26.042 17.188c2.183 1.44 2.183 4.645 0 6.086-2.184 1.44 6.51-4.3-.002-.004Z" fill="#fff"/></g></svg>',
indicator: '<img width="16" heigth="16" style="border-radius:50px" src="/favicon.ico">',
play: '<svg width="13" height="13" viewBox="0 0 87.5 100"><path d="m0 0v100l87.5-50z"></path></svg>',
pause: '<svg width="13" height="13" viewBox="0 0 81.75 100"><path d="m56.596 100v-100h25.154v100zm-56.596-100h25.154v100h-25.154z"></path></svg>',
volume: '<svg width="18" height="18" viewBox="0 0 120 100" fill="none"><path d="m30 25 39.999-25v100l-39.999-25zm-30 50h20v-50h-20zm101.32-66.32-7.4851 7.485c9.2351 8.915 14.915 20.785 14.915 33.835s-5.6752 24.92-14.915 33.83l7.4899 7.49c11.525-10.765 18.676-25.275 18.676-41.32 0-16.046-7.1498-30.55-18.68-41.32zm-2.4453 41.32c0-10.42-4.5747-19.835-11.919-26.954l-7.5146 7.515c5.0547 5.245 8.1845 12.005 8.1845 19.44 0 7.44-3.1146 14.205-8.1697 19.456l7.515 7.5147c7.34-7.12 11.904-16.544 11.904-26.97z" stroke-width="1.1995"></path></svg>',
volumeClose: '<svg width="18" height="18" viewBox="0 0 120 100" fill="none"><path d="m83.949 30.656v65.176l-42.579-20.834v-3.2712zm7.9837-25.393-7.1156-5.2669-15.84 17.697-27.608 15.637v15.192l-9.1933 10.267v-25.459h-18.387v41.668h3.8749l-17.664 19.734 7.1156 5.267z" stroke-width="1.0504"></path></svg>',
setting: '<svg width="18" height="18" viewBox="0 0 97.3 100"><path d="m85.822 54.9c0.19964-1.6004 0.35-3.2002 0.35-4.9002s-0.15036-3.3-0.35-4.9l10.553-8.2497c0.95018-0.75 1.2004-2.1 0.60018-3.2l-10.003-17.3c-0.60018-1.1-1.9509-1.5-3.0515-1.1l-12.453 5c-2.601-2-5.4016-3.65-8.4525-4.9l-1.901-13.25c-0.14973-1.2-1.2004-2.1-2.4506-2.1h-20.006c-1.2504 0-2.3007 0.9-2.4508 2.1l-1.9006 13.25c-3.051 1.25-5.8518 2.95-8.4525 4.9l-12.453-5c-1.1503-0.45-2.4508 0-3.051 1.1l-10.003 17.3c-0.65022 1.1-0.35013 2.45 0.60018 3.2l10.553 8.2497c-0.20008 1.6-0.35013 3.25-0.35013 4.9 0 1.65 0.15005 3.2998 0.35013 4.9002l-10.553 8.2497c-0.95031 0.75032-1.2004 2.1-0.60018 3.2002l10.003 17.3c0.60018 1.0996 1.9506 1.5 3.051 1.0996l12.453-4.9996c2.6008 1.9996 5.4016 3.6499 8.4525 4.8998l1.9006 13.25c0.15004 1.2 1.2004 2.1 2.4508 2.1h20.006c1.2503 0 2.3009-0.9 2.4506-2.1l1.901-13.25c3.0508-1.2499 5.8515-2.9501 8.4525-4.8998l12.453 4.9996c1.1505 0.45032 2.4513 0 3.0515-1.0996l10.003-17.3c0.60018-1.1002 0.35-2.4499-0.60018-3.2002zm-37.161 12.6c-9.6528 0-17.505-7.8499-17.505-17.5 0-9.6499 7.8523-17.5 17.505-17.5 9.6528 0 17.505 7.8499 17.505 17.5 0 9.6506-7.8523 17.5-17.505 17.5z"></path></svg>',
},
setting: true,
hotkey: true,
flip: true,
playbackRate: true,
aspectRatio: true,
miniProgressBar: true,
fullscreen: true,
fullscreenWeb: true,
fastForward: true,
autoOrientation: true,
lock: true,
moreVideoAttr: {
'preload': 'none'
},
})
art.on('fullscreen', () => {
$('header').toggle();
$(art.controls.goodRing).toggle();
if (!$('body').hasClass('no-scroll')) {
$('body').addClass('no-scroll');
} else {
$('body').removeClass('no-scroll');
}
});
art.on('fullscreenWeb', () => {
$('header').toggle();
$(art.controls.goodRing).toggle();
if (!$('body').hasClass('no-scroll')) {
$('body').addClass('no-scroll');
} else {
$('body').removeClass('no-scroll');
}
});
var contextmenuStyle = {
"display": "flex",
"justify-content": "center",
"align-items": "center",
"border-bottom": "none"
}
art.contextmenu.add({
name: 'appTitle',
index: 1,
html: `<img width="16" heigth="16" style="border-radius:50px" src="/favicon.ico">Pronhub 增强`,
style: contextmenuStyle,
click: function () {
GM_openInTab('https://greasyfork.org/scripts/501537/feedback', { active: true });
},
})
art.contextmenu.update({
name: 'version',
index: 2,
html: `<img width="15" heigth="15" src="https://artplayer.org/assets/img/logo.png"/>Artplayer Ultra ${Artplayer.version}`,
click: function () {
GM_openInTab('https://artplayer.org/', { active: true });
},
style: contextmenuStyle
})
art.contextmenu.update({
name: 'info',
index: 40,
html: `${art.i18n.language["Video Info"]}`,
style: contextmenuStyle
})
art.contextmenu.update({
name: 'close',
index: 50,
html: `${art.i18n.language["Close"]}`,
style: contextmenuStyle
})
unsafeWindow.art = art
cover ? (art.poster = cover) : ""
urls ? (art.quality = [...urls]) : ""
$(art.template.$container).find(".icon").removeClass("icon")
actionFunction ? actionFunction(art) : ""
}
function waitForKeyElements(selectorTxt, actionFunction, bWaitOnce, iframeSelector) {
var targetbadges, btargetsFound;
if (typeof iframeSelector == "undefined")
targetbadges = $(selectorTxt);
else
targetbadges = $(iframeSelector).contents().find(selectorTxt);
if (targetbadges && targetbadges.length > 0) {
btargetsFound = true;
targetbadges.each(function () {
var jThis = $(this);
var alreadyFound = jThis.data('alreadyFound') || false;
if (!alreadyFound) {
var cancelFound = actionFunction(jThis);
if (cancelFound) {
btargetsFound = false;
} else {
jThis.data('alreadyFound', true);
}
}
});
} else {
btargetsFound = false;
}
var controlObj = waitForKeyElements.controlObj || {};
var controlKey = selectorTxt.replace(/[^\w]/g, "_");
var timeControl = controlObj[controlKey];
if (btargetsFound && bWaitOnce && timeControl) {
clearInterval(timeControl);
delete controlObj[controlKey];
} else {
if (!timeControl) {
timeControl = setInterval(function () {
waitForKeyElements(selectorTxt, actionFunction, bWaitOnce, iframeSelector);
}, 1);
controlObj[controlKey] = timeControl;
}
}
waitForKeyElements.controlObj = controlObj;
}
})();