- // ==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;
- }
- })();