您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
显示影片预览图和预览影片
// ==UserScript== // @name x1080x-preview // @license MIT // @namespace https://greasyfork.org/zh-CN/scripts/439204-x1080x-preview // @version 7.6 // @description 显示影片预览图和预览影片 // @author jasmine // @match https://*.x567x.me/forum.php?mod=viewthread&tid=* // @match https://*.x567x.me/home.php?mod=spacecp&ac=pm&from=script // @match https://x567x.me/forum.php?mod=viewthread&tid=* // @match https://x567x.me/home.php?mod=spacecp&ac=pm&from=script // @match https://*.x999x.me/forum.php?mod=viewthread&tid=* // @match https://*.x999x.me/home.php?mod=spacecp&ac=pm&from=script // @match https://x999x.me/forum.php?mod=viewthread&tid=* // @match https://x999x.me/home.php?mod=spacsecp&ac=pm&from=script // @icon https://www.google.com/s2/favicons?domain=www.x999x.me // @connect javdb.com // @connect javbus.com // @connect ec.sod.co.jp // @connect cloudfront.net // @connect r18.com // @connect www.dmm.co.jp // @connect accounts.dmm.co.jp // @connect dahlia-av.jp // @connect cdn.faleno.net // @connect faleno.jp // @connect www.mgstage.com // @connect www.afesta.tv // @connect www.bing.com // @require https://lib.baomitu.com/jquery/3.5.1/jquery.min.js // @resource fancybox_css https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.css // @require https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.js // @resource videojs_css https://lib.baomitu.com/video.js/5.20.5/video-js.min.css // @require https://lib.baomitu.com/video.js/5.20.5/video.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/videojs-hotkeys/0.2.27/videojs.hotkeys.min.js // @resource videojs_resolution_switcher_css https://lib.baomitu.com/videojs-resolution-switcher/0.4.2/videojs-resolution-switcher.min.css // @require https://lib.baomitu.com/videojs-resolution-switcher/0.4.2/videojs-resolution-switcher.min.js // @grant GM_xmlhttpRequest // @grant GM_notification // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @grant GM_getResourceText // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // @grant GM_log // @grant GM_openInTab // @grant GM_info // ==/UserScript== (function() { 'use strict'; // 菜单列表 var menu_ALL = [ ['menu_showGallery', '显示预览图', '显示预览图', true], ['menu_quality', '画面优先', '画面优先', true], ['menu_jumpSOD', '视频跳转SOD', '视频跳转SOD', true], ['menu_offcial', '搜索官网', '搜索官网', true], ['menu_multi', '并发搜索', '并发搜索', false], ['menu_JavDB', '搜索JavDB', '搜索JavDB', false], ['menu_JavBus', '搜索JavBus', '搜索JavBus', false], ], menu_ID = []; for (let i=0;i<menu_ALL.length;i++){ // 如果读取到的值为 null 就写入默认值 if (GM_getValue(menu_ALL[i][0]) == null) { GM_setValue(menu_ALL[i][0], menu_ALL[i][3]) }; } registerMenuCommand(); // 注册脚本菜单 function registerMenuCommand() { if (menu_ID.length > menu_ALL.length){ // 如果菜单ID数组多于菜单数组,说明不是首次添加菜单,需要卸载所有脚本菜单 for (let i=0;i<menu_ID.length;i++){ GM_unregisterMenuCommand(menu_ID[i]); } } for (let i=0;i<menu_ALL.length;i++){ // 循环注册脚本菜单 menu_ALL[i][3] = GM_getValue(menu_ALL[i][0]); menu_ID[i] = GM_registerMenuCommand(`${menu_ALL[i][3]?'✅':'❌'} ${menu_ALL[i][1]}`, function(){menu_switch(`${menu_ALL[i][3]}`,`${menu_ALL[i][0]}`,`${menu_ALL[i][2]}`)}); } // menu_ID[menu_ID.length] = GM_registerMenuCommand(`📥 导入FanzaCookies`, function () { // let fanza_cookies = ""; // let cookies = prompt("请使用EditThisCookie导出Cookies后粘贴至此"); // try { // JSON.parse(cookies).forEach(item=>{ // fanza_cookies += `${item.name}=${item.value};` // }) // GM_setValue("FANZA_Cookies", fanza_cookies) // } catch (error) { // console.error(error); // } // }) menu_ID[menu_ID.length + 1] = GM_registerMenuCommand('💬 反馈 & 建议', function () {GM_openInTab(`https://${document.location.hostname}/home.php?mod=spacecp&ac=pm&from=script`, {active: true,insert: true,setParent: true});}); } // 菜单开关 function menu_switch(menu_status, Name, Tips) { if (menu_status == 'true'){ GM_setValue(`${Name}`, false); GM_notification({text: `已关闭 [${Tips}] 功能\n(点击刷新网页后生效)`, timeout: 3500, onclick: function(){location.reload();}}); }else{ GM_setValue(`${Name}`, true); if (['menu_JavDB', 'menu_JavBus'].includes(Name)) { GM_setValue('menu_offcial', false) } GM_notification({text: `已开启 [${Tips}] 功能\n(点击刷新网页后生效)`, timeout: 3500, onclick: function(){location.reload();}}); } registerMenuCommand(); // 重新注册脚本菜单 }; // 返回菜单值 function menu_value(menuName) { for (let menu of menu_ALL) { if (menu[0] == menuName) { return menu[3] } } } // 日志记录 function record_log(msg) { let log = GM_getValue("log"); if (log !== "") { log = log + "\n" } GM_setValue("log", log + msg); GM_log(msg); } // 根据xpath查找 一个结果 function _xO(path, obj) { return obj.evaluate(path, obj, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; } // 根据xpath查找 多个结果 function _xM(path, obj) { var xresult = obj.evaluate(path, obj, null, XPathResult.ANY_TYPE, null); var xnodes = []; var xres; while (xres = xresult.iterateNext()) { xnodes.push(xres.textContent); } return xnodes; } // 通用请求 function gmFetch(obj) { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: obj.method || 'GET', // timeout in ms timeout: obj.timeout, url: obj.url, headers: obj.headers, cookie: obj.cookie, data: obj.data, revalidate: obj.revalidate ? true: false, nocache: obj.nocache ? true: false, onload: res => { if (res.status >= 200 && res.status < 400 || res.finalUrl === "http://ec.sod.co.jp/prime/") { resolve(res); } else { reject(res); } }, onerror: reject, ontimeout: reject, }); }); } // 请求 function fetch(url, headers={"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"}){ return new Promise((resolve, reject) => { GM_xmlhttpRequest({ url: url, method: "GET", headers: headers, //timeout: 5000, onload: function(r){ if (r.status === 200) { resolve(r.responseText) } else { reject("status error: " + r.status) } }, onerror: function(e) { reject('fetch error') }, ontimeout: function(e) { reject('fetch timeout') } }); }) } // 检查连接 function checkURL(url, headers={"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"}){ return new Promise((resolve, reject) => { GM_xmlhttpRequest({ url: url, method: "HEAD", headers: headers, //timeout: 5000, onload: function(r){ if (r.status === 200) { resolve(true) } else { resolve(false) } }, onerror: function(e) { resolve(false) }, ontimeout: function(e) { resolve(false) } }); }) } async function asyncForEach(array, callback) { for (let index = 0; index < array.length; index++) { await callback(array[index], index, array); } } // 格式化页面 function parseResponse(html) { const parser = new DOMParser() const tree = parser.parseFromString(html, "text/html") return tree } // DMM获取大图 function preview_src(src) { if (src.match(/(p[a-z]\.)jpg/)) { return src.replace(RegExp.$1, 'pl.'); } else if (src.match(/consumer_game/)) { return src.replace('js-','-'); } else if (src.match(/js\-([0-9]+)\.jpg$/)) { return src.replace('js-','jp-'); } else if (src.match(/ts\-([0-9]+)\.jpg$/)) { return src.replace('ts-','tl-'); } else if (src.match(/(\-[0-9]+\.)jpg$/)) { return src.replace(RegExp.$1, 'jp' + RegExp.$1); } else { return src.replace('-','jp-'); } } function getBase64FromImage(url, onSuccess, onError) { var xhr = new XMLHttpRequest(); xhr.responseType = "arraybuffer"; xhr.open("GET", url); xhr.onload = function () { var base64, binary, bytes, mediaType; bytes = new Uint8Array(xhr.response); //NOTE String.fromCharCode.apply(String, ... //may cause "Maximum call stack size exceeded" binary = [].map.call(bytes, function (byte) { return String.fromCharCode(byte); }).join(''); mediaType = xhr.getResponseHeader('content-type'); base64 = [ 'data:', mediaType ? mediaType + ';':'', 'base64,', btoa(binary) ].join(''); onSuccess(base64); }; xhr.onerror = onError; xhr.send(); } // 插入预览图 function insertImages(item) { let src; if (video_type === "sod" && ["sod", "javbus"].includes(source)) { src = URL.createObjectURL(item) } else { src = item } const a = document.createElement("a"); const img = document.createElement("img"); a.href = src; a.setAttribute("data-fancybox", "gallery"); a.setAttribute("class", "x1080x-ga-box"); img.setAttribute("class", "x1080x-auto-img"); img.src = src; a.appendChild(img); gallery_div.appendChild(a); } //下载预览图 // async function downloadSODImages(gallery, headers) { // for (let index = 0; index < gallery.length; index++) { // try { // await download(gallery[index], gallery[index], headers); // } // catch(e){ // record_log(e) // } // } // } //访问预览图 async function accessSODImages(gallery, headers) { for (let index = 0; index < gallery.length; index++) { try { await fetch(gallery[index], headers); } catch(e){ record_log(e) } } } // 浏览器版本 navigator.sayswho= (function(){ let ua= navigator.userAgent; let tem; let M= ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || []; if(/trident/i.test(M[1])){ tem = /\brv[ :]+(\d+)/g.exec(ua) || []; return 'IE '+(tem[1] || ''); } if(M[1]=== 'Chrome'){ tem= ua.match(/\b(OPR|Edge)\/(\d+)/); if(tem!= null) return tem.slice(1).join(' ').replace('OPR', 'Opera'); } M= M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?']; if((tem= ua.match(/version\/(\d+)/i))!= null) M.splice(1, 1, tem[1]); return M.join(' '); })(); // 入口 //const res = await fetch("https://www.dmm.co.jp/service/digitalapi/-/html5_player/=/cid=ssis279/mtype=AhRVShI_/service=litevideo/mode=/width=560/height=360/", {"accept-language": "ja-JP,ja;q=0.9"}) //log(res); //const re = /const args = ({.+});$/gm; //const hits = []; //// Iterate hits //let match = null; //do { // match = re.exec(res); // if(match) { // hits.push(match[1]); // } //} while (match); //const obj = JSON.parse(hits[0]) //record_log(obj["bitrates"]); // Prints [ '#with', '#hashtags' ] //return false // 意见反馈 if (window.location.href.endsWith("from=script")) { //let log = GM_getValue("log") document.querySelector("#username").value = "jpyl0423" document.querySelector("#sendmessage").value = GM_getValue("log") return } // 基础div const node = _xO("//div[@class='t_fsz']/table/tbody", document); if (node == null || !menu_value("menu_showGallery")) { return; } // 封面 let cover = document.querySelector("td[id^=postmessage] img").src if (!cover.match(/(pics.dmm.co.jp|www.hxmmdd.com)/)) { return } // 预览容器 const tr = document.createElement("tr"); const td = document.createElement("td"); const gallery_div = document.createElement("div") td.appendChild(gallery_div) tr.appendChild(td) gallery_div.setAttribute("class", "x1080x-gallery"); const ga_inner = document.createElement('span'); gallery_div.appendChild(ga_inner) node.appendChild(tr) // 播放容器 const play_box = document.createElement("a"); play_box.setAttribute("class", "x1080x-ga-box x1080x-play-box"); play_box.setAttribute("data-fancybox", ""); gallery_div.insertBefore(play_box, gallery_div.firstChild); // 视频封面 const poster = document.createElement("img"); poster.setAttribute("class", "x1080x-auto-img"); poster.src = cover const span = document.createElement("span"); span.setAttribute("class", "x1080x-preview"); span.innerHTML = '預告片' const outer_span = document.createElement("span"); outer_span.setAttribute("class", "x1080x-outer"); outer_span.innerHTML = '外链' play_box.appendChild(span); play_box.appendChild(outer_span); play_box.appendChild(poster); // 播放器 const video_player = document.createElement("video"); video_player.setAttribute("id", "x1080x-player"); video_player.setAttribute("class", "video-js vjs-default-skin"); play_box.append(video_player) const options = { controls: true, responsive: true, plugins: { videoJsResolutionSwitcher: { default: menu_value('menu_quality') ? `high`: `low`, // Default resolution [{Number}, 'low', 'high'], dynamicLabel: true } }, }; let player = videojs("x1080x-player", options, function(){}); player.ready(function() { this.hotkeys({ volumeStep: 0.1, seekStep: 5, enableModifiersForNumbers: false }); }); // 加载fancybox样式 const fancybox_css = GM_getResourceText("fancybox_css"); GM_addStyle(fancybox_css); // 加载video-js样式 const videojs_css = GM_getResourceText("videojs_css"); GM_addStyle(videojs_css); GM_addStyle(".video-js .vjs-progress-holder, .video-js .vjs-progress-holder .vjs-play-progress,.video-js .vjs-progress-holder .vjs-load-progress,.video-js .vjs-progress-holder .vjs-tooltip-progress-bar,.video-js .vjs-progress-holder .vjs-load-progress div{height:1.0em}"); // 加载videojs-resolution-switcher样式 const videojs_resolution_switcher_css = GM_getResourceText("videojs_resolution_switcher_css"); GM_addStyle(videojs_resolution_switcher_css); // 自定义样式 let btn_img = `PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNTEycHgiIGhlaWdodD0iNTEycHgiIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPCEtLSBHZW5lcmF0b3I6IFNrZXRjaCA1Mi4xICg2NzA0OCkgLSBodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2ggLS0+CiAgICA8dGl0bGU+YnRuLXBsYXk8L3RpdGxlPgogICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+CiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0iYnRuLXBsYXkiIGZpbGwtcnVsZT0ibm9uemVybyI+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yNTYsMCBDMTE0Ljg0MzU0OSwwIDAsMTE0Ljg0MzU0OSAwLDI1NiBDMCwzOTcuMTU2NDUxIDExNC44NDM1NDksNTEyIDI1Niw1MTIgQzM5Ny4xNTY0NTEsNTEyIDUxMiwzOTcuMTU2NDUxIDUxMiwyNTYgQzUxMiwxMTQuODQzNTQ5IDM5Ny4xNTY0NTEsMCAyNTYsMCBaIiBpZD0iU2hhcGUiIGZpbGw9IiMwQTVFRTAiPjwvcGF0aD4KICAgICAgICAgICAgPHBvbHlnb24gaWQ9IlBhdGgiIGZpbGw9IiNGRkZGRkYiIHBvaW50cz0iMTkyIDM4My45OTcyODUgMTkyIDEyNy45OTkwOTUgMzg0IDI1NS45OTcyODUiPjwvcG9seWdvbj4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==` GM_addStyle(` .x1080x-gallery { display: flex; flex-direction: row; flex-wrap: wrap; margin-top: 10px; max-width: 95%; } .x1080x-ga-box { display: inline-block; width: 250px; height: auto; text-align: center; vertical-align: middle; overflow-x: hidden; text-overflow: ellipsis; font-size: .9rem; background-color: black; margin: 5px 5px 0px 0px; cursor: pointer; } .x1080x-ga-box .x1080x-auto-img { position: relative; height: 120px; } .x1080x-play-box { display: none; position: relative; } .x1080x-play-box span.x1080x-preview { font-size: .8rem; color: #fff; background-color: #fc8300; position: absolute; top: 4px; left: 4px; text-align: center; padding: 1px 2px; border-radius: 3px; z-index: 999; } .x1080x-play-box span.x1080x-outer { font-size: .8rem; color: #fff; background-color: #fc8300; position: absolute; top: 4px; right: 4px; text-align: center; padding: 1px 2px; border-radius: 3px; z-index: 999; display: none; } .x1080x-play-box:after { background: url("data:image/svg+xml;base64,${btn_img}") 50% no-repeat; background-color: rgba(0,0,0,.2); background-size: 40px 40px; bottom: 0; content: ""; display: block; left: 0; position: absolute; right: 0; top: 0; height: 100%; } .x1080x-play-box:hover::after { background-color: rgba(33,156,239,0);; } #x1080x-player { display:none; position: absolute; width: 50%; height: 50%; top: 50%; left: 50%; transform: translate(-50%, -50%); overflow: hidden; } `); GM_setValue("log", ""); let title_pattern = /\)([^\(\)].*)</g; let subject = document.querySelector("#thread_subject").innerText let video_type; if (subject.match(/\(SOD\)|\(SODVR\)/) && menu_value("menu_offcial")) { video_type = "sod" } else if ([subject.match(/\(Prestige\)|\(MAXING\)/), document.body.innerHTML.indexOf("Prestige") != -1].some((e)=>e) && menu_value("menu_offcial")) { video_type = "mgs" } else if (subject.match(/\(AfestaVR\)/) && menu_value("menu_offcial")) { video_type = "afesta" } else { video_type = "sod" } let is_vr = (subject.indexOf("【VR】") !== -1 || subject.indexOf("【8K VR】")!== -1) ? true: false let pid = cover.replace("pl.jpg", ".jpg").replace("plzm.jpg", ".jpg").split("/").slice(-1)[0].split(".")[0] let vid = subject.match(/\w+-\d+/)[0] // SOD影片有可能在DMM, 番号格式类似: 1mogi00030 if (pid != vid && video_type == "sod") { video_type = "dmm" } if (menu_value("menu_offcial") && pid.startsWith(`1`) == false) { if (subject.match(/\(DAHLIA\)/)) { video_type = "dahlia" pid = pid.replace("-", "") } if (subject.match(/\(FALENO\)/) && document.body.innerHTML.indexOf("Prestige") === -1) { video_type = "faleno" pid = pid.replace("-", "") } } if (is_vr & video_type == "sod" & vid.startsWith('3') == false) { vid = `3${vid}` } if (pid.match(/\d{3}[A-Z]+-\d{3}/)) { video_type = "mgs" } // MXGS-1341 const regex = /^MXGS-(\d{3,4})$/i; const match = vid.match(regex); if (match) { const numberPart = match[1]; const paddedNumber = numberPart.padStart(5, '0'); vid = `mxgs${paddedNumber}`; video_type = "dmm" } let multi_search = menu_value("menu_multi") record_log(`浏览器: ${navigator.sayswho}`) record_log(`插件版本: ${GM_info.script.version}`) record_log(`标题: ${subject}`) record_log(`地址: ${window.location.href}`) record_log(`番号: ${pid}`) record_log(`视频ID: ${vid}`) let source; let dmm = async() => { if (!multi_search && (video_type !== "dmm" && !(video_type == "sod" && pid.includes("-"))) || !menu_value("menu_offcial")) { record_log(`DMM Search: 跳过`) throw new Error('DMM Search: 跳过'); } let search_id = pid if (pid.includes("-")) { search_id = pid.split("-").join("00").toLowerCase() } record_log(`DMM Search: ${search_id}`) let dmm_headers = {"accept-language": "ja-JP,ja;q=0.9"} let dmm_cookie = "age_check_done=1" //let dmm_cookie = GM_getValue("FANZA_Cookies") ? GM_getValue("FANZA_Cookies"): "age_check_done=1"; let search_request = {url: `https://www.dmm.co.jp/search/=/searchstr=${search_id}`, headers: dmm_headers, cookie: dmm_cookie} let search_res = await gmFetch(search_request).catch(err => {record_log(err); return;}) // let search_html = parseResponse(search_res.responseText) // let ele_detail = search_html.querySelector(`.tmb a[href*="${search_id}"][href^="https://www.dmm.co.jp"]`) const pattern = `https:\/\/www\.dmm\.co\.jp\/[\\w\/\\-\\=]*cid=${search_id}`; const regex = new RegExp(pattern, "g"); let ele_detail = regex.exec(search_res.responseText) if (!ele_detail) { record_log(`DMM Search: 未找到`); throw new Error('DMM Search: 未找到'); } // let detail_url = ele_detail.getAttribute("href").split("?")[0] let detail_url = ele_detail[0] record_log(`DMM Search: 详情页 ${detail_url}`) // let cid_pattern = /cid=(.*?\w)\// // let cid = cid_pattern.exec(detail_url)[1] let detail_request = {url: detail_url, headers: dmm_headers, cookie: dmm_cookie} let detail_res = await gmFetch(detail_request).catch(err => {record_log(err); return;}) let detail_html = parseResponse(detail_res.responseText) // 预览图 let imgs = [...detail_html.querySelectorAll("#sample-image-block img")].map( item => item.getAttribute("src")).map( item => preview_src(item)) // 预览视频 let video = [] if (is_vr) { let video_request = {url: `https://www.dmm.co.jp/digital/-/vr-sample-player/=/cid=${search_id}/`, headers: dmm_headers, cookie: dmm_cookie} let video_res = await gmFetch(video_request).catch(err => {record_log(err); return;}); let video_pattern = /var sampleUrl = "(.*)";/g; let video_url = video_pattern.exec(video_res.responseText)[1] if (video_url !== '') { video.push({ src: video_url, type: 'video/mp4', label: `VR`, res: `100` }) } } else { // let video_request = {url: `https://www.dmm.co.jp/service/digitalapi/-/html5_player/=/cid=${cid}/mtype=AhRVShI_/service=litevideo/mode=/width=560/height=360/`, headers: dmm_headers, cookie: dmm_cookie}; let video_request = {url: `https://www.dmm.co.jp/service/digitalapi/-/html5_player/=/cid=${search_id}`, headers: dmm_headers, cookie: dmm_cookie}; const video_label = {300: "流畅", 1000: "清晰", 1500: "高清", 2000: "高清", 3000: "HD", "4K (2160p)": "4K", "4K (2160p60)": "4K", "FullHD (1080p)": "1080p", "FullHD (1080p60)": "1080p", "HD (720p)": "720p", "HD (720p60)": "720p","高画質 (576p)": "576p", "中画質 (432p)": "432p", "中画質 (288p)": "288p", "低画質 (144p)": "144p"} let video_res = await gmFetch(video_request).catch(err => {record_log(err); return;}); let video_pattern = /(const args = |const params = )({.+});$/gm; if (video_res.responseText) { let bitrates = JSON.parse(video_pattern.exec(video_res.responseText)[2]).bitrates video = bitrates.map( function(item) { return { src: item.src, type: 'video/mp4', label: video_label[item.bitrate], res: item.bitrate } }) } } return {imgs: imgs, video: video, source: "dmm"} } let dahlia = async() => { if (!multi_search && video_type !== "dahlia" || !menu_value("menu_offcial")) { record_log(`DAHLIA Search: 跳过`) throw new Error('DAHLIA Search: 跳过'); } let dahlia_cookie = "max-age=0" let detail_url = `https://dahlia-av.jp/works/${pid}/` record_log(`DAHLIA Search: 详情页 ${detail_url}`) let detail_request = {url: detail_url, cookie: dahlia_cookie} let detail_res = await gmFetch(detail_request).catch(err => {record_log(err); return;}) let detail_html = parseResponse(detail_res.responseText) // 预览图 let imgs = [...detail_html.querySelectorAll(".box_works01_ga a")].map( item => item.getAttribute("href")) // 预览视频 let video = [] let video_url = detail_html.querySelector(".overoll_box .pop_sample").getAttribute("href"); if (video_url !== '') { video.push({ src: video_url, type: 'video/mp4', label: `DAHLIA`, res: `100` }) } return {imgs: imgs, video: video, source: "dmm"} } let faleno = async() => { if (!multi_search && video_type !== "faleno" || !menu_value("menu_offcial")) { record_log(`FALENO Search: 跳过`) throw new Error('FALENO Search: 跳过'); } let faleno_cookie = "modal=off" let detail_url = `https://faleno.jp/top/works/${pid}/` record_log(`FALENO Search: 详情页 ${detail_url}`) let detail_request = {url: detail_url, cookie: faleno_cookie} let detail_res = await gmFetch(detail_request).catch(err => {record_log(err); return;}) let detail_html = parseResponse(detail_res.responseText) // 预览图 let imgs = [...detail_html.querySelectorAll(".box_works01_ga a")].map( item => item.getAttribute("href")) // 预览视频 let video = [] let video_url = detail_html.querySelector(".pop_sample").getAttribute("href"); if (video_url !== '') { video.push({ src: video_url, type: 'video/mp4', label: `FALENO`, res: `100` }) } return {imgs: imgs, video: video, source: "dmm"} } let mgstage = async() => { if (!multi_search && video_type !== "mgs" || !menu_value("menu_offcial")) { record_log(`MGSTAGE Search: 跳过`) throw new Error('MGSTAGE Search: 跳过'); } record_log(`MGSTAGE Search: ${pid}`) let cookie = `adc=1`; let detail_request = {url: `https://www.mgstage.com/product/product_detail/${pid}/`, cookie: cookie} let detail_res = await gmFetch(detail_request).catch(err => {record_log(err); return;}) let detail_html = parseResponse(detail_res.responseText) // 预览图 let imgs = [...detail_html.querySelectorAll(".sample_image")].map( item => item.getAttribute("href")) // 预览视频 let video = [] let ele = detail_html.querySelector('div.detail_photo p.sample_movie_btn a:not([disabled])'); if (ele) { let href = ele.getAttribute('href'); let pid = href.split('/').pop(); record_log(`MGSTAGE Search: 视频ID ${pid}`); let video_request = {url: `https://www.mgstage.com/sampleplayer/sampleRespons.php?pid=${pid}`, cookie: cookie} let video_res = await gmFetch(video_request).catch(err => {record_log(err); return;}) let re = /https.*?ism/ let json_obj = JSON.parse(video_res.responseText); let video_url = json_obj.url; video_url = re.exec(video_url)[0].replace('ism', 'mp4'); video.push({ src: video_url, type: 'video/mp4', label: `MGS`, res: `100` }) } return {imgs: imgs, video: video, source: "mgs"} } let sod = async() => { if (!multi_search && video_type !== "sod" || !menu_value("menu_offcial")) { record_log(`SOD Search: 跳过`) throw new Error('SOD Search: 跳过'); } record_log(`SOD Search: ${vid}`) let detail_request = {url: `https://ec.sod.co.jp/prime/videos/?id=${vid}`} let detail_res = await gmFetch(detail_request).catch(err => {record_log(err); return;}) let detail_html = parseResponse(detail_res.responseText) let age_check = detail_html.querySelector(".pkg_age") if (age_check) { await gmFetch({url: `https://ec.sod.co.jp/prime/_ontime.php`}).catch(err => {record_log(err); return;}) detail_res = await gmFetch(detail_request).catch(err => {record_log(err); return;}) detail_html = parseResponse(detail_res.responseText) } // 预览图 let imgs = [...detail_html.querySelectorAll(".img-gallery a")].map( item => item.getAttribute("href")) let imgs_blob = [] await asyncForEach(imgs, async (img) => { const response = await new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "get", url: img, headers: {"referer": `https://ec.sod.co.jp/prime/videos/?id=${vid}`}, responseType: "blob", onload: response => {resolve(response)}, onerror: response => {reject(response)}, }); }); //console.log("response:", response); const {response: blob} = response; console.log(blob); imgs_blob.push(blob) }) imgs = imgs_blob // 预览视频 let video = [] let ele_video = detail_html.querySelector(".videos_sampb a"); if (ele_video) { let video_url = `https://ec.sod.co.jp/prime/videos/${ele_video.getAttribute('href')}`; video.push({ src: video_url, type: 'video/mp4', label: `SOD`, res: `100` }) let video_request = {url: video_url} let video_res = await gmFetch(video_request).catch(err => {record_log(err); return;}) let video_html = parseResponse(video_res.responseText) let video_src = video_html.querySelector("#moviebox source").getAttribute("src") video.push({ src: `${video_src}?from=script`, type: 'video/mp4', label: `SOD`, res: `100` }) } return {imgs: imgs, video: video, source: "sod"} } let afesta = async() => { if (!multi_search && video_type !== "afesta" || !menu_value("menu_offcial")) { record_log(`Afesta Search: 跳过`) throw new Error('Afesta Search: 跳过'); } record_log(`Afesta Search: ${pid}`) const params = new URLSearchParams(); params.append("keyword", `${pid}`); params.append("header", "search"); let search_request = {url: `https://www.afesta.tv/vr/search.php`, method: `POST`, data: `keyword=${pid}&header=search`, headers: {"Content-Type": "application/x-www-form-urlencoded"}} let search_res = await gmFetch(search_request).catch(err => {record_log(err); return;}) let search_html = parseResponse(search_res.responseText) let ele_detail = Array.from(search_html.querySelectorAll('.faces-list a')).find(el => el.querySelector(`img`).getAttribute(`data-src`).indexOf(pid) != -1) if (!ele_detail) { record_log(`Afesta Search: 未找到`); throw new Error('Afesta Search: 未找到'); } let detail_url = ele_detail.getAttribute("href") record_log(`Afesta Search: 详情页 ${detail_url}`) let detail_request = {url: detail_url} let detail_res = await gmFetch(detail_request).catch(err => {record_log(err); return;}) let detail_html = parseResponse(detail_res.responseText) // 预览图 let imgs = [...detail_html.querySelectorAll(`.thumbs-grid li a`)] .map( item => item.getAttribute("href")) .map( item => { if (!item.startsWith(`http`)) { return new URL(item, detail_url).href } else { return item }}) // 预览视频 let video = [] return {imgs: imgs, video: video, source: "afesta"} } let javdb = async() => { if (!menu_value("menu_JavDB") || menu_value("menu_offcial")) { record_log(`JavDB Search: 跳过`) throw new Error('JavDB Search: 跳过'); } record_log(`JavDB Search: ${vid}`) let cookie = `over18=1`; let search_request = {url: `https://javdb.com/search?q=${vid}&f=all`, cookie: cookie} let search_res = await gmFetch(search_request).catch(err => {record_log(err); return;}) let search_html = parseResponse(search_res.responseText) let ele_detail = Array.from(search_html.querySelectorAll('.video-title strong')).find(el => el.textContent === vid) if (!ele_detail) { record_log(`JavDB Search: 未找到`); throw new Error('JavDB Search: 未找到'); } let detail_url = `https://javdb.com${ele_detail.closest("a").getAttribute("href")}` let detail_request = {url: detail_url, cookie: cookie} let detail_res = await gmFetch(detail_request).catch(err => {record_log(err); return;}) let detail_html = parseResponse(detail_res.responseText) // 预览图 let imgs = [...detail_html.querySelectorAll(".preview-images a[class=tile-item]")].map( item => item.getAttribute("href")) // 预览视频 let video = [] let ele_video = detail_html.querySelector(".preview-video-container") if (ele_video) { let video_src = ele_video.nextElementSibling.querySelector("source").getAttribute("src") video.push({ src: video_src, type: 'video/mp4', label: `JavDB`, res: `100` }) } return {imgs: imgs, video: video, source: "javdb"} } let javbus = async() => { if (!menu_value("menu_JavBus") || menu_value("menu_offcial")) { record_log(`JavBus Search: 跳过`) throw new Error('JavBus Search: 跳过'); } record_log(`JavBus Search: ${vid}`) let detail_request = {url: `https://www.javbus.com/${vid}`} let detail_res = await gmFetch(detail_request).catch(err => {record_log(err); return;}) let detail_html = parseResponse(detail_res.responseText) // 预览图 let imgs = [...detail_html.querySelectorAll("#sample-waterfall a")] .map( item => item.getAttribute("href")) .map(function(item) { if(item.startsWith("http")) { return item } else { video_type="sod" return `https://www.javbus.com${item}` } }) if (video_type==="sod") { let imgs_blob = [] await asyncForEach(imgs, async (img) => { const response = await new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "get", url: img, headers: {"referer": `https://www.javbus.com/${vid}`}, responseType: "blob", onload: response => {resolve(response)}, onerror: response => {reject(response)}, }); }); //console.log("response:", response); const {response: blob} = response; imgs_blob.push(blob) }) imgs = imgs_blob } // 预览视频 let video = [] return {imgs: imgs, video: video, source: "javbus"} } ga_inner.innerHTML = "正在搜索预览图..." Promise.allSettled([dmm(),dahlia(),faleno(),mgstage(),sod(),afesta(),javdb(),javbus()]).then(results=>{ ga_inner.innerHTML = "" results.forEach(r => { if (r.status == "rejected" && r.reason.stack.indexOf("跳过") == -1) { record_log(`Error Reason: ${r.reason.stack}`) } }) let p = results.find(result => result.status==="fulfilled") if (p) { source = p.value.source let imgs = p.value.imgs let video = p.value.video if (imgs.length !== 0) { imgs.forEach(insertImages) } if (video.length !==0) { play_box.setAttribute("style", "display:inline-block"); if (source === "sod") { if (menu_value("menu_jumpSOD")) { video = video.slice(0,1) outer_span.setAttribute("style", "display:block"); } else { video = video.slice(1) player.updateSrc(video) } } else { player.updateSrc(video) } // 点击弹出播放器 play_box.onclick = function (e) { e.preventDefault(); if (source === "sod" && menu_value("menu_jumpSOD")) { GM_openInTab(video[0].src, {active : true}) } else { video_player.setAttribute("style", "display:block"); $.fancybox.open({ src : '#x1080x-player', type : 'inline', opts : { smallBtn: false, touch: false, afterShow : function( instance, current ) { player.play(); }, afterClose : function( instance, current ) { player.pause(); } } }); } } } if (imgs.length === 0 && video.length === 0 ){ gallery_div.style.display = "none" } } }) //$.fancybox.defaults.loop = "true"; })();