Jable.tv
https://jable.tv/#xh
分享者: xiaohan231 (515)发布时间: 2024/09/11
修改:1、优化页面样式;by:xiaohan231-2024/08/25 修改:1、优化长按倍速播放功能;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、增加收藏关键词;2、视频不再采用第三方解析,改为调用原生播放器;3、添加视频封面;by:xiaohan231-2024/08/18 修改:1、优化女优信息获取;2、优化内容规则;by:xiaohan231-2024/08/17 修改:1、增加源站更新切换;2、优化分类获取;3、更换视频解析接口;by:xiaohan231-2024/08/16 by:xiaohan231-2024/08/15
{ "articleStyle": 1, "concurrentRate": "20\/10000", "contentBlacklist": "", "customOrder": 19, "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 = ['post_date_and_popularity','post_date','video_viewed','most_favourited'];\n sort1 = ['','post_date_and_popularity','post_date','video_viewed','most_favourited'];\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}", "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\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 { name: \" 最高收藏 \", type: \"button\", action: \"r(4)\" },\n { name: \" \", type: \"button\" },\n\n { name: \" ༺ˇ»`ʚ 分类女优排序 ɞ´«ˇ༻ \", type: \"button\" },\n { name: \" 热 度 \", type: \"button\", action: \"p(0)\" },\n { name: \" 名 字 \", type: \"button\", action: \"p(1)\" },\n { name: \" 更 新 \", type: \"button\", action: \"p(2)\" },\n { name: \" 数 量 \", type: \"button\", action: \"p(3)\" },\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:\/\/alldayj.com';\noriginal = {\n 'o': 0,\n 'p': 0,\n 'q': 0,\n 'r': 0,\n 'url': 'https:\/\/jable.tv',\n 'urls': [\n 'https:\/\/jable.tv',\n 'https:\/\/jable.tv'\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]);\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]);\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('.col-md-8 a');\n for (i in u) {\n host = String(u[i].attr('href'));\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┗┅━┅━┅━┅━┅━┅━┅━┅━┅┛');\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}", "ruleArticles": ".mb-e-20", "ruleContent": "<js>\n\/\/获取集数\nvar n = 0;\nvar names = ['原版视频'];\nvar list = [];\nURL = baseUrl;\nlist.push(URL);\njishu = list.map(($, i)=>{\n var value = '',name = '',bt = '',fm = '';\n html = $ == baseUrl ? result : java.ajax($);\n J = org.jsoup.Jsoup.parse(html);\n name = names[i];\n var Value = [];\n url = html.match(\/hlsUrl\\s*=\\s*'(.*?)'\/)[1];\n Value.push({src:url,size:'0'});\n value = JSON.stringify(Value);\n bt = J.select('h4')[0].text();\n fm = J.select('video')[0].attr('poster');\n return `<button onclick=\"jishu(this)\" value=${value} data-bt=\"${bt}\" data-fm=\"${fm}\"><b>${name}<\/b><\/button>`;\n}).join('\\n');\n\nstyle = ' 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>{{src.match(\/hlsUrl\\s*=\\s*'(.*?)'\/)[1]}}<\/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>{{@@h4.0@text}}<\/h3>\n <\/summary>\n <img src={{@@video@poster}}>\n<\/details>\n{{JSON.parse(result).jishu}}\n<div>\n <p>📆 更新:{{@@.mr-3.0@text}}<\/p>\n <p>🎥 播放:{{@@.mr-3.1@text##\\s}}<\/p>\n <p>❤ 收藏:{{@@.count@text}}<\/p>\n <p>👩🎤 女优:{{@@.rounded-circle@title}}<\/p>\n <p>📦 主题:{{@@.tags.h6-md@text##•.*$}}<\/p>\n <p>🔖 标签:{{@@.tags.h6-md@text##^.*•}}<\/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 fm = $(\".jishu button.active\")[0].dataset.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>", "ruleDescription": "", "ruleImage": "img@data-src", "ruleLink": "a.0@href", "ruleNextPage": "page", "rulePubDate": "⌚️ {{@@.label@text}} 🎥 {{@@.sub-title@html}}\n@js:\nresult.replace(\/<p[\\s\\S]*?<\\\/svg>|<\\\/p>|\\n\/gm,'').replace(\/<svg[\\s\\S]*?<\\\/svg>\/m,' ❤ ').replace(\/(\\d)\\s+(\\d)\/g,'$1$2')", "ruleTitle": ".title@text", "singleUrl": false, "sortUrl": "@js:\neval(String(source.loginUrl));\nvar exploreUrl = [];\nvar Sort = `{{get('sort',Get('q'))}}`;\nvar Sort1 = `{{get('sort1',Get('r'))}}`;\nfunction explore(e, f, g) {\n if (g=='收藏') {\n style = `${e}::@js:\\`${f}\\`\\n`;\n } else if (g=='主题') {\n style = `${e}::@js:\\`${f}?mode=async&function=get_block&block_id=list_videos_common_videos_list&sort_by=${Sort}&from={{page}}&_={{new Date().getTime()}}\\`\\n`;\n } else if (g=='标签') {\n style = `${e}::@js:\\`${f}?mode=async&function=get_block&block_id=list_videos_common_videos_list&sort_by=${Sort}&from={{page}}&_={{new Date().getTime()}}\\`\\n`;\n } else {\/\/女优\n style = `${e}::@js:\\`${f}?mode=async&function=get_block&block_id=list_videos_common_videos_list&sort_by=${Sort}&from={{page}}&_={{new Date().getTime()}}\\`\\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')}}\/search\/${sc}\/?mode=async&function=get_block&block_id=list_videos_videos_list_search_result&q=${sc}&sort_by=${Sort1}&from={{page}}&_={{new Date().getTime()}}`;\n exploreUrl.push(explore(sc, scHref, '收藏'));\n });\n}\n\nhtml = java.ajax(Get('url')+'\/categories\/');\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 categories = J.select('.pb-e-lg-40 a');\n for (i in categories) {\n exploreUrl.push(explore(categories[i].select('h4').text()+'('+String(categories[i].select('span').text()).replace(\/(\\d+).*$\/, '$1')+')', `{{Get('url')}}${String(categories[i].attr('href')).replace(\/.*\\\/\\\/[a-z0-9.-]+\/, '')}`, '主题'));\n }\n tags = J.select('.gutter-20.pb-3 a');\n for (i in tags) {\n exploreUrl.push(explore(tags[i].text(), `{{Get('url')}}${String(tags[i].attr('href')).replace(\/.*\\\/\\\/[a-z0-9.-]+\/, '')}`, '标签'));\n }\n}\n\nnsort = ['avg_videos_popularity','title','last_content_date','total_videos'];\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')+'\/models\/?mode=async&function=get_block&block_id=list_models_models_list&sort_by='+nsort[Get('p')]+'&from='+i+'&_='+(new Date().getTime())); \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('.horizontal-img-box');\n models.forEach((model) => {\n let modelName = model.select('.title').text();\n let modelSpanText = model.select('span').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\n`变量搜索::@js:\\`{{Get('url')}}\/search\/{{v=source.getVariable();if(\/^\\s*$\/.test(v)||v==null)source.setVariable('秘密');source.getVariable()}}\/?mode=async&function=get_block&block_id=list_videos_videos_list_search_result&q=${source.getVariable()}&sort_by=${Sort1}&from={{page}}&_={{new Date().getTime()}}\\`\\n\n${exploreUrl.join('\\n')}`", "sourceComment": "修改:1、优化页面样式;by:xiaohan231-2024\/08\/25\n\n修改:1、优化长按倍速播放功能;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、增加收藏关键词;2、视频不再采用第三方解析,改为调用原生播放器;3、添加视频封面;by:xiaohan231-2024\/08\/18\n\n修改:1、优化女优信息获取;2、优化内容规则;by:xiaohan231-2024\/08\/17\n\n修改:1、增加源站更新切换;2、优化分类获取;3、更换视频解析接口;by:xiaohan231-2024\/08\/16\n\nby:xiaohan231-2024\/08\/15", "sourceGroup": "🔭 其他,📽 视频", "sourceIcon": "https:\/\/krseoul.imgtbl.com\/i\/2024\/08\/17\/66bfb45e25be1.png", "sourceName": "Jable.tv", "sourceUrl": "https:\/\/jable.tv\/#xh", "style": "" }