/* eslint-disable no-undef */ // ==UserScript== // @name VIP视频解析 // @namespace mofiter.xinngsf // @version 1.6.7 // @description 添加的解析按钮样式与原站一致,不会产生突兀感,支持多个解析接口切换,支持自定义接口,支持站内站外解析,支持 Tampermonkey、Violentmonkey // @require https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js // @match https://v.qq.com/tv/* // @match https://v.qq.com/x/* // @match https://www.iqiyi.com/v* // @match https://v.youku.com/v_show/* // @match https://tv.sohu.com/* // @match https://film.sohu.com/album/* // @match https://www.mgtv.com/b/* // @author xinngsf mofiter // @match http://v.pptv.com/show/* // @match https://v.pptv.com/show/* // @match http://www.le.com/ptv/vplay/* // @match https://www.le.com/ptv/vplay/* // @noframes // @grant unsafeWindow // @grant GM_addStyle // @grant GM_getValue // @grant GM_setValue // @grant GM_registerMenuCommand // @updateURL https://gitee.com/xinggsf/gm/raw/master/jx-mv-vip.user.js // ==/UserScript== //原版:https://greasyfork.org/scripts/373063 'use strict'; const { protocol, hostname:host, pathname } = location; const url = `${protocol}//${host}${pathname}`; const vs = document.getElementsByTagName('video'); const videoPlayer = `
`; let playerCSS, posCSS, jiexiDIV, userIntfs; const interfaces = [ // 88看 必须修改请求头referer为https://www.mgtv1.net/ 示例网址:https://www.bilibili.com/bangumi/play/ss39418 {name:"88看",type:3,url:"https://v1.shankuwang.com/?v="}, {name:"parwix",type:3,url:"https://jx.parwix.com:4433/player/analysis.php?v="}, {name:"虾米",type:3,url:"https://jx.xmflv.com/?url="}, {name:"诺讯",type:3,url:"https://www.nxflv.com/?url="}, {name:"m3u8.tv",type:3,url:"https://jx.m3u8.tv/jiexi/?url="}, {name:"黑云",type:3,url: "https://jiexi.380k.com/?url="}, {name:"爱豆",type:3,url:"https://jx.aidouer.net/?url="}, {name:"sugan",type:3,url:"https://api.suganjx.com/index/?url="}, // Youku {name:"m1907",type:3,url:"https://z1.m1907.cn/?jx="}, {name:"OK云",type:3,url:"https://api.okjx.cc:3389/m33/?url="}, {name:"猪蹄",type:3,url:"https://jx.iztyy.com/svip/?url="}, {name:"盘古",type:3,url:"https://www.pangujiexi.cc/jiexi.php?url="}, {name:"ergan",type:3,url:"​https://jx.ergan.top/?url="}, // https://www.iqiyi.com/v_19rrjvu2dc.html // {name:"久播",type:1,url:"https://jx.jiubojx.com/vip.php?url="}, {name:"思古",type:3,url:"https://api.sigujx.com/?url="}, {name:"代代",type:3,url:"https://api.daidaitv.com/index/?url="}, // {name:"菜鸟",type:3,url: "https://jiexi.bm6ig.cn/?url="}, // {name:"tv920",type:3,url:"https://api.tv920.com/jx/?url="}, // {name:"石头云",type:3,url:"https://jiexi.071811.cc/jx.php?url="}, {name:"1717yun",type:3,url:"https://www.1717yun.com/jx/ty.php?url="}, // {name:"金桥",type:3,url:"https://www.jqaaa.com/jx.php?url="}, // {name:"618g",type:3,url:"https://jx.618g.com/?url="}, // {name:"大亨影院",type:2,url:"http://jx.oopw.top/?url="} ]; const hasDOM = css => $(css).length > 0; const delayReload = () => { setTimeout(location.reload.bind(location), 1000); }; const rawPlay = HTMLVideoElement.prototype.play; const innerParse = function(li) { HTMLVideoElement.prototype.play = function() { return this.clientWidth > 99 ? rawPlay.call(this) : new Promise(() => {}) }; // const audioCtx = new AudioContext(); // audioCtx.close(); $(vs).remove(); if (this instanceof Node) li = this; const e = $(playerCSS).empty().append(videoPlayer); const s = li.getAttribute('data-url') || interfaces[0].url + url; e.find("#iframe-player").attr("src", s); }; const hideElements = el => !!el.hide(); class TaskPool { //简易任务池 constructor(isFree) { const tasks = new Map(); const timer = setInterval(() => { for (let [i, cb] of tasks) { let ret, a = i; if (typeof i == 'string') { a = $(i); if (i.split(',').length > a.length) continue; ret = cb(a); } else if (typeof i == 'object') ret = cb($(i)); else ret = cb(i); if (!ret) tasks.delete(i); } if (isFree && !tasks.size) { clearInterval(timer); this._tasks = null; } }, 500); this._tasks = tasks; } //wait for do something. Key = css selector or element or number; cb = function($el) { return true: wait again } add(key, cb = hideElements) { if (!key) key = this._tasks.size + 1; this._tasks.set(key, cb); } } const tasks = new TaskPool(true); const showSetting = () => { if (!hasDOM('#jiexi-setting')) { GM_addStyle(`#jiexi-setting legend,table,table th,td{text-align:center;}`); const container = $( `
VIP 解析设置
接口名称接口地址接口类型操作
`); $('body').append(container); if (userIntfs.length > 0) { const trList = userIntfs.map(item => ` ${item.name} ${item.url} ${item.type} `).join(''); container.find("#interface-table").append($(trList)); } } $("#cancel-button").click(function () { this.closest("#jiexi-setting").remove(); }); $("#save_button").click(function () { const tr = $(this).closest('tr'); var interface_name = tr.find("#interface-name").val().trim(); var interface_url = tr.find("#interface-url").val().trim(); var interface_type = tr.find('input[name="interface-type"]:checked').val() | 0; if (interface_name == "") { alert("请输入接口名称"); return; } if (interface_url == "") { alert(" 请输入接口地址"); return; } if (!interface_url.startsWith("http")) { alert(" 请输入以 http 或 https 开头的接口地址"); return; } if ((interface_type & 1) && !interface_url.startsWith("https")) { alert("站内解析只支持以 https 开头的接口地址,请修改接口类型"); return; } var canSave = !userIntfs.some(item => interface_name === item.name); if (canSave) { userIntfs.push({ "name": interface_name, "url": interface_url, "type": interface_type }); GM_setValue("user_interface", userIntfs); location.reload(); } else { alert("已存在同名接口,请修改接口名称"); } }); $(".delete-button").click(function () { const pp = this.closest('tr'); const del_name = pp.firstChild.innerHTML; userIntfs.forEach((k, i) => { // a.splice(a.findIndex(k => k.name == del_name), 1); if (del_name == k.name) userIntfs.splice(i, 1); }); GM_setValue("user_interface", userIntfs); pp.remove(); $(`#_gm__vipJX li:contains("${del_name}")`).remove(); }); }; const router = { ["www.iqiyi.com"]() { playerCSS = "#flashbox"; posCSS = ".func-item.func-like-v1"; GM_addStyle( `.fn-iqiyi-jiexi li { color: #ccc; text-align: center; width: 60px; cursor: pointer; line-height: 20px; float:left; border:1px solid gray; border-radius:8px; padding:0 4px; margin:4px 2px; } #_gm__vipJX a {color: #ccc} .fn-iqiyi-jiexi > .qy-popup-box { background-color:#2e2e2e; border:1px solid gray; } #flashbox { z-index: 400 !important } .func-item.fn-jiexi-main:hover > div { display: block } .fn-iqiyi-jiexi { display:none;position:absolute;left:-50px; text-align:center;z-index:2147483647; } .iqiyi_JX:hover {color: #6ba430} #_gm__vipJX li:hover, #_gm__vipJX a:hover {color: #01be07}`); const iqiyi_jiexi = $( `
解析
${jiexiDIV}
`); this.wait = el => { $(posCSS).replaceWith(iqiyi_jiexi)[0].addEventListener('click', ev => { const e = ev.target; if (e.matches('li[data-url]')) { ev.stopPropagation(); innerParse(e); } }); //.find("li[data-url], .fn-iqiyi-jiexi-text").click(innerParse); }; tasks.add(".qy-player-vippay-popup, .black-screen"); }, ["v.qq.com"]() { playerCSS = "#mod_player"; posCSS = ".action_wrap.cf"; GM_addStyle( `.fn-qq-jiexi { background-color:#2e2e2e; width:auto; left:-50px; border:1px solid gray; } .fn-qq-jiexi li { text-align:center; width:60px; line-height:20px; float:left; border:1px solid gray; border-radius:8px; padding:0 4px; color:#999; cursor: pointer; margin:4px 2px; } .fn-qq-jiexi a { color:#999; } #_gm__vipJX li:hover {color:#fe6527}` ); const qq_jiexi = $( `
解析
${jiexiDIV}
`); this.wait = el => { const { type_name, vipPage } = unsafeWindow.COVER_INFO; if (type_name === "电影") { $(".mod_figure_list .list_item").click(delayReload); } else if (type_name === "电视剧" || type_name === "动漫") { $('.mod_episode .item').click(delayReload); $(".mod_episode_filter").click(() => { $('.mod_episode .item').click(delayReload); }); } $(".action_share, .action_qrcode, .action_more").remove(); el.filter(posCSS).append(qq_jiexi) .on("mouseover mouseout", () => { qq_jiexi.toggleClass("open"); }) .find(".fn-qq-jiexi-text, li[data-url]").click(ev => { unsafeWindow.fetch = x => new Promise((_, fail) => fail()); $('.txp_btn_play[data-status=pause]').click(); $("body").unbind('keydown keyup'); innerParse(ev.target); }); }; tasks.add(".mod_vip_popup,.tvip_layer,#mask_layer"); }, ["v.youku.com"]() { playerCSS = '#ykPlayer'; posCSS = "ul.play-fn"; GM_addStyle( `.fn-youku-jiexi li { text-align:center;width:60px;line-height:20px; float:left;border:1px solid gray;border-radius:3px; padding:0 4px;margin:4px 2px; cursor: pointer; } #_gm__vipJX a {color:#ccc} .fn-youku-jiexi > .fn-panel { border:1px solid gray; min-width:100%; } #_gm__vipJX li:hover, #_gm__vipJX a:hover {color:#2592ff}` ); const youku_jiexi = $( `
  • 解析
    ${jiexiDIV}
  • `); this.wait = el => { $('li.fn-phonewatch').hide(); el.filter(posCSS).append(youku_jiexi) .find(".fn-youku-jiexi-text, li[data-url]").click(function() { $('.control-play-icon.control-pause-icon').click(); innerParse(this); }); }; }, ["www.mgtv.com"]() { playerCSS ="#mgtv-player-wrap"; posCSS = ".logolist"; GM_addStyle( `.fn-mgtv-jiexi:hover > .extend { display: block } .fn-mgtv-jiexi li { color:#ccc;text-align:center;width:60px;line-height:20px;float:left; border:1px solid gray;border-radius:8px;padding:0 4px;margin:4px 2px; cursor: pointer; } #_gm__vipJX a {color:#ccc} .fn-mgtv-jiexi > .extend { display:none;top:-5px;left:-50px;text-align:center;position:relative; } #_gm__vipJX li:hover {color:#ff6f00} #_gm__vipJX a:hover {color:#ff6f00 !important} .v-panel-extend > .fn-panel { background-color:#2e2e2e;width:auto;border:1px solid gray; }`); const mgtv_jiexi = $( `
    解析
    ${jiexiDIV}
    `); this.wait = el => { $(".aside-tabbox li").click(delayReload); el.filter(posCSS).empty().append(mgtv_jiexi) .find(".fn-mgtv-jiexi-text, li[data-url]").click(innerParse); }; }, ["tv.sohu.com"]() { playerCSS = '#player'; posCSS = ".vBox-tb.cfix"; GM_addStyle( `.fn-sohu-jiexi li{ color:#333; text-align:center; width:60px; line-height:20px; float:left; border:1px solid gray; border-radius:8px; padding:0 4px; margin:4px 2px; cursor: pointer; } /* .vBox.vBox-play:hover > div {display: block} */ .fn-sohu-jiexi { display: none;background-color:#2e2e2e;border:1px solid gray; padding:0;margin:0 0 0 0;line-height:25px;min-width:100% important; } #_gm__vipJX li:hover {color:#e33c30}` ); const sohu_jiexi = $( `
    解析
    ${jiexiDIV}
    `); sohu_jiexi.click(() => { sohu_jiexi.children(".fn-sohu-jiexi").toggle(); }); this.wait = el => { playerCSS = el.filter(playerCSS); el.filter(posCSS).prepend(sohu_jiexi) .find("li[data-url]").click(innerParse); }; tasks.add(".x-video-adv,.x-player-mask,#player_vipTips"); }, ["film.sohu.com"]() { playerCSS = "#playerWrap"; posCSS = ".player-content-info"; GM_addStyle( `.fn-sohu-jiexi li { color:#ccc; text-align:center; width:60px; cursor: pointer; line-height:20px; float:left; border:1px solid gray; border-radius:8px; padding:0 4px; margin:4px 2px; } #_gm__vipJX a {color:#ccc} .action-item.jiexi:hover > div {display: block} .fn-sohu-jiexi { display:none;background-color:#2e2e2e;border:1px solid gray; width:auto;text-align:center;margin-left:-61px; } #_gm__vipJX li:hover, #_gm__vipJX a:hover {color:#ee3c3a}` ); const sohu_film_jiexi = $( `
    解析
    ${jiexiDIV}
    `); this.wait = el => { el.filter(posCSS).prepend(sohu_film_jiexi) .find(".fn-sohu-jiexi-text, li[data-url]").click(innerParse); }; }, ["www.le.com"]() { playerCSS = "#le_playbox"; posCSS = ".interact_area"; GM_addStyle( `.fn-le-jiexi { display:none;background-color:#2e2e2e;border:1px solid gray; width:auto;position:absolute;top:45px;border-top:2px solid #E42112; box-shadow:0 2px 6px 0 rgba(0,0,0,.1);left:-40px; } .fn-le-jiexi li { color:#ccc;text-align:center;width:60px;line-height:20px; float:left;border:1px solid gray;border-radius:8px; padding:0 5px;margin:4px 2px; height:25px; } .le-jiexi-main:hover > div {display: block} #_gm__vipJX li:hover {color:#e42013}` ); const le_jiexi = $( `
  • 解析
    ${jiexiDIV}
  • `); this.wait = el => { el.filter(posCSS).prepend(le_jiexi) .find(".fn-le-jiexi-text, li[data-url]").click(innerParse); }; }, ["v.pptv.com"]() { playerCSS = "#pptv_playpage_box"; posCSS = ".module-video2016-ops ul"; GM_addStyle( `#fn-pptv-jiexi li { color:#ccc;text-align:center; width:60px;line-height:20px;float:left;border:1px solid gray; border-radius:8px;padding:0 4px;margin:4px 2px; } #_gm__vipJX li:hover, #_gm__vipJX a:hover {color:#39f} #_gm__vipJX a {color:#ccc;display:inline;padding:0 4px;} #pptv-jiexi-btn:hover>div {display: block} #fn-pptv-jiexi { display:none; position:absolute; top:50px; background-color:#444; border:1px solid gray; }`); const pptv_jiexi = $( `
  • 解析
    ${jiexiDIV}
  • ` ); this.wait = el => { el.filter(posCSS).prepend(pptv_jiexi) .find(".pptv_jiexi-text, li[data-url]").click(innerParse); }; } }; const init = () => { GM_registerMenuCommand("自定义 VIP 视频解析接口", showSetting); userIntfs = GM_getValue("user_interface", []); userIntfs.length && interfaces.push.apply(interfaces, userIntfs); let outLi = '', inLi = ''; for (const k of interfaces) { const addr = k.url.trim() + url; if (k.type & 1) inLi += `
  • ${k.name}
  • `; if (k.type & 2) outLi += `
  • ${k.name}
  • `; } jiexiDIV = `
    站内解析
    站外解析
    `; router[host] && router[host](); tasks.add(`${playerCSS},${posCSS}`, router.wait); }; init();