MISSAV
https://missav.com/#xh
分享者: xiaohan231 (515)发布时间: 2024/09/11
修改:1、优化页面样式;by:xiaohan231-2024/08/25 修改:1、优化长按倍速播放功能;2、增加分辨率切换功能;by:xiaohan231-2024/08/24 修改:1、优化播放器样式;2、选择播放倍速后,点击屏幕不再恢复成正常;3、添加长按2倍速播放功能,想要设置成其他的可以在内容规则根据注释修改;by:xiaohan231-2024/08/21 修改:1、调用Plyr插件搭建网页播放器;2、设置播放器默认比例为16/9,以防止加载时播放器高度变动;3、优化播放器样式;by:xiaohan231-2024/08/20 修改:1、修复部分视频无法播放的bug;2、增加收藏关键词;3、视频不再采用第三方解析,改为调用原生播放器;4、添加视频封面;by:xiaohan231-2024/08/18 by:xiaohan231-2024/08/17
{ "articleStyle": 1, "concurrentRate": "20\/10000", "contentBlacklist": "", "customOrder": 20, "enableJs": true, "enabled": true, "enabledCookieJar": true, "header": "<js>\nheaders={\n \"User-Agent\": \"Mozilla\/5.0 (Linux; Android 10; K) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/127.0.0.0 Mobile Safari\/537.36 EdgA\/127.0.0.0\",\n \"Referer\": String(source.getKey()).replace(\/(.*\\\/\\\/[a-z0-9.-]+).*\/, '$1')\n}\nJSON.stringify(headers);\n<\/js>", "injectJs": "", "jsLib": "function get(tag,num) {\n sort = ['today_views','weekly_views','monthly_views','views','released_at','published_at','saved'];\n filters = ['','individual','multiple','chinese-subtitle'];\n filters1 = ['','individual','jav','uncensored-leak','uncensored','chinese-subtitle'];\n var e = eval(tag + '[' + num + ']');\n return e;\n}\nfunction Get(e) {\n const { java, source, cookie, cache } = this;\n var get = JSON.parse(source.getLoginHeader());\n return get[e];\n}\nfunction Map(e) {\n const { java, source, cookie, cache } = this;\n var infomap = source.getLoginInfoMap();\n var map = (infomap !== null && infomap.get(e)) ? infomap.get(e) : '';\n return String(map);\n}\nfunction formatSeconds(seconds) {\n var hours = Math.floor(seconds \/ 3600);\n var minutes = Math.floor((seconds % 3600) \/ 60);\n var secs = Math.floor(seconds % 60);\n\n var formattedHours = hours.toString().padStart(2, '0');\n var formattedMinutes = minutes.toString().padStart(2, '0');\n var formattedSeconds = secs.toString().padStart(2, '0');\n\n return `${formattedHours}:${formattedMinutes}:${formattedSeconds}`;\n}", "lastUpdateTime": 0, "loadWithBaseUrl": true, "loginCheckJs": "", "loginUi": "[\n { name: \" 查看当前 \", type: \"button\", action: \"look(0)\" },\n { name: \" 查看历史 \", type: \"button\", action: \"look(1)\" },\n { name: \" 恢复默认 \", type: \"button\", action: \"test(0)\" },\n\n {\n name: \" 💡 源 站 更 新 💡 \",\n type: \"button\",\n action: \"update()\"\n },\n\n { name: \" ༺ˇ»`ʚ 点击切换源站 ɞ´«ˇ༻ \", type: \"button\" },\n { name: \" ①国际网址✈️ \", type: \"button\", action: \"$(1)\"},\n { name: \" ②国内网址🐰 \", type: \"button\", action: \"$(2)\"},\n\n { name: \" ༺ˇ»`ʚ 点击切换分类 ɞ´«ˇ༻ \", type: \"button\" },\n { name: \" 类型标签 \", type: \"button\", action: \"o(0)\" },\n { name: \" 女优一览 \", type: \"button\", action: \"o(1)\" },\n\n { name: \" ༺ˇ»`ʚ 影片浏览排序 ɞ´«ˇ༻ \", type: \"button\" },\n { name: \" 今 日 \", type: \"button\", action: \"q(0)\" },\n { name: \" 本 周 \", type: \"button\", action: \"q(1)\" },\n { name: \" 本 月 \", type: \"button\", action: \"q(2)\" },\n { name: \" 全 部 \", type: \"button\", action: \"q(3)\" },\n { name: \" ༺ˇ»`ʚ 影片其他排序 ɞ´«ˇ༻ \", type: \"button\" },\n { name: \" 发行日期 \", type: \"button\", action: \"q(4)\" },\n { name: \" 最近更新 \", type: \"button\", action: \"q(5)\" },\n { name: \" 收藏数量 \", type: \"button\", action: \"q(6)\" },\n\n { name: \" ༺ˇ»`ʚ 分类影片过滤 ɞ´«ˇ༻ \", type: \"button\" },\n { name: \" 所 有 \", type: \"button\", action: \"r(0)\" },\n { name: \" 单 人 \", type: \"button\", action: \"r(1)\" },\n { name: \" 多 人 \", type: \"button\", action: \"r(2)\" },\n { name: \" 中 文 \", type: \"button\", action: \"r(3)\" },\n\n { name: \" ༺ˇ»`ʚ 搜索影片过滤 ɞ´«ˇ༻ \", type: \"button\" },\n { name: \" 所有影片 \", type: \"button\", action: \"s(0)\" },\n { name: \" 单人作品 \", type: \"button\", action: \"s(1)\" },\n { name: \" 日本AV \", type: \"button\", action: \"s(2)\" },\n { name: \" 无码流出 \", type: \"button\", action: \"s(3)\" },\n { name: \" 无码影片 \", type: \"button\", action: \"s(4)\" },\n { name: \" 中文字幕 \", type: \"button\", action: \"s(5)\" },\n\n { name: \" ༺ˇ»`ʚ 分类女优排序 ɞ´«ˇ༻ \", type: \"button\" },\n { name: \" 影片数量 \", type: \"button\", action: \"p(0)\" },\n { name: \" 出道时间 \", type: \"button\", action: \"p(1)\" },\n\n { name: \" ༺ˇ»`ʚ 女优加载过滤 ɞ´«ˇ༻ \", type: \"button\" },\n { name: \" 身 高 \", type: \"button\", action: \"login('【身高参数】' + n(2) + '[0]131-135 [1]136-140 [2]141-145 [3]146-150 [4]151-155 [5]156-160 [6]161-165 [7]166-170 [8]171-175 [9]176-180 [10]181-185 [11]186-190\\\\n\\\\n填写对应身高序号')\" },\n { name: \" 年 龄 \", type: \"button\", action: \"login('【年龄参数】' + n(2) + '[0]0-20 [1]20-30 [2]30-40\\\\n[3]40-50 [4]50-60 [5]60-99\\\\n\\\\n填写对应年龄序号')\" },\n { name: \" 罩 杯 \", type: \"button\", action: \"login('【罩杯参数】' + n(2) + '可选罩杯范围:A~Q\\\\n只能填写一个大写字母')\" },\n { name: \" 出 道 \", type: \"button\", action: \"login('【出道年份】' + n(2) + '填写年份,如:2024\\\\n只能填写一个')\" },\n { name: \"身高:\", type: \"text\" },\n { name: \"年龄:\", type: \"text\" },\n { name: \"罩杯:\", type: \"text\" },\n { name: \"出道:\", type: \"text\" },\n\n { name: \" ༺ˇ»`ʚ 女优加载页数 ɞ´«ˇ༻ \", type: \"button\", action: \"login('【加载页数】' + n(2) + '填写数字或范围,如:15或10-20')\" },\n { name: \"页数:\", type: \"text\" },\n\n { name: \" ༺ˇ»`ʚ 填写收藏词条 ɞ´«ˇ༻ \", type: \"button\", action: \"login('【收藏词条】' + n(2) + '填写搜索关键词\\\\n多个关键词用英文逗号”,“隔开')\" },\n { name: \"收藏:\", type: \"text\" },\n\n {\n name: \" 💡 源 站 打 印 💡 \",\n type: \"button\",\n action: \"test()\"\n }\n]", "loginUrl": "var fburl = 'https:\/\/missav.live';\noriginal = {\n 'o': 0,\n 'p': 0,\n 'q': 0,\n 'r': 0,\n 's': 0,\n 'url': 'https:\/\/missav.com',\n 'urls': [\n 'https:\/\/missav.com',\n 'https:\/\/missav.com'\n ]\n};\ntry {\n $$$ = JSON.parse(source.getLoginHeader());\n if ($$$ == null) {\n error;\n } else {\n '';\n };\n} catch (e) {\n $$$ = original;\n put($$$);\n}\nx = '⓪①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳㉑㉒㉓㉔㉕㉖㉗㉘㉙㉚';\nvar Headers = String(cache.get(java.md5Encode16(Get('url') + \"headers\")));\nvar Option = {\n \"method\": \"GET\",\n \"headers\": Headers\n};\nfunction test(e) {\n if (e == undefined) {\n return java.log('\\n' + JSON.stringify($$$['urls'], null, '\\t')) + login('【源站输出提示】' + n(2) + '源站已打印完毕,请到日志查看');\n }\n if (e == 0) {\n login('【初始化提示】' + n(2) + '已恢复默认设置');\n return put(original);\n }\n date1 = new Date().getTime();\n html = java.ajax($$$.urls[e]+'\/dm10\/cn');\n if(html.includes('no-js')){\n cookie.removeCookie(Get('url'));\n java.startBrowserAwait($$$.urls[e],\"验证\").body();\n date1 = new Date().getTime();\n html = java.ajax($$$.urls[e]+'\/dm10\/cn');\n }\n date2 = new Date().getTime();\n t = date2 - date1;\n time = t \/ 1000 + 's';\n c = String(html).indexOf('日本');\n logTime = '【' + name(e) + '】\\n┋┋\\n' + '解析时间:' + time;\n if (c == -1 || t > 5000) {\n return login('【访问失败提示】' + n(2) + '┏┅━┅━┅━┅━┅━┅━┅━┅━┅┓\\n┋┋\\n' + logTime + '\\n┋┋\\n♣️源站已失效(可能被墙)♣️\\n┋┋\\n请更新网址\/切换源站\/切换网络环境\\n┋┋' + '\\n┗┅━┅━┅━┅━┅━┅━┅━┅━┅┛');\n } else if (t < 1000) {\n return login('【网络环境优良】' + n(2) + '┏┅━┅━┅━┅━┅━┅━┅━┅━┅┓\\n┋┋\\n' + logTime + '\\n┋┋\\n❤️延迟低,推荐使用此站❤️\\n┋┋\\n网络环境优良,请继续保持状态\\n┋┋' + '\\n┗┅━┅━┅━┅━┅━┅━┅━┅━┅┛');\n } else if (t >= 1000 && t < 2000) {\n return login('【网络环境一般】' + n(2) + '┏┅━┅━┅━┅━┅━┅━┅━┅━┅┓\\n┋┋\\n' + logTime + '\\n┋┋\\n♦️延迟一般,勉强可使用♦️\\n┋┋\\n请切换其他源站或切换网络环境\\n┋┋' + '\\n┗┅━┅━┅━┅━┅━┅━┅━┅━┅┛');\n } else if (t >= 2000 && t < 5000) {\n return login('【网络环境堪忧】' + n(2) + '┏┅━┅━┅━┅━┅━┅━┅━┅━┅┓\\n┋┋\\n' + logTime + '\\n┋┋\\n♠延迟过高,不建议使用♠\\n┋┋\\n请切换其他源站或切换网络环境\\n┋┋' + '\\n┗┅━┅━┅━┅━┅━┅━┅━┅━┅┛');\n }\n}\nfunction put(data) {\n return source.putLoginHeader(JSON.stringify(data, null, '\\t'));\n}\nfunction update() {\n $$$['urls'].splice(original['urls'].length);\n time = new Date().getTime();\n html = java.webViewGetOverrideUrl(null, fburl + '?t=' + time, null, '');\n J = org.jsoup.Jsoup.parse(html);\n u = J.select('button');\n for (i in u) {\n host = eval(String(String(u[i].attr('onclick')).replace(\/^.*=\\s*\/,''))).replace(\/(.*\\\/\\\/[a-z0-9.-]+).*\/, '$1');\n if (String($$$['urls']).indexOf(host) === -1) {\n java.log('\\n✅已添加源站:\\n' + host);\n $$$['urls'].push(host);\n put($$$);\n }\n }\n return login('【源站更新提示】' + n(2) + '源站更新完毕,请到日志查看');\n}\nfunction name(e) {\n if (e == undefined) {\n e = 0;\n }\n return x[e] + $$$.urls[e];\n}\nfunction login(e) {\n if (e == undefined) {\n return;\n }\n java.longToast(e);\n}\nfunction n(e) {\n n = '\\n';\n for (m = 1; m < e; m++) {\n n = n + '\\n';\n }\n return n;\n}\nfunction k(e) {\n k = ' ';\n for (q = 1; q < e; q++) {\n k = k + ' ';\n }\n return k;\n}\nfunction l(e) {\n l = '';\n for (o = 1; o < e; o++) {\n l = l + '';\n }\n return l;\n}\nfunction look(e) {\n if (e == 0) {\n return login('【查看当前源站】\\n\\n┏┅━┅━┅━┅━┅━┅━┅━┅━┅┓\\n┋┋' + ('\\n ' + '📌' + name($$$.ci0)) + '\\n┋┋' + ('\\n' + '🗳订阅分类:' + typeO($$$.o)) + '\\n┋┋' + ('\\n' + '👩🎤女优排序:' + typeP($$$.p)) + '\\n┋┋' + ('\\n' + '📚影片排序:' + typeQ($$$.q)) + '\\n┋┋' + ('\\n' + '🔎分类过滤:' + typeR($$$.r)) + '\\n┋┋' + ('\\n' + '🔍搜索过滤:' + typeS($$$.s)) + '\\n┋┋' + '\\n┗┅━┅━┅━┅━┅━┅━┅━┅━┅┛');\n } else {\n return login('【查看历史接口】\\n\\n┏┅━┅━┅━┅━┅━┅━┅━┅━┅┓\\n┋┋' + ('\\n ci1:' + name($$$.ci1)) + '\\n┋┋' + ('\\n ci2:' + name($$$.ci2)) + '\\n┋┋' + ('\\n ci3:' + name($$$.ci3)) + '\\n┋┋' + '\\n┗┅━┅━┅━┅━┅━┅━┅━┅━┅┛');\n }\n}\nfunction $(e) {\n if (e == undefined) {\n e = result['序号:'];\n e = e > 0 ? e : '0';\n }\n if (\/^ci[123]$\/.test(e)) {\n eval('i=$$$.' + e);\n }\n if (\/\\D|^$\/.test(e) || e < 0 || e >= $$$['urls'].length) {\n return login('【源站错误提示】' + n(2) + '已选择的源站无效,请重新选择');\n }\n $$$['url'] = $$$['urls'][e];\n $$$['ci3'] = $$$['ci2'];\n $$$['ci2'] = $$$['ci1'];\n $$$['ci1'] = $$$['ci0'];\n $$$['ci0'] = e;\n put($$$);\n test(e);\n}\nO = ['主题标签','全部女优'];\nfunction typeO(e) {\n if (e == undefined) {\n e = 0;\n }\n return O[e];\n}\nfunction o(e) {\n if (o == undefined) {\n o = result.o;\n }\n if (e == $$$.o) {\n return login('【分类切换提示】' + n(2) + '已经选择此分类,无需更换');\n }\n login('【分类切换提示】' + n(2) + '已经切换到[' + typeO(e) + ']分类,请刷新分类');\n $$$.o = e;\n return put($$$);\n}\nP = ['影片数量','出道时间'];\nfunction typeP(e) {\n if (e == undefined) {\n e = 0;\n }\n return P[e];\n}\nfunction p(e) {\n if (p == undefined) {\n p = result.p;\n }\n if (e == $$$.p) {\n return login('【女优排序提示】' + n(2) + '已经选择此排序,无需更换');\n }\n login('【女优排序提示】' + n(2) + '已经切换到[' + typeP(e) + ']排序,请刷新分类');\n $$$.p = e;\n return put($$$);\n}\nQ = ['今日浏览','本周浏览','本月浏览','全部浏览','发行日期','最近更新','收藏数量'];\nfunction typeQ(e) {\n if (e == undefined) {\n e = 0;\n }\n return Q[e];\n}\nfunction q(e) {\n if (q == undefined) {\n q = result.q;\n }\n if (e == $$$.q) {\n return login('【切换影片排序】' + n(2) + '已经选择此排序,无需更换');\n }\n login('【切换影片排序】' + n(2) + '已经切换到[' + typeQ(e) + ']排序');\n $$$.q = e;\n return put($$$);\n}\nR = ['所有影片','单人作品','多人作品','中文字幕'];\nfunction typeR(e) {\n if (e == undefined) {\n e = 0;\n }\n return R[e];\n}\nfunction r(e) {\n if (r == undefined) {\n r = result.r;\n }\n if (e == $$$.r) {\n return login('【列表影片过滤】' + n(2) + '已经选择此过滤,无需更换');\n }\n login('【列表影片过滤】' + n(2) + '已经切换到[' + typeR(e) + ']过滤');\n $$$.r = e;\n return put($$$);\n}\nS = ['所有影片','单人作品','日本AV','无码流出','无码影片','中文字幕'];\nfunction typeS(e) {\n if (e == undefined) {\n e = 0;\n }\n return S[e];\n}\nfunction s(e) {\n if (r == undefined) {\n r = result.s;\n }\n if (e == $$$.s) {\n return login('【搜索影片过滤】' + n(2) + '已经选择此过滤,无需更换');\n }\n login('【搜索影片过滤】' + n(2) + '已经切换到[' + typeS(e) + ']过滤');\n $$$.s = e;\n return put($$$);\n}", "ruleArticles": ".thumbnail.group", "ruleContent": "<js>\n\/\/获取集数\nvar n = \/-chinese-subtitle\/.test(baseUrl) ? 2 : (\/-uncensored-leak\/.test(baseUrl) ? 1 : 0);\nvar names = ['原版视频', '无码流出', '中文字幕'];\nvar fhs = ['', '-uncensored-leak', '-chinese-subtitle'];\nvar list = [];\nURL = baseUrl.replace(\/-uncensored-leak|-chinese-subtitle\/,'');\nFH = String(java.getElements('[property=\"og:title\"]').attr('content')).replace(\/^(.*?)\\s.*\/, '$1');\nlist.push(URL);\nlist.push(URL+'-uncensored-leak');\nlist.push(URL+'-chinese-subtitle');\nvar url = '';\njishu = list.map(($, i)=>{\n var value = '',name = '',bt = '',fm = '',fh = '',lx = '';\n var style = ' style=\"display:none;\"';\n html = $ == baseUrl ? result : java.ajax($);\n J = org.jsoup.Jsoup.parse(html);\n if (i < 1 || String(J.select('[hreflang=\"zh-Hans\"]').attr('href')) !== list[0] || i < 1) {\n name = names[i];\n var Value = [];\n url = \/找不到页面\/.test(html) ? '' : eval(html.match(\/(eval.*video.*\\)\\))\/m)[1]);\n if (url !== '') {\n url1 = String(url).replace(\/\\\/[^\\\/]+\\\/[^\\\/]+$\/, '\/');\n res = String(java.ajax(String(url).replace(\/\\\/[^\\\/]+\\\/[^\\\/]+$\/, '\/playlist.m3u8')));\n sizes = res.match(\/RESOLUTION=\\d+x\\d+\/g).map(e => e.split('x')[1]);\n srcs = res.match(\/(.*\\\/video\\.m3u8)\/g);\n for (j in srcs) {\n Value.push({src:url1+srcs[j],size:sizes[j]});\n }\n Value.sort((a, b) => parseInt(b.size) - parseInt(a.size));\n value = JSON.stringify(Value);\n }\n bt = J.select('[property=\"og:title\"]').attr('content');\n fh = '🎬 番号:' + FH + fhs[i];\n lx = '📦 类型:' + String(\/找不到页面\/.test(html) ? '' : J.select('.text-secondary:contains(类型:)').text()).replace(\/类型:\/,'');\n fm = J.select('video').attr('data-poster');\n style = \/找不到页面\/.test(html) ? ' style=\"display:none;\"' : '';\n }\n return `<button onclick=\"jishu(this)\" value=${value} data-bt=\"${bt}\" data-fh=\"${fh}\" data-lx=\"${lx}\" data-fm=\"${fm}\"${style}><b>${name}<\/b><\/button>`;\n}).join('\\n');\n\nstyle = \/none.*none\/s.test(jishu) ? ' style=\"display:none;\"' : '';\njishu = `<div class=\"jishu\" data-n=\"${n}\"${style}>\\n<p>🎥 视频版本:‎<\/p>\\n<p>${jishu}<\/p>\\n<\/div>\\n`;\n\n\/\/返回json\nJSON.stringify({\n jishu: jishu\n})\n<\/js>\n<!DOCTYPE html>\n<html lang=\"zh-Hans\">\n<head>\n<title><\/title>\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no\">\n<link rel=\"stylesheet\" href=\"https:\/\/cdn.plyr.io\/3.6.12\/plyr.css\">\n<style>\n* {\n z-index: 0;\n margin: 0;\n padding: 0;\n}\n\nbody {\n margin: auto;\n background: #ccc;\n width: 100%;\n}\n\nbody>p:first-of-type {\n width: 100%;\n position: sticky;\n top: 0px;\n text-indent: 0px;\n height: 16px;\n font-size: 0.7rem;\n border-radius: 0px 0px 0px 0px;\n background: #000;\n color: #fff;\n white-space: nowrap;\n overflow: auto;\n z-index: 4;\n}\n\nvideo {\n visibility: hidden;\n}\n\n.video-container {\n position: relative;\n min-height: 56.25vw;\n z-index: 3;\n}\n\n#player {\n position: relative;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n}\n\n:root {\n --plyr-color-main: #00aaff;\/* 播放器主要颜色 *\/\n --plyr-control-color: #fff;\/* 播放器控件图标颜色 *\/\n --plyr-control-background: transparent;\/* 播放器控件背景颜色 *\/\n --plyr-video-background: transparent;\/* 视频背景颜色 *\/\n --plyr-range-fill-background: #0099ee;\/* 进度条已填充部分的颜色 *\/\n --plyr-range-thumb-background: #fff;\/* 进度条滑块的颜色 *\/\n}\n\n.plyr__control--overlaid {\n background: transparent;\n border: 0;\n border-radius: 100%;\n color: #fff;\n left: calc(50% - 30px);\n top: calc(50% - 45px);\n transform: none;\n width: 60px;\n height: 60px;\n padding: 0;\n z-index: 2;\n}\n\n.plyr__control--overlaid svg {\n width: 50px;\n height: 50px;\n left: calc(50% - 25px);\n top: calc(50% - 25px);\n transform: none;\n fill: #fff;\/* 大播放器控件图标颜色 *\/\n}\n\n.plyr--video .plyr__control.plyr__tab-focus,.plyr--video .plyr__control:hover,.plyr--video .plyr__control[aria-expanded=true] {\n background: transparent;\/* 播放器控件悬停\/点击背景颜色 *\/\n color: #00aaff;\/* 播放器控件悬停\/点击图标颜色 *\/\n}\n\n.plyr__controls .plyr__controls__item {\n margin-left: auto;\n margin: calc(var(--plyr-control-spacing,10px)\/4);\n}\n\n.plyr__time--duration {\n display: inline-block!important;\n}\n\n.plyr__time+.plyr__time:before {\n margin-right: 8px!important\n}\n\n@media (max-width: 640px) {\n .plyr__captions {\n margin-bottom:-8px\n }\n\n .plyr__progress__container {\n margin-right: 5px\n }\n\n .plyr__time {\n position: absolute;\n bottom: 29px;\n }\n\n .plyr__time--current {\n left: 108px\n }\n\n .plyr__time+.plyr__time:before {\n content: \"\"!important\n }\n\n .plyr__time--duration {\n right: 110px;\n }\n\n .plyr__volume {\n width: auto;\n max-width: 32px!important;\n min-width: 32px!important\n }\n\n input[id^=plyr-volume-] {\n display: none!important;\n }\n\n .plyr--airplay-supported [data-plyr=airplay],.plyr--captions-enabled [data-plyr=captions],.plyr--pip-supported [data-plyr=pip] {\n display: none!important;\n }\n}\n\n.all-info {\n position: absolute;\n background: #ccc;\/* 详情信息背景颜色 *\/\n margin: auto;\n width: 100%;\n height: auto;\n}\n\n.all-info>div {\n width: 100%;\n margin: auto;\n}\n\n.all-info>p {\n text-indent: 0px;\n}\n\n.all-info>div>p {\n width: 90%;\n margin: 5px 5%;\n outline: none;\n text-align: left;\n word-wrap: break-word;\n}\n\ndetails {\n width: 100%;\n height: auto;\n margin: auto;\n padding: 0;\n border-bottom: 0.5px solid #333;\n}\n\ndetails>img {\n width: 100%;\n}\n\ndetails[open] {\n border-bottom: none;\n}\n\nsummary {\n width: 90%;\n margin: 5px 3%;\n outline: none;\n line-height: 1.5;\n text-align: left;\n word-wrap: break-word;\n}\n\nsummary::-webkit-details-marker {\n display: none;\n}\n\nbutton {\n width: 29.5%;\n margin: 1.25%;\n padding: 5px;\n outline: none;\n border-radius: 8px;\n font-size: 0.7rem;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\nbutton.active {\n color: #166188;\n position: sticky;\n left: 0;\n right: 0;\n}\n<\/style>\n<\/head>\n<body>\n<p><\/p>\n<div class=\"video-container\">\n <video id=\"player\" playsinline controls preload=\"auto\" poster=\"https:\/\/qyyuapi.com\/img\/noposter.png\">\n <\/video>\n<\/div>\n<div class=\"all-info\">\n<details>\n <summary>\n <h3><\/h3>\n <\/summary>\n <img>\n<\/details>\n{{JSON.parse(result).jishu}}\n<div>\n <p>📆 发行:{{@css:.text-secondary:contains(发行日期:)@text##发行日期:|}}<\/p>\n <p><\/p>\n <p>👩🎤 女优:{{@css:.text-secondary:contains(女优:)@text##女优:}}<\/p>\n <p>👨🎤 男优:{{@css:.text-secondary:contains(男优:)@text##男优:}}<\/p>\n <p>🎦 片商:{{@css:.text-secondary:contains(发行商:)@text##发行商:}}<\/p>\n <p>🕵️♀️ 导演:{{@css:.text-secondary:contains(导演:)@text##导演:}}<\/p>\n <p>🔖 标签:{{@css:.text-secondary:contains(标籤:)@text##标籤:}}<\/p>\n <p>🏷 系列:{{@css:.text-secondary:contains(系列:)@text##系列:}}<\/p>\n <p><\/p>\n <p>✏️ 标题:{{@css:.text-secondary:contains(标题:)@text##标题:}}<\/p>\n <p>📋 简介:{{@@[property=\"og:description\"]@content##.*免费加入会员.*}}<\/p>\n<\/div>\n<\/div>\n\n<script src=\"https:\/\/cdn.plyr.io\/3.6.12\/plyr.js\"><\/script>\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/hls.js@latest\"><\/script>\n\n<script>\n\/\/ 选中标签\nfunction $(rule) {\n return document.querySelectorAll(rule);\n}\n\n\/\/ 删除选中标签的class\nfunction omit(items) {\n return Array.from(items, (item) => {\n item.className = \"\";\n });\n}\n\n\/\/ 选中标签的class增加active\nfunction active(items, index) {\n items[index].className = \"active\";\n}\n\n\/\/ 播放器实例\nlet player = null;\n\n\/\/ 获取视频URL并更新视频源\nfunction geturl() {\n let zyurl = $(\".jishu button.active\")[0].value;\n let img = $('img')[0];\n let bt = $(\".jishu button.active\")[0].dataset.bt;\n let fh = $(\".jishu button.active\")[0].dataset.fh;\n let lx = $(\".jishu button.active\")[0].dataset.lx;\n let fm = $(\".jishu button.active\")[0].dataset.fm;\n\n \/\/ 更新页面信息\n $(\"title\")[0].innerText = bt;\n $(\".all-info>details>summary>h3\")[0].innerText = bt;\n $(\".all-info>div>p\")[3].innerText = fh;\n $(\".all-info>div>p\")[10].innerText = lx;\n $(\".all-info>div>p\")[3].style = \/:\\s*$\/.test(fh) ? \"display:none;\" : \"\";\n $(\".all-info>div>p\")[10].style = \/:\\s*$\/.test(lx) ? \"display:none;\" : \"\";\n\n \/\/ 更新详情封面\n img.src = fm;\n\n \/\/ 更新视频封面\n $(\".video-container\")[0].style.background = `#000 url('${fm}') no-repeat center center \/ cover`;\n\n \/\/ 设置不同分辨率的视频源\n let sources = JSON.parse(zyurl);\n\n return { sources: sources };\n}\n\n\/\/ 初始化播放器\nfunction initializePlayer(sources) {\n const video = $('video')[0];\n const qualityOptions = sources.map(source => parseInt(source.size));\n\n \/\/ 立即重新初始化 Plyr 实例\n player = new Plyr(video, {\n controls: [\n 'play-large', \/\/ 大播放按钮\n 'rewind', \/\/ 倒退\n 'play', \/\/ 播放\n 'fast-forward', \/\/ 快进\n 'progress', \/\/ 进度条\n 'current-time', \/\/ 当前时间\n 'duration', \/\/ 总时长\n 'mute', \/\/ 静音\n 'volume', \/\/ 音量\n 'captions', \/\/ 字幕\n 'settings', \/\/ 设置\n 'pip', \/\/ 画中画\n 'airplay', \/\/ Airplay\n 'fullscreen' \/\/ 全屏\n ],\n settings: ['quality', 'speed'],\n quality: {\n default: qualityOptions[0],\n options: qualityOptions,\n forced: true,\n onChange: (newQuality) => {\n changeVideoQuality(newQuality, sources);\n }\n },\n fullscreen: {\n enabled: true,\n fallback: true,\n iosNative: true,\n container: null,\n },\n speed: {\n selected: 1, \/\/ 设置默认播放倍数\n options: [0.25, 0.5, 1, 1.5, 2],\n },\n i18n: {\n restart: '重新开始',\n rewind: '倒退 {seektime} 秒',\n play: '播放',\n pause: '暂停',\n fastForward: '快进 {seektime} 秒',\n seek: '进度',\n seekLabel: '{currentTime} \/ {duration}',\n played: '播放',\n buffered: '缓冲',\n currentTime: '当前时间',\n duration: '持续时间',\n volume: '音量',\n mute: '静音',\n unmute: '取消静音',\n enableCaptions: '启用字幕',\n disableCaptions: '禁用字幕',\n enterFullscreen: '进入全屏',\n exitFullscreen: '退出全屏',\n frameTitle: '播放器',\n captions: '字幕',\n settings: '设置',\n speed: '速度',\n normal: '正常',\n quality: '画质',\n qualityLabel: {\n 0: '自动',\n },\n pip: '画中画',\n loop: '循环',\n start: '开始',\n end: '结束',\n all: '全部',\n reset: '重置',\n disabled: '禁用',\n advertisement: '广告'\n },\n keyboard: {\n focused: true,\n global: true,\n },\n tooltips: {\n controls: true,\n seek: true\n },\n captions: {\n active: true,\n update: true,\n language: 'auto',\n },\n });\n\n player.on('ready', () => {\n video.style.visibility = 'visible';\n\n \/\/ 添加长按倍速播放功能\n let longPressTimeout = null;\n let initialSpeed = 1;\n let isLongPress = false;\n const controls = document.querySelector('.plyr__controls');\n const overlaid = document.querySelector('.plyr__control--overlaid');\n\n const startLongPress = (e) => {\n e.stopPropagation();\n initialSpeed = player.speed;\n longPressTimeout = setTimeout(() => {\n setTimeout(() => {\n controls.style.display = 'none';\n overlaid.style.display = 'none';\n }, 1000);\n isLongPress = true;\n player.speed = 2; \/\/ 长按时设置2倍速播放\n }, 500);\n };\n\n const endLongPress = (e) => {\n e.stopPropagation();\n clearTimeout(longPressTimeout);\n if (isLongPress) {\n player.speed = initialSpeed;\n isLongPress = false;\n setTimeout(() => {\n controls.style.display = 'flex';\n overlaid.style.display = 'flex';\n }, 2000);\n }\n };\n\n \/\/ 监听播放器区域的pointerdown和pointerup事件\n const playerContainer = document.querySelector('.plyr__video-wrapper');\n\n playerContainer.addEventListener('pointerdown', startLongPress, true);\n playerContainer.addEventListener('pointerup', endLongPress, true);\n playerContainer.addEventListener('pointerleave', endLongPress, true);\n\n \/\/ 处理全屏模式下的特殊情况\n document.addEventListener('fullscreenchange', () => {\n if (!document.fullscreenElement) {\n endLongPress();\n }\n });\n });\n}\n\n\/\/ 切换视频质量的函数\nfunction changeVideoQuality(quality, sources) {\n const video = $('video')[0];\n const selectedSource = sources.find(source => source.size === quality.toString());\n const currentTime = video.currentTime;\n const wasPlaying = !video.paused;\n\n if (wasPlaying) {\n $(\".video-container\")[0].style.background = '#000';\n }\n $(\"body>p\")[0].innerText = selectedSource.src;\n\n if (selectedSource) {\n if (Hls.isSupported() && selectedSource.src.endsWith('.m3u8')) {\n const hls = new Hls();\n hls.loadSource(selectedSource.src);\n hls.attachMedia(video);\n hls.on(Hls.Events.MANIFEST_PARSED, () => {\n video.currentTime = currentTime;\n if (wasPlaying) {\n video.play();\n }\n });\n } else {\n video.pause();\n video.src = selectedSource.src;\n video.load();\n video.currentTime = currentTime;\n if (wasPlaying) {\n video.play();\n }\n }\n }\n}\n\n\/\/ 点击集数按钮时调用的函数\nfunction jishu(item) {\n if (player && typeof player.destroy === 'function') {\n player.destroy();\n player = null;\n }\n omit($('.jishu button.active'));\n item.className = \"active\";\n const { sources } = geturl();\n initializePlayer(sources);\n}\n\n\/\/ 页面加载时初始化播放器\n(() => {\n let n = $(\".jishu\")[0].dataset.n;\n active($('.jishu button'), n);\n const { sources } = geturl();\n initializePlayer(sources);\n})();\n<\/script>\n<\/body>\n<\/html>\n@js:result\n.replace(\/:\\s*\/g,':')\n.replace(\/<p>(.+):<\\\/p>\/gm, '<p style=\"display:none;\">$1:<\/p>')", "ruleDescription": "", "ruleImage": "img@data-src", "ruleLink": "a.0@href", "ruleNextPage": "page", "rulePubDate": "⌚️ {{@@.right-1@text}} 📦 {{@@.left-1@text}}\n@js:result.replace(\/📦\\s*$\/,'')", "ruleTitle": ".text-secondary@text", "singleUrl": false, "sortUrl": "@js:\neval(String(source.loginUrl));\nvar exploreUrl = [];\nvar Sort = `{{get('sort',Get('q'))}}`;\nvar Filters = `{{get('filters',Get('r'))}}`;\nvar Filters1 = `{{get('filters1',Get('s'))}}`;\nfunction explore(e, f, g) {\n if (g=='类别') {\n style = `${e}::${f}\\n`;\n } else if (g=='收藏') {\n style = `${e}::@js:\\`${f}\\`\\n`;\n } else if (g=='分类') {\n style = `${e}::@js:\\`${f}?page={{page}}&filters=${Filters}&sort=${Sort}\\`\\n`;\n } else if (g=='日本') {\n style = `${e}::@js:\\`${f}?page={{page}}&filters=${Filters}\\`\\n`;\n } else {\/\/女优\n style = `${e}::@js:\\`${f}?page={{page}}&filters=${Filters}&sort=${Sort}\\`\\n`;\n }\n return style;\n}\n\nsc = Map('收藏:');\nscs = sc !== '' ? sc.split(\",\") : [];\nif (scs.length > 0) {\n scs.forEach((sc) => {\n let scHref = `{{Get('url')}}\/cn\/search\/${sc}?page={{page}}&filters=${Filters1}&sort=${Sort}`;\n exploreUrl.push(explore(sc, scHref, '收藏'));\n });\n}\n\nhtml = java.ajax(Get('url')+'\/dm10\/cn');\nif(String(html).includes('no-js')){\n cookie.removeCookie(Get('url'));\n java.startBrowserAwait(Get('url'),'验证');\n}\n\nJ = org.jsoup.Jsoup.parse(html);\n\nif (Get('o') == 0) {\n java.toast(\"正在获取分类标签数据,请耐心等待!\")\n gcs = J.select('.right-0.mt-2.w-56 span')[7].select('a');\n exploreUrl.push(explore('中文字幕', `{{Get('url')}}\/dm265\/cn\/chinese-subtitle?page={{page}}&filters=${Filters}&sort=${Sort}`, '分类'));\n exploreUrl.push(explore('国产▶', null, '类别'));\n for (i in gcs) {\n exploreUrl.push(explore(gcs[i].text(), `{{Get('url')}}${String(gcs[i].attr('href')).replace(\/.*\\\/\\\/[a-z0-9.-]+\/, '')}`, '分类'));\n }\n rbs = J.select('.right-0.mt-2.w-56 span')[1].select('a');\n exploreUrl.push(explore('日本▶', null, '类别'));\n for (i in rbs) {\n if (i < 3 || i > 6) {\n exploreUrl.push(explore(rbs[i].text(), `{{Get('url')}}${String(rbs[i].attr('href')).replace(\/.*\\\/\\\/[a-z0-9.-]+\/, '')}`, '日本'));\n }\n }\n srs = J.select('.right-0.mt-2.w-56 span')[3].select('a');\n exploreUrl.push(explore('素人▶', null, '类别'));\n for (i in srs) {\n exploreUrl.push(explore(srs[i].text(), `{{Get('url')}}${String(srs[i].attr('href')).replace(\/.*\\\/\\\/[a-z0-9.-]+\/, '')}`, '分类'));\n }\n wms = J.select('.right-0.mt-2.w-56 span')[5].select('a');\n exploreUrl.push(explore('无码▶', null, '类别'));\n for (i in wms) {\n exploreUrl.push(explore(wms[i].text(), `{{Get('url')}}${String(wms[i].attr('href')).replace(\/.*\\\/\\\/[a-z0-9.-]+\/, '')}`, '分类'));\n }\n}\n\nif (Get('o') == 0) {\n exploreUrl.push(explore('标签▶', null, '类别'));\n J0 = org.jsoup.Jsoup.parse(java.ajax(Get('url')+'\/cn\/genres'));\n Page = String(J0.select('#price-currency')[0].text()).match(\/(\\d+)\/)[1];\n var murl = [];\n for (i = 1; i <= Page; i++) {\n murl.push(Get('url')+'\/cn\/genres?page='+i); \n }\n htmls = java.ajaxAll(murl);\n for (let i = 0; i < htmls.length; i++) {\n let models = org.jsoup.Jsoup.parse(htmls[i].body()).select('.gap-4 div');\n models.forEach((model) => {\n let modelName = model.select('.text-nord13').text();\n let modelSpanText = model.select('.text-nord10').text();\n let modelVideosCount = String(modelSpanText).replace(\/(\\d+).*$\/, '$1');\n let modelHref = `{{Get('url')}}${String(model.select('a').attr('href')).replace(\/.*\\\/\\\/[a-z0-9.-]+\/, '')}`;\n exploreUrl.push(explore(`${modelName}(${modelVideosCount})`, modelHref, '分类'));\n });\n }\n}\n\nnsort = ['videos','debut'];\nNsort = \/\\d+\/.test(Map('出道:')) ? 'debut' : nsort[Get('p')]\nheight = ['131-135', '136-140', '141-145', '146-150', '151-155', '156-160', '161-165', '166-170', '171-175', '176-180', '181-185', '186-190'];\nage = ['0-20','20-30','30-40','40-50','50-60','60-99'];\nHeight= \/\\d+\/.test(Map('身高:')) ? height[Map('身高:')] : '';\nAge= \/\\d+\/.test(Map('年龄:')) ? age[Map('年龄:')] : '';\nif (Get('o') == 1) {\n java.toast(\"正在获取女优数据,请耐心等待!\");\n Fpage = \/-\/.test(Map('页数:')) ? Map('页数:').match(\/(\\d+)\/g)[0] : '1';\n Lpage = \/-\/.test(Map('页数:')) ? Map('页数:').match(\/(\\d+)\/g)[1] : (\/\\d+\/.test(Map('页数:')) ? Map('页数:') : '5');\n var murl = [];\n for (let i = Fpage; i <= Lpage; i++) {\n murl.push(Get('url')+'\/cn\/actresses?sort='+Nsort+'&height='+Height+'&cup='+Map('罩杯:')+'&age='+Age+'&debut='+Map('出道:')+'&page='+i);\n }\n htmls = java.ajaxAll(murl);\n for (let i = 0; i < htmls.length; i++) {\n let models = org.jsoup.Jsoup.parse(htmls[i].body()).select('.max-w-full .space-y-4');\n models.forEach((model) => {\n let modelName = model.select('h4').text();\n let modelP0Text = model.select('p')[0].text();\n let modelVideosCount = String(modelP0Text).replace(\/(\\d+).*$\/, '$1');\n let modelP1Text = model.select('p')[1].text();\n let modelDebutYear = String(modelP1Text).replace(\/(\\d+).*$\/, '$1');\n let modelHref = `{{Get('url')}}${String(model.select('a').attr('href')).replace(\/.*\\\/\\\/[a-z0-9.-]+\/, '')}`;\n exploreUrl.push(explore(`${modelName}(${modelVideosCount} • ${modelDebutYear})`, modelHref, '女优'));\n });\n }\n}\n\n`变量搜索::@js:\\`{{Get('url')}}\/cn\/search\/{{v=source.getVariable();if(\/^\\s*$\/.test(v)||v==null)source.setVariable('秘密');source.getVariable()}}?page={{page}}&filters=${Filters1}&sort=${Sort}\\`\\n\n${exploreUrl.join('\\n')}`", "sourceComment": "修改:1、优化页面样式;by:xiaohan231-2024\/08\/25\n\n修改:1、优化长按倍速播放功能;2、增加分辨率切换功能;by:xiaohan231-2024\/08\/24\n\n修改:1、优化播放器样式;2、选择播放倍速后,点击屏幕不再恢复成正常;3、添加长按2倍速播放功能,想要设置成其他的可以在内容规则根据注释修改;by:xiaohan231-2024\/08\/21\n\n修改:1、调用Plyr插件搭建网页播放器;2、设置播放器默认比例为16\/9,以防止加载时播放器高度变动;3、优化播放器样式;by:xiaohan231-2024\/08\/20\n\n修改:1、修复部分视频无法播放的bug;2、增加收藏关键词;3、视频不再采用第三方解析,改为调用原生播放器;4、添加视频封面;by:xiaohan231-2024\/08\/18\n\nby:xiaohan231-2024\/08\/17", "sourceGroup": "🔭 其他,📽 视频", "sourceIcon": "https:\/\/krseoul.imgtbl.com\/i\/2024\/08\/17\/66bfb74a9b088.png", "sourceName": "MISSAV", "sourceUrl": "https:\/\/missav.com\/#xh", "style": "" }