├── .gitattributes ├── Forward ├── ForwardWidgets.png ├── JS │ └── Move_list.js ├── Widgets.fwd └── ForwardWidgets.fwd ├── XPTV ├── VOD │ ├── YouTube.json │ └── Live.json ├── Alist │ └── Alist.json ├── JS │ ├── tianyiso.js │ ├── harunasan.js │ ├── baipiao.js │ ├── seedhub.js │ ├── liuqu.js │ ├── aomi.js │ ├── texiafan.js │ ├── shandian.js │ ├── age.js │ ├── huban.js │ ├── star2.js │ ├── EXPORNTOONS.js │ ├── wogg.js │ ├── koreapornmovie.js │ ├── xzys.js │ ├── avdb.js │ ├── ole.js │ ├── yunpanres.js │ ├── ystt.js │ ├── kbjfan.js │ ├── mucpan.js │ ├── hohoj.js │ ├── anime1.js │ ├── hjkk.js │ ├── apple.js │ ├── yunpan8.js │ ├── madou.js │ ├── SpankBang.js │ ├── wobg.js │ ├── 91jav.js │ ├── ouge.js │ ├── xhamster.js │ ├── taiav.js │ ├── nanfeng.js │ ├── guanying.js │ ├── pandatv.js │ ├── rou.js │ ├── jable.js │ ├── ppp.js │ ├── twivideo.js │ ├── sgsd.js │ ├── uaa.js │ ├── pornhub.js │ ├── leijing.js │ ├── 4kav.js │ └── jpyy.js └── CMS │ └── AV.json ├── LICENSE ├── SteveWatch ├── CMS.json └── AV.json └── .github └── workflows └── Update-ForwardWidgets-JS.yml /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /Forward/ForwardWidgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sooyaaabo/VOD-CMS-Widgets/HEAD/Forward/ForwardWidgets.png -------------------------------------------------------------------------------- /Forward/JS/Move_list.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/quantumultxx/ForwardWidgets/main/Widgets/Move_list.js 2 | 404: Not Found -------------------------------------------------------------------------------- /XPTV/VOD/YouTube.json: -------------------------------------------------------------------------------- 1 | { 2 | "sites": [ 3 | { 4 | "name": "Live-YouTube", 5 | "type": 3, 6 | "api": "csp_youtube", 7 | "ext": "https://gist.githubusercontent.com/Yswag/98b86b68755f698e2f601962f76c036a/raw/you.js" 8 | } 9 | ] 10 | } -------------------------------------------------------------------------------- /XPTV/Alist/Alist.json: -------------------------------------------------------------------------------- 1 | { 2 | "sites": [ 3 | { 4 | "name": "AList-TVBox", 5 | "type": 3, 6 | "api": "csp_TvBox", 7 | "ext": "https://raw.githubusercontent.com/netcookies/xptv-extensions/main/alist_tvbox.js" 8 | }, 9 | { 10 | "name": "AList-小雅", 11 | "type": 3, 12 | "api": "csp_xiaoya", 13 | "ext": "https://raw.githubusercontent.com/kingreevice/my_xptv/main/js/alist_xiaoya.js" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /XPTV/VOD/Live.json: -------------------------------------------------------------------------------- 1 | { 2 | "sites": [ 3 | { 4 | "name": "Live-BiliLive", 5 | "type": 3, 6 | "api": "csp_bililive", 7 | "ext": "https://raw.githubusercontent.com/Yswag/xptv-extensions/main/js/bililive.js" 8 | }, 9 | { 10 | "name": "Live-斗鱼", 11 | "type": 3, 12 | "api": "csp_douyu", 13 | "ext": "https://raw.githubusercontent.com/Yswag/xptv-extensions/main/js/douyu.js" 14 | }, 15 | { 16 | "name": "Live-虎牙", 17 | "type": 3, 18 | "api": "csp_huya", 19 | "ext": "https://raw.githubusercontent.com/Yswag/xptv-extensions/main/js/huya.js" 20 | }, 21 | { 22 | "name": "Live-LemonLive", 23 | "type": 3, 24 | "api": "csp_nmlive", 25 | "ext": "https://raw.githubusercontent.com/Yswag/xptv-extensions/main/js/nmlive.js" 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 sooyaaabo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /SteveWatch/CMS.json: -------------------------------------------------------------------------------- 1 | { 2 | "sites": [ 3 | { 4 | "name": "素白白", 5 | "type": 3, 6 | "api": "SW_SBB", 7 | "ext": "SW_SBB" 8 | }, 9 | { 10 | "name": "修罗影视", 11 | "type": 3, 12 | "api": "SW_BDYS", 13 | "ext": "SW_BDYS" 14 | }, 15 | { 16 | "name": "在线之家", 17 | "type": 3, 18 | "api": "SW_ZXZJ", 19 | "ext": "SW_ZXZJ" 20 | }, 21 | { 22 | "name": "欧乐🪜", 23 | "type": 3, 24 | "api": "SW_OLE", 25 | "ext": "SW_OLE" 26 | }, 27 | { 28 | "name": "ギリギリ动漫", 29 | "type": 3, 30 | "api": "SW_DMZF", 31 | "ext": "SW_DMZF" 32 | }, 33 | { 34 | "name": "韩剧看看", 35 | "type": 3, 36 | "api": "SW_HJKK", 37 | "ext": "SW_HJKK" 38 | }, 39 | { 40 | "name": "4K资源", 41 | "type": 3, 42 | "api": "SW_FKAV", 43 | "ext": "SW_FKAV" 44 | }, 45 | { 46 | "name": "低端影视", 47 | "type": 3, 48 | "api": "SW_DDYS", 49 | "ext": "SW_DDYS" 50 | } 51 | ] 52 | } -------------------------------------------------------------------------------- /XPTV/JS/tianyiso.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://gist.githubusercontent.com/occupy-pluto/874d9b180bcaff91e2dac06d38ed8474/raw/tianyiso.js 2 | const cheerio = createCheerio() 3 | const CryptoJS = createCryptoJS() 4 | const UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" 5 | 6 | const headers = { 7 | 'Referer': 'https://www.tianyiso.com/', 8 | 'Origin': 'https://www.tianyiso.com', 9 | 'User-Agent': UA, 10 | } 11 | 12 | const appConfig = { 13 | ver: 1, 14 | title: "天逸搜", 15 | site: "https://www.tianyiso.com", 16 | tabs: [{ 17 | name: '只有搜索功能', 18 | ext: { 19 | url: '/' 20 | }, 21 | }] 22 | } 23 | 24 | async function getConfig() { 25 | return jsonify(appConfig) 26 | } 27 | 28 | async function getCards(ext) { 29 | ext = argsify(ext) 30 | let cards = [] 31 | return jsonify({ 32 | list: cards, 33 | }) 34 | } 35 | 36 | async function getTracks(ext) { 37 | const { url } = argsify(ext) 38 | const { data } = await $fetch.get(url, { 39 | headers 40 | }) 41 | let pan = data.match(/"(https:\/\/cloud\.189\.cn\/t\/.*)",/)[1] 42 | return jsonify({ 43 | list: [{ 44 | title: '在线', 45 | tracks: [{ 46 | name: '网盘', 47 | pan, 48 | }] 49 | }] 50 | }) 51 | } 52 | 53 | async function getPlayinfo(ext) { 54 | return jsonify({ 55 | urls: [], 56 | }) 57 | } 58 | 59 | async function search(ext) { 60 | ext = argsify(ext) 61 | let cards = []; 62 | 63 | let text = encodeURIComponent(ext.text) 64 | let page = ext.page || 1 65 | if (page > 1) { 66 | return jsonify({ 67 | list: cards, 68 | }) 69 | } 70 | 71 | const url = appConfig.site + `/search?k=${text}` 72 | const { data } = await $fetch.get(url, { 73 | headers 74 | }) 75 | 76 | const $ = cheerio.load(data) 77 | $('a').each((_, each) => { 78 | const path = $(each).attr('href') ?? '' 79 | if (path.startsWith('/s/')) { 80 | cards.push({ 81 | vod_id: path, 82 | vod_name: $(each).find('template').first().text().trim(), 83 | vod_pic: '', 84 | vod_remarks: '', 85 | ext: { 86 | url: appConfig.site + path, 87 | }, 88 | }) 89 | } 90 | }) 91 | 92 | return jsonify({ 93 | list: cards, 94 | }) 95 | } -------------------------------------------------------------------------------- /.github/workflows/Update-ForwardWidgets-JS.yml: -------------------------------------------------------------------------------- 1 | # 2025-07-21 09:00 2 | 3 | name: Update ForwardWidgets JS Files 4 | 5 | on: 6 | workflow_dispatch: 7 | schedule: 8 | - cron: "0 */2 * * *" 9 | 10 | permissions: 11 | actions: write 12 | contents: write 13 | 14 | jobs: 15 | download-js: 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - name: Checkout repository 20 | uses: actions/checkout@v3 21 | with: 22 | repository: sooyaaabo/VOD-CMS-Widgets 23 | path: VOD-CMS-Widgets 24 | 25 | - name: Download JS files 26 | run: | 27 | mkdir -p VOD-CMS-Widgets/Forward/JS 28 | declare -A jsfiles=( 29 | [douban]="https://raw.githubusercontent.com/huangxd-/ForwardWidgets/main/widgets/douban.js" 30 | [trakt]="https://raw.githubusercontent.com/huangxd-/ForwardWidgets/main/widgets/trakt.js" 31 | [zhuijurili]="https://raw.githubusercontent.com/huangxd-/ForwardWidgets/main/widgets/zhuijurili.js" 32 | [Move_list]="https://raw.githubusercontent.com/quantumultxx/ForwardWidgets/main/Widgets/Move_list.js" 33 | [HotPicks]="https://raw.githubusercontent.com/2kuai/ForwardWidgets/main/Widgets/HotPicks.js" 34 | [Bangumi_v2.0.0]="https://raw.githubusercontent.com/opix-maker/Forward/main/js/Bangumi_v2.0.0.js" 35 | [imdb_discovery]="https://raw.githubusercontent.com/opix-maker/Forward/main/js/IMDb.js" 36 | [imdb]="https://raw.githubusercontent.com/pack1r/ForwardWidgets/main/widgets/imdb.js" 37 | [person_movie]="https://raw.githubusercontent.com/EmrysChoo/ForwardWidgets/main/Widgets/person_movie.js" 38 | ) 39 | 40 | for js_name in "${!jsfiles[@]}"; do 41 | url="${jsfiles[$js_name]}" 42 | curl -A -L -o "VOD-CMS-Widgets/Forward/JS/${js_name}.js" "$url" 43 | sed -i "1s|^|// 引用链接: $url\n|" "VOD-CMS-Widgets/Forward/JS/$js_name.js" 44 | done 45 | 46 | - name: Commit and push changes 47 | working-directory: VOD-CMS-Widgets 48 | run: | 49 | git config user.name "github-actions" 50 | git config user.email "github-actions@github.com" 51 | git add Forward/JS/ 52 | git commit -m "Synchronously Update JS files" || echo "No changes to commit" 53 | git push 54 | 55 | - name: Clear Workflow 56 | uses: Mattraks/delete-workflow-runs@main 57 | with: 58 | retain_days: 0 59 | keep_minimum_runs: 12 60 | -------------------------------------------------------------------------------- /XPTV/CMS/AV.json: -------------------------------------------------------------------------------- 1 | { 2 | "sites": [ 3 | { 4 | "name": "AV-91麻豆", 5 | "type": 1, 6 | "api": "https://91md.me/api.php/provide/vod/" 7 | }, 8 | { 9 | "name": "AV-AIvin", 10 | "type": 1, 11 | "api": "http://lbapiby.com/api.php/provide/vod/at/json" 12 | }, 13 | { 14 | "name": "AV-奥斯卡资源", 15 | "type": 1, 16 | "api": "https://aosikazy.com/api.php/provide/vod/" 17 | }, 18 | { 19 | "name": "AV-草榴资源", 20 | "type": 1, 21 | "api": "https://www.caoliuzyw.com/api.php/prodao/vod/" 22 | }, 23 | { 24 | "name": "AV-番号资源", 25 | "type": 1, 26 | "api": "http://fhapi9.com/api.php/provide/vod/" 27 | }, 28 | { 29 | "name": "AV-黄瓜资源", 30 | "type": 1, 31 | "api": "https://www.zy018.com/api.php/provide/vod/" 32 | }, 33 | { 34 | "name": "AV-精品资源", 35 | "type": 1, 36 | "api": "https://www.jingpinx.com/api.php/provide/vod/" 37 | }, 38 | { 39 | "name": "AV-辣椒资源", 40 | "type": 1, 41 | "api": "https://apilj.com/api.php/provide/vod/" 42 | }, 43 | { 44 | "name": "AV-老色逼资源", 45 | "type": 1, 46 | "api": "https://apilsbzy1.com/api.php/provide/vod/" 47 | }, 48 | { 49 | "name": "AV-老鸭资源", 50 | "type": 1, 51 | "api": "https://api.apilyzy.com/api.php/provide/vod/" 52 | }, 53 | { 54 | "name": "AV-奶香香", 55 | "type": 1, 56 | "api": "https://Naixxzy.com/api.php/provide/vod/" 57 | }, 58 | { 59 | "name": "AV-森林资源", 60 | "type": 1, 61 | "api": "https://slapibf.com/api.php/provide/vod/" 62 | }, 63 | { 64 | "name": "AV-鲨鱼资源", 65 | "type": 1, 66 | "api": "https://shayuapi.com/api.php/provide/vod/" 67 | }, 68 | { 69 | "name": "AV-探探资源", 70 | "type": 1, 71 | "api": "https://apittzy.com/api.php/provide/vod/" 72 | }, 73 | { 74 | "name": "AV-易看资源", 75 | "type": 1, 76 | "api": "https://api.yikanapi.com/api.php/provide/vod/" 77 | }, 78 | { 79 | "name": "AV-玉兔资源", 80 | "type": 1, 81 | "api": "https://apiyutu.com/api.php/provide/vod/" 82 | } 83 | ] 84 | } -------------------------------------------------------------------------------- /SteveWatch/AV.json: -------------------------------------------------------------------------------- 1 | { 2 | "sites": [ 3 | { 4 | "name": "AV-91麻豆", 5 | "type": 1, 6 | "api": "https://91md.me/api.php/provide/vod/" 7 | }, 8 | { 9 | "name": "AV-AIvin", 10 | "type": 1, 11 | "api": "http://lbapiby.com/api.php/provide/vod/at/json" 12 | }, 13 | { 14 | "name": "AV-奥斯卡资源", 15 | "type": 1, 16 | "api": "https://aosikazy.com/api.php/provide/vod/" 17 | }, 18 | { 19 | "name": "AV-草榴资源", 20 | "type": 1, 21 | "api": "https://www.caoliuzyw.com/api.php/prodao/vod/" 22 | }, 23 | { 24 | "name": "AV-番号资源", 25 | "type": 1, 26 | "api": "http://fhapi9.com/api.php/provide/vod/" 27 | }, 28 | { 29 | "name": "AV-黄瓜资源", 30 | "type": 1, 31 | "api": "https://www.zy018.com/api.php/provide/vod/" 32 | }, 33 | { 34 | "name": "AV-精品资源", 35 | "type": 1, 36 | "api": "https://www.jingpinx.com/api.php/provide/vod/" 37 | }, 38 | { 39 | "name": "AV-辣椒资源", 40 | "type": 1, 41 | "api": "https://apilj.com/api.php/provide/vod/" 42 | }, 43 | { 44 | "name": "AV-老色逼资源", 45 | "type": 1, 46 | "api": "https://apilsbzy1.com/api.php/provide/vod/" 47 | }, 48 | { 49 | "name": "AV-老鸭资源", 50 | "type": 1, 51 | "api": "https://api.apilyzy.com/api.php/provide/vod/" 52 | }, 53 | { 54 | "name": "AV-奶香香", 55 | "type": 1, 56 | "api": "https://Naixxzy.com/api.php/provide/vod/" 57 | }, 58 | { 59 | "name": "AV-森林资源", 60 | "type": 1, 61 | "api": "https://slapibf.com/api.php/provide/vod/" 62 | }, 63 | { 64 | "name": "AV-鲨鱼资源", 65 | "type": 1, 66 | "api": "https://shayuapi.com/api.php/provide/vod/" 67 | }, 68 | { 69 | "name": "AV-探探资源", 70 | "type": 1, 71 | "api": "https://apittzy.com/api.php/provide/vod/" 72 | }, 73 | { 74 | "name": "AV-易看资源", 75 | "type": 1, 76 | "api": "https://api.yikanapi.com/api.php/provide/vod/" 77 | }, 78 | { 79 | "name": "AV-玉兔资源", 80 | "type": 1, 81 | "api": "https://apiyutu.com/api.php/provide/vod/" 82 | } 83 | ] 84 | } -------------------------------------------------------------------------------- /XPTV/JS/harunasan.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://gist.githubusercontent.com/Yswag/d9f072b75dab5b1b107c523dd148eea3/raw/harunasan.js 2 | const UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0.1 Mobile/15E148 Safari/604.1' 3 | 4 | let appConfig = { 5 | ver: 1, 6 | title: '聚合直播', 7 | site: 'http://api.maiyoux.com:81', 8 | } 9 | 10 | async function getConfig() { 11 | let config = appConfig 12 | config.tabs = await getTabs() 13 | return jsonify(config) 14 | } 15 | 16 | async function getTabs() { 17 | let list = [] 18 | let ignore = ['卫视直播', '龙珠', '映客'] 19 | function isIgnoreClassName(className) { 20 | return ignore.some((element) => className.includes(element)) 21 | } 22 | 23 | const jsonurl = appConfig.site + '/mf/json.txt' 24 | const { data } = await $fetch.get(jsonurl, { 25 | headers: { 26 | 'User-Agent': UA, 27 | }, 28 | }) 29 | 30 | argsify(data).pingtai.forEach((e) => { 31 | const name = `${e.title} (${e.Number})` 32 | const href = e.address 33 | const isIgnore = isIgnoreClassName(name) 34 | if (isIgnore) return 35 | 36 | list.push({ 37 | name, 38 | ext: { 39 | url: encodeURI(href), 40 | }, 41 | }) 42 | }) 43 | 44 | return list 45 | } 46 | 47 | async function getCards(ext) { 48 | ext = argsify(ext) 49 | let cards = [] 50 | let jsonurl = ext.url 51 | let page = ext.page 52 | let url 53 | if (page === 1) { 54 | url = `${appConfig.site}/mf/${jsonurl}` 55 | } 56 | const { data } = await $fetch.get(url, { 57 | headers: { 58 | 'User-Agent': UA, 59 | }, 60 | }) 61 | argsify(data).zhubo.forEach((e) => { 62 | const cover = e.img 63 | const time = e.duration 64 | const addtime = e.createAt 65 | const address = e.address 66 | if (address.startsWith('rtmp')) return 67 | cards.push({ 68 | vod_id: address, 69 | vod_name: e.title, 70 | vod_pic: cover, 71 | vod_remarks: 'live', 72 | ext: { 73 | url: address, 74 | }, 75 | }) 76 | }) 77 | return jsonify({ 78 | list: cards, 79 | }) 80 | } 81 | 82 | async function getTracks(ext) { 83 | ext = argsify(ext) 84 | let tracks = [] 85 | let url = ext.url 86 | tracks.push({ 87 | name: '播放', 88 | ext: { 89 | playurl: url, 90 | }, 91 | }) 92 | return jsonify({ 93 | list: [ 94 | { 95 | title: '默认分组', 96 | tracks, 97 | }, 98 | ], 99 | }) 100 | } 101 | 102 | async function getPlayinfo(ext) { 103 | ext = argsify(ext) 104 | let playurl = ext.playurl 105 | return jsonify({ urls: [playurl] }) 106 | } 107 | -------------------------------------------------------------------------------- /Forward/Widgets.fwd: -------------------------------------------------------------------------------- 1 | { 2 | "title": "sooyaaabo's ForwardWidgets", 3 | "description": "ForwardWidgets自用合集 by sooyaaabo", 4 | "icon": "https://raw.githubusercontent.com/sooyaaabo/VOD-CMS-Widgets/refs/heads/main/Forward/ForwardWidgets.png", 5 | "widgets": [ 6 | { 7 | "id": "douban", 8 | "title": "豆瓣我看&豆瓣个性化推荐", 9 | "description": "解析豆瓣想看、在看、已看以及根据个人数据生成的个性化推荐", 10 | "requiredVersion": "0.0.1", 11 | "version": "1.0.15", 12 | "author": "huangxd", 13 | "url": "https://raw.githubusercontent.com/huangxd-/ForwardWidgets/refs/heads/main/widgets/douban.js" 14 | }, 15 | { 16 | "id": "trakt", 17 | "title": "Trakt我看&Trakt个性化推荐", 18 | "description": "解析Trakt想看、在看、已看、片单、追剧日历以及根据个人数据生成的个性化推荐", 19 | "requiredVersion": "0.0.1", 20 | "version": "1.0.11", 21 | "author": "huangxd", 22 | "url": "https://raw.githubusercontent.com/huangxd-/ForwardWidgets/refs/heads/main/widgets/trakt.js" 23 | }, 24 | { 25 | "id": "zhuijurili", 26 | "title": "追剧日历(今/明日播出、周历、各项榜单、今日推荐)", 27 | "description": "解析追剧日历今/明日播出剧集/番剧/国漫/综艺、周历、各项榜单、今日推荐等", 28 | "requiredVersion": "0.0.1", 29 | "version": "1.0.4", 30 | "author": "huangxd", 31 | "url": "https://raw.githubusercontent.com/huangxd-/ForwardWidgets/refs/heads/main/widgets/zhuijurili.js" 32 | }, 33 | { 34 | "id": "forward.combined.media.lists", 35 | "title": "影视榜单", 36 | "description": "获取TMDB和豆瓣的榜单", 37 | "requiredVersion": "0.0.1", 38 | "version": "1.0.0", 39 | "author": "阿米诺斯", 40 | "url": "https://raw.githubusercontent.com/quantumultxx/ForwardWidgets/refs/heads/main/Widgets/Move_list.js" 41 | }, 42 | { 43 | "id": "hot_picks", 44 | "title": "热门精选", 45 | "description": "获取最新热播剧和热门影片推荐", 46 | "requiredVersion": "0.0.1", 47 | "version": "1.1.7", 48 | "author": "两块", 49 | "url": "https://raw.githubusercontent.com/2kuai/ForwardWidgets/refs/heads/main/Widgets/HotPicks.js" 50 | }, 51 | { 52 | "id": "bangumi_charts_tmdb_v3", 53 | "title": "Bangumi 热门榜单", 54 | "description": "获取Bangumi近期热门、每日放送数据,支持榜单筛选。", 55 | "requiredVersion": "0.0.1", 56 | "version": "2.0.0", 57 | "author": "Autism", 58 | "url": "https://raw.githubusercontent.com/opix-maker/Forward/refs/heads/main/js/Bangumi_v2.0.0.js" 59 | }, 60 | { 61 | "id": "imdb_discovery_final_v2", 62 | "title": "IMDb 分类资源 v2", 63 | "description": "聚合 IMDb 热门影视资源", 64 | "requiredVersion": "0.0.1", 65 | "version": "2.0.0", 66 | "author": "Autism", 67 | "url": "https://raw.githubusercontent.com/opix-maker/Forward/refs/heads/main/js/IMDb.js" 68 | }, 69 | { 70 | "id": "imdb", 71 | "title": "IMDB", 72 | "description": "IMDB", 73 | "requiredVersion": "0.0.1", 74 | "version": "1.0.0", 75 | "author": "pack1r", 76 | "url": "https://raw.githubusercontent.com/pack1r/ForwardWidgets/refs/heads/main/widgets/imdb.js" 77 | }, 78 | { 79 | "id": "person.movie.tmdb", 80 | "title": "TMDB人物影视作品", 81 | "description": "获取 TMDB 的榜单数据", 82 | "requiredVersion": "0.0.1", 83 | "version": "1.0.4", 84 | "author": "Evan", 85 | "url": "https://raw.githubusercontent.com/EmrysChoo/ForwardWidgets/refs/heads/main/Widgets/person_movie.js" 86 | } 87 | ] 88 | } -------------------------------------------------------------------------------- /XPTV/JS/baipiao.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/baipiao.js 2 | const cheerio = createCheerio() 3 | 4 | const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' 5 | 6 | const appConfig = { 7 | ver: 1, 8 | title: '白嫖', 9 | site: 'https://smdyo.top', 10 | tabs: [ 11 | { 12 | name: '電影', 13 | ext: { 14 | id: 30, 15 | }, 16 | }, 17 | { 18 | name: '劇集', 19 | ext: { 20 | id: 25, 21 | }, 22 | }, 23 | { 24 | name: '動漫', 25 | ext: { 26 | id: 20, 27 | }, 28 | }, 29 | ], 30 | } 31 | 32 | async function getConfig() { 33 | return jsonify(appConfig) 34 | } 35 | 36 | async function getCards(ext) { 37 | 38 | ext = argsify(ext) 39 | let cards = [] 40 | let { page = 1, id } = ext 41 | 42 | const url = appConfig.site + `/index.php/vod/show/id/${id}/page/${page}.html` 43 | const { data } = await $fetch.get(url, { 44 | headers: { 45 | 'User-Agent': UA, 46 | }, 47 | }) 48 | 49 | const $ = cheerio.load(data) 50 | 51 | const videos = $('#main .module-item') 52 | videos.each((_, e) => { 53 | const href = $(e).find('.module-item-pic a').attr('href') 54 | const title = $(e).find('.module-item-pic a').attr('title') 55 | const cover = $(e).find('.module-item-pic img').attr('data-src') 56 | const remarks = $(e).find('.module-item-text').text() 57 | 58 | cards.push({ 59 | vod_id: href, 60 | vod_name: title, 61 | vod_pic: cover, 62 | vod_remarks: remarks, 63 | 64 | ext: { 65 | url: `${appConfig.site}${href}`, 66 | }, 67 | }) 68 | }) 69 | 70 | return jsonify({ 71 | list: cards, 72 | }) 73 | } 74 | 75 | async function getTracks(ext) { 76 | ext = argsify(ext) 77 | let tracks = [] 78 | let url = ext.url 79 | 80 | const { data } = await $fetch.get(url, { 81 | headers: { 82 | 'User-Agent': UA, 83 | }, 84 | }) 85 | 86 | const $ = cheerio.load(data) 87 | 88 | const playlist = $('.module-player-list .module-row-one') 89 | playlist.each((_, e) => { 90 | const panShareUrl = $(e).find('.module-row-title p').text() 91 | tracks.push({ 92 | name: '网盘', 93 | pan: panShareUrl, 94 | }) 95 | }) 96 | 97 | return jsonify({ 98 | list: [ 99 | { 100 | title: '默认分组', 101 | tracks, 102 | }, 103 | ], 104 | }) 105 | } 106 | 107 | async function getPlayinfo(ext) { 108 | return jsonify({ urls: [] }) 109 | } 110 | 111 | async function search(ext) { 112 | ext = argsify(ext) 113 | let cards = [] 114 | 115 | let text = encodeURIComponent(ext.text) 116 | let page = ext.page || 1 117 | let url = `${appConfig.site}/index.php/vod/search/page/${page}/wd/${text}.html` 118 | 119 | const { data } = await $fetch.get(url, { 120 | headers: { 121 | 'User-Agent': UA, 122 | }, 123 | }) 124 | 125 | const $ = cheerio.load(data) 126 | 127 | const videos = $('#main .module-search-item') 128 | videos.each((_, e) => { 129 | const href = $(e).find('.video-info-header h3 a').attr('href') 130 | const title = $(e).find('.video-info-header h3 a').attr('title') 131 | const cover = $(e).find('.module-item-pic img').attr('data-src') 132 | const remarks = $(e).find('.video-serial').text() 133 | 134 | cards.push({ 135 | vod_id: href, 136 | vod_name: title, 137 | vod_pic: cover, 138 | vod_remarks: remarks, 139 | ext: { 140 | url: `${appConfig.site}${href}`, 141 | }, 142 | }) 143 | }) 144 | 145 | return jsonify({ 146 | list: cards, 147 | }) 148 | } 149 | -------------------------------------------------------------------------------- /XPTV/JS/seedhub.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/seedhub.js 2 | const cheerio = createCheerio() 3 | const UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_2 like Mac OS X) AppleWebKit/604.1.14 (KHTML, like Gecko)' 4 | 5 | const appConfig = { 6 | ver: 1, 7 | title: 'SeedHub', 8 | site: 'https://www.seedhub.cc', 9 | tabs: [ 10 | { 11 | name: '首页', 12 | ext: { 13 | id: '/', 14 | }, 15 | }, 16 | { 17 | name: '电影', 18 | ext: { 19 | id: '/categories/1/movies/', 20 | }, 21 | }, 22 | { 23 | name: '剧集', 24 | ext: { 25 | id: '/categories/3/movies/', 26 | }, 27 | }, 28 | { 29 | name: '动漫', 30 | ext: { 31 | id: '/categories/2/movies/', 32 | }, 33 | } 34 | 35 | ], 36 | } 37 | async function getConfig() { 38 | return jsonify(appConfig) 39 | } 40 | 41 | async function getCards(ext) { 42 | ext = argsify(ext) 43 | let cards = [] 44 | let { page = 1, id } = ext 45 | const url =appConfig.site + id + `?page=${page}` 46 | const { data } = await $fetch.get(url, { 47 | headers: { 48 | "User-Agent": UA, 49 | }, 50 | }); 51 | 52 | const $ = cheerio.load(data) 53 | const videos = $('.cover') 54 | videos.each((_, e) => { 55 | const href = $(e).find('a').attr('href') 56 | const title = $(e).find('a img').attr('alt') 57 | const cover = $(e).find('a img').attr('src') 58 | cards.push({ 59 | vod_id: href, 60 | vod_name: title, 61 | vod_pic: cover, 62 | vod_remarks: '', 63 | ext: { 64 | url: `${appConfig.site}${href}`, 65 | }, 66 | }) 67 | }) 68 | return jsonify({ 69 | list: cards, 70 | }) 71 | } 72 | 73 | async function getTracks(ext) { 74 | ext = argsify(ext); 75 | let tracks = []; 76 | let url = ext.url; 77 | 78 | const { data } = await $fetch.get(url, { 79 | headers: { 80 | 'User-Agent': UA, 81 | }, 82 | }); 83 | 84 | const $ = cheerio.load(data); 85 | const playlist = $('.pan-links'); 86 | 87 | if (playlist.length === 0 || playlist.find('li').length === 0) { 88 | $utils.toastError('没有网盘资源'); 89 | return jsonify({ list: [] }); 90 | } 91 | 92 | playlist.each((_, e) => { 93 | 94 | $(e).find('li a').each((_, link) => { 95 | const href = $(link).attr('data-link'); 96 | 97 | tracks.push({ 98 | name: '网盘', 99 | pan: href, 100 | }); 101 | 102 | }); 103 | }); 104 | 105 | return jsonify({ 106 | list: [ 107 | { 108 | title: '默认分组', 109 | tracks, 110 | }, 111 | ], 112 | }); 113 | } 114 | async function getPlayinfo(ext) { 115 | ext = argsify(ext) 116 | const url = ext.url 117 | 118 | return jsonify({ urls: [ext.url] }) 119 | } 120 | 121 | async function search(ext) { 122 | ext = argsify(ext) 123 | let cards = [] 124 | 125 | let text = encodeURIComponent(ext.text) 126 | let page = ext.page || 1 127 | let url = `${appConfig.site}/s/${text}/?page=${page}` 128 | 129 | const { data } = await $fetch.get(url, { 130 | headers: { 131 | 'User-Agent': UA, 132 | }, 133 | }) 134 | 135 | const $ = cheerio.load(data) 136 | const videos = $('.cover') 137 | videos.each((_, e) => { 138 | const href = $(e).find('a').attr('href') 139 | const title = $(e).find('a img').attr('alt') 140 | const cover = $(e).find('a img').attr('src') 141 | cards.push({ 142 | vod_id: href, 143 | vod_name: title, 144 | vod_pic: cover, 145 | vod_remarks: '', 146 | ext: { 147 | url: `${appConfig.site}${href}`, 148 | }, 149 | }) 150 | }) 151 | 152 | return jsonify({ 153 | list: cards, 154 | }) 155 | } 156 | -------------------------------------------------------------------------------- /XPTV/JS/liuqu.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/liuqu.js 2 | const cheerio = createCheerio() 3 | 4 | const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' 5 | 6 | const appConfig = { 7 | ver: 1, 8 | title: '六趣', 9 | site: 'https://wp.0v.fit', 10 | tabs: [ 11 | { 12 | name: '電影', 13 | ext: { 14 | id: 1, 15 | }, 16 | }, 17 | { 18 | name: '劇集', 19 | ext: { 20 | id: 2, 21 | }, 22 | }, 23 | { 24 | name: '動漫', 25 | ext: { 26 | id: 4, 27 | }, 28 | }, 29 | ], 30 | } 31 | 32 | async function getConfig() { 33 | return jsonify(appConfig) 34 | } 35 | 36 | async function getCards(ext) { 37 | 38 | ext = argsify(ext) 39 | let cards = [] 40 | let { page = 1, id } = ext 41 | 42 | const url = appConfig.site + `/index.php/vod/show/id/${id}/page/${page}.html` 43 | const { data } = await $fetch.get(url, { 44 | headers: { 45 | 'User-Agent': UA, 46 | }, 47 | }) 48 | 49 | const $ = cheerio.load(data) 50 | 51 | const videos = $('#main .module-item') 52 | videos.each((_, e) => { 53 | const href = $(e).find('.module-item-pic a').attr('href') 54 | const title = $(e).find('.module-item-pic a').attr('title') 55 | const cover = $(e).find('.module-item-pic img').attr('data-src') 56 | const remarks = $(e).find('.module-item-text').text() 57 | 58 | if (/六趣/.test(title)) return; 59 | cards.push({ 60 | vod_id: href, 61 | vod_name: title, 62 | vod_pic: cover, 63 | vod_remarks: remarks, 64 | 65 | ext: { 66 | url: `${appConfig.site}${href}`, 67 | }, 68 | }) 69 | }) 70 | 71 | return jsonify({ 72 | list: cards, 73 | }) 74 | } 75 | 76 | async function getTracks(ext) { 77 | ext = argsify(ext) 78 | let tracks = [] 79 | let url = ext.url 80 | 81 | const { data } = await $fetch.get(url, { 82 | headers: { 83 | 'User-Agent': UA, 84 | }, 85 | }) 86 | 87 | const $ = cheerio.load(data) 88 | 89 | const playlist = $('.module-player-list .module-row-one') 90 | playlist.each((_, e) => { 91 | const name = $(e).find('.module-row-title h4').text().replace('- 第1集', '') 92 | const panShareUrl = $(e).find('.module-row-title p').text() 93 | tracks.push({ 94 | name: name.trim(), 95 | pan: panShareUrl, 96 | }) 97 | }) 98 | 99 | return jsonify({ 100 | list: [ 101 | { 102 | title: '默认分组', 103 | tracks, 104 | }, 105 | ], 106 | }) 107 | } 108 | 109 | async function getPlayinfo(ext) { 110 | return jsonify({ urls: [] }) 111 | } 112 | 113 | async function search(ext) { 114 | ext = argsify(ext) 115 | let cards = [] 116 | 117 | let text = encodeURIComponent(ext.text) 118 | let page = ext.page || 1 119 | let url = `${appConfig.site}/index.php/vod/search/page/${page}/wd/${text}.html` 120 | 121 | const { data } = await $fetch.get(url, { 122 | headers: { 123 | 'User-Agent': UA, 124 | }, 125 | }) 126 | 127 | const $ = cheerio.load(data) 128 | 129 | const videos = $('#main .module-search-item') 130 | videos.each((_, e) => { 131 | const href = $(e).find('.video-info-header h3 a').attr('href') 132 | const title = $(e).find('.video-info-header h3 a').attr('title') 133 | const cover = $(e).find('.module-item-pic img').attr('data-src') 134 | const remarks = $(e).find('.video-serial').text() 135 | 136 | if (/六趣/.test(title)) return; 137 | cards.push({ 138 | vod_id: href, 139 | vod_name: title, 140 | vod_pic: cover, 141 | vod_remarks: remarks, 142 | ext: { 143 | url: `${appConfig.site}${href}`, 144 | }, 145 | }) 146 | }) 147 | 148 | return jsonify({ 149 | list: cards, 150 | }) 151 | } 152 | -------------------------------------------------------------------------------- /Forward/ForwardWidgets.fwd: -------------------------------------------------------------------------------- 1 | { 2 | "title": "sooyaaabo's ForwardWidgets", 3 | "description": "ForwardWidgets自用合集 by sooyaaabo", 4 | "icon": "https://raw.githubusercontent.com/sooyaaabo/VOD-CMS-Widgets/main/Forward/ForwardWidgets.png", 5 | "widgets": [ 6 | { 7 | "id": "douban", 8 | "title": "豆瓣我看&豆瓣个性化推荐", 9 | "description": "解析豆瓣想看、在看、已看以及根据个人数据生成的个性化推荐", 10 | "requiredVersion": "0.0.1", 11 | "version": "1.0.15", 12 | "author": "huangxd", 13 | "url": "https://raw.githubusercontent.com/huangxd-/ForwardWidgets/main/widgets/douban.js" 14 | }, 15 | { 16 | "id": "trakt", 17 | "title": "Trakt我看&Trakt个性化推荐", 18 | "description": "解析Trakt想看、在看、已看、片单、追剧日历以及根据个人数据生成的个性化推荐", 19 | "requiredVersion": "0.0.1", 20 | "version": "1.0.11", 21 | "author": "huangxd", 22 | "url": "https://raw.githubusercontent.com/huangxd-/ForwardWidgets/main/widgets/trakt.js" 23 | }, 24 | { 25 | "id": "zhuijurili", 26 | "title": "追剧日历(今/明日播出、周历、各项榜单、今日推荐)", 27 | "description": "解析追剧日历今/明日播出剧集/番剧/国漫/综艺、周历、各项榜单、今日推荐等", 28 | "requiredVersion": "0.0.1", 29 | "version": "1.0.4", 30 | "author": "huangxd", 31 | "url": "https://raw.githubusercontent.com/huangxd-/ForwardWidgets/main/widgets/zhuijurili.js" 32 | }, 33 | { 34 | "id": "forward.combined.media.lists", 35 | "title": "影视榜单", 36 | "description": "获取TMDB和豆瓣的榜单", 37 | "requiredVersion": "0.0.1", 38 | "version": "1.0.0", 39 | "author": "阿米诺斯", 40 | "url": "https://raw.githubusercontent.com/quantumultxx/ForwardWidgets/main/Widgets/Move_list.js" 41 | }, 42 | { 43 | "id": "hot_picks", 44 | "title": "热门精选", 45 | "description": "获取最新热播剧和热门影片推荐", 46 | "requiredVersion": "0.0.1", 47 | "version": "1.1.7", 48 | "author": "两块", 49 | "url": "https://raw.githubusercontent.com/2kuai/ForwardWidgets/main/Widgets/HotPicks.js" 50 | }, 51 | { 52 | "id": "bangumi_charts_tmdb_v3", 53 | "title": "Bangumi 热门榜单", 54 | "description": "获取Bangumi近期热门、每日放送数据,支持榜单筛选。", 55 | "requiredVersion": "0.0.1", 56 | "version": "2.0.0", 57 | "author": "Autism", 58 | "url": "https://raw.githubusercontent.com/opix-maker/Forward/main/js/Bangumi_v2.0.0.js" 59 | }, 60 | { 61 | "id": "imdb_discovery_final_v2", 62 | "title": "IMDb 分类资源 v2", 63 | "description": "聚合 IMDb 热门影视资源", 64 | "requiredVersion": "0.0.1", 65 | "version": "2.0.0", 66 | "author": "Autism", 67 | "url": "https://raw.githubusercontent.com/opix-maker/Forward/main/js/IMDb.js" 68 | }, 69 | { 70 | "id": "imdb", 71 | "title": "IMDB", 72 | "description": "IMDB", 73 | "requiredVersion": "0.0.1", 74 | "version": "1.0.0", 75 | "author": "pack1r", 76 | "url": "https://raw.githubusercontent.com/pack1r/ForwardWidgets/main/widgets/imdb.js" 77 | }, 78 | { 79 | "id": "person.movie.tmdb", 80 | "title": "TMDB人物影视作品", 81 | "description": "获取 TMDB 的榜单数据", 82 | "requiredVersion": "0.0.1", 83 | "version": "1.0.4", 84 | "author": "Evan", 85 | "url": "https://raw.githubusercontent.com/EmrysChoo/ForwardWidgets/main/Widgets/person_movie.js" 86 | } 87 | ] 88 | } -------------------------------------------------------------------------------- /XPTV/JS/aomi.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/aomi.js 2 | const cheerio = createCheerio() 3 | 4 | const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' 5 | 6 | const appConfig = { 7 | ver: 1, 8 | title: '奥秘', 9 | site: 'https://vip.omii.top', 10 | tabs: [ 11 | { 12 | name: '電影', 13 | ext: { 14 | id: 30, 15 | }, 16 | }, 17 | { 18 | name: '劇集', 19 | ext: { 20 | id: 31, 21 | }, 22 | }, 23 | { 24 | name: '動漫', 25 | ext: { 26 | id: 32, 27 | }, 28 | }, 29 | { 30 | name: '綜藝', 31 | ext: { 32 | id: 33, 33 | }, 34 | }, 35 | ], 36 | } 37 | 38 | async function getConfig() { 39 | return jsonify(appConfig) 40 | } 41 | 42 | async function getCards(ext) { 43 | 44 | ext = argsify(ext) 45 | let cards = [] 46 | let { page = 1, id } = ext 47 | 48 | const url = appConfig.site + `/index.php/vod/show/id/${id}/page/${page}.html` 49 | const { data } = await $fetch.get(url, { 50 | headers: { 51 | 'User-Agent': UA, 52 | }, 53 | }) 54 | 55 | const $ = cheerio.load(data) 56 | 57 | const videos = $('#main .module-item') 58 | videos.each((_, e) => { 59 | const href = $(e).find('.module-item-pic a').attr('href') 60 | const title = $(e).find('.module-item-pic a').attr('title') 61 | const cover = $(e).find('.module-item-pic img').attr('data-src') 62 | const remarks = $(e).find('.module-item-text').text() 63 | 64 | cards.push({ 65 | vod_id: href, 66 | vod_name: title, 67 | vod_pic: cover, 68 | vod_remarks: remarks, 69 | 70 | ext: { 71 | url: `${appConfig.site}${href}`, 72 | }, 73 | }) 74 | }) 75 | 76 | return jsonify({ 77 | list: cards, 78 | }) 79 | } 80 | 81 | async function getTracks(ext) { 82 | ext = argsify(ext) 83 | let tracks = [] 84 | let url = ext.url 85 | 86 | const { data } = await $fetch.get(url, { 87 | headers: { 88 | 'User-Agent': UA, 89 | }, 90 | }) 91 | 92 | const $ = cheerio.load(data) 93 | 94 | const playlist = $('.module-player-list .module-row-one') 95 | playlist.each((_, e) => { 96 | const name = $(e).find('.module-row-title h4').text().replace('- 奥秘分享', '') 97 | const panShareUrl = $(e).find('.module-row-title p').text() 98 | tracks.push({ 99 | name: name.trim(), 100 | pan: panShareUrl, 101 | }) 102 | }) 103 | 104 | return jsonify({ 105 | list: [ 106 | { 107 | title: '默认分组', 108 | tracks, 109 | }, 110 | ], 111 | }) 112 | } 113 | 114 | async function getPlayinfo(ext) { 115 | return jsonify({ urls: [] }) 116 | } 117 | 118 | async function search(ext) { 119 | ext = argsify(ext) 120 | let cards = [] 121 | 122 | let text = encodeURIComponent(ext.text) 123 | let page = ext.page || 1 124 | let url = `${appConfig.site}/index.php/vod/search/page/${page}/wd/${text}.html` 125 | 126 | const { data } = await $fetch.get(url, { 127 | headers: { 128 | 'User-Agent': UA, 129 | }, 130 | }) 131 | 132 | const $ = cheerio.load(data) 133 | 134 | const videos = $('#main .module-search-item') 135 | videos.each((_, e) => { 136 | const href = $(e).find('.video-info-header h3 a').attr('href') 137 | const title = $(e).find('.video-info-header h3 a').attr('title') 138 | const cover = $(e).find('.module-item-pic img').attr('data-src') 139 | const remarks = $(e).find('.video-serial').text() 140 | 141 | cards.push({ 142 | vod_id: href, 143 | vod_name: title, 144 | vod_pic: cover, 145 | vod_remarks: remarks, 146 | ext: { 147 | url: `${appConfig.site}${href}`, 148 | }, 149 | }) 150 | }) 151 | 152 | return jsonify({ 153 | list: cards, 154 | }) 155 | } 156 | -------------------------------------------------------------------------------- /XPTV/JS/texiafan.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/xiafan.js 2 | const cheerio = createCheerio() 3 | 4 | const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' 5 | 6 | const appConfig = { 7 | ver: 1, 8 | title: '下饭', 9 | site: 'https://xiafan.banye.tech:7086', 10 | tabs: [ 11 | { 12 | name: '電影', 13 | ext: { 14 | id: 1, 15 | }, 16 | }, 17 | { 18 | name: '劇集', 19 | ext: { 20 | id: 2, 21 | }, 22 | }, 23 | { 24 | name: '動漫', 25 | ext: { 26 | id: 3, 27 | }, 28 | }, 29 | { 30 | name: '綜藝', 31 | ext: { 32 | id: 4, 33 | }, 34 | }, 35 | ], 36 | } 37 | 38 | async function getConfig() { 39 | return jsonify(appConfig) 40 | } 41 | 42 | async function getCards(ext) { 43 | 44 | ext = argsify(ext) 45 | let cards = [] 46 | let { page = 1, id } = ext 47 | 48 | const url = appConfig.site + `/index.php/vod/show/id/${id}/page/${page}.html` 49 | const { data } = await $fetch.get(url, { 50 | headers: { 51 | 'User-Agent': UA, 52 | }, 53 | }) 54 | 55 | const $ = cheerio.load(data) 56 | 57 | const videos = $('#main .module-item') 58 | videos.each((_, e) => { 59 | const href = $(e).find('.module-item-pic a').attr('href') 60 | const title = $(e).find('.module-item-pic a').attr('title') 61 | const cover = $(e).find('.module-item-pic img').attr('data-src') 62 | const remarks = $(e).find('.module-item-text').text() 63 | 64 | if (/六趣/.test(title)) return; 65 | cards.push({ 66 | vod_id: href, 67 | vod_name: title, 68 | vod_pic: cover, 69 | vod_remarks: remarks, 70 | 71 | ext: { 72 | url: `${appConfig.site}${href}`, 73 | }, 74 | }) 75 | }) 76 | 77 | return jsonify({ 78 | list: cards, 79 | }) 80 | } 81 | 82 | async function getTracks(ext) { 83 | ext = argsify(ext) 84 | let tracks = [] 85 | let url = ext.url 86 | 87 | const { data } = await $fetch.get(url, { 88 | headers: { 89 | 'User-Agent': UA, 90 | }, 91 | }) 92 | 93 | const $ = cheerio.load(data) 94 | 95 | const playlist = $('.module-player-list .module-row-one') 96 | playlist.each((_, e) => { 97 | const name = $(e).find('.module-row-title h4').text().replace('- 特下饭', '') 98 | const panShareUrl = $(e).find('.module-row-title p').text() 99 | tracks.push({ 100 | name: name.trim(), 101 | pan: panShareUrl, 102 | }) 103 | }) 104 | 105 | return jsonify({ 106 | list: [ 107 | { 108 | title: '默认分组', 109 | tracks, 110 | }, 111 | ], 112 | }) 113 | } 114 | 115 | async function getPlayinfo(ext) { 116 | return jsonify({ urls: [] }) 117 | } 118 | 119 | async function search(ext) { 120 | ext = argsify(ext) 121 | let cards = [] 122 | 123 | let text = encodeURIComponent(ext.text) 124 | let page = ext.page || 1 125 | let url = `${appConfig.site}/index.php/vod/search/page/${page}/wd/${text}.html` 126 | 127 | const { data } = await $fetch.get(url, { 128 | headers: { 129 | 'User-Agent': UA, 130 | }, 131 | }) 132 | 133 | const $ = cheerio.load(data) 134 | 135 | const videos = $('#main .module-search-item') 136 | videos.each((_, e) => { 137 | const href = $(e).find('.video-info-header h3 a').attr('href') 138 | const title = $(e).find('.video-info-header h3 a').attr('title') 139 | const cover = $(e).find('.module-item-pic img').attr('data-src') 140 | const remarks = $(e).find('.video-serial').text() 141 | 142 | cards.push({ 143 | vod_id: href, 144 | vod_name: title, 145 | vod_pic: cover, 146 | vod_remarks: remarks, 147 | ext: { 148 | url: `${appConfig.site}${href}`, 149 | }, 150 | }) 151 | }) 152 | 153 | return jsonify({ 154 | list: cards, 155 | }) 156 | } 157 | -------------------------------------------------------------------------------- /XPTV/JS/shandian.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/shandian.js 2 | const cheerio = createCheerio() 3 | 4 | const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' 5 | 6 | const appConfig = { 7 | ver: 1, 8 | title: '闪电', 9 | site: 'http://1.95.79.193', 10 | tabs: [ 11 | { 12 | name: '電影', 13 | ext: { 14 | id: 1, 15 | }, 16 | }, 17 | { 18 | name: '劇集', 19 | ext: { 20 | id: 2, 21 | }, 22 | }, 23 | { 24 | name: '動漫', 25 | ext: { 26 | id: 4, 27 | }, 28 | }, 29 | { 30 | name: '綜藝', 31 | ext: { 32 | id: 3, 33 | }, 34 | }, 35 | { 36 | name: '短劇', 37 | ext: { 38 | id: 6, 39 | }, 40 | }, 41 | ], 42 | } 43 | 44 | async function getConfig() { 45 | return jsonify(appConfig) 46 | } 47 | 48 | async function getCards(ext) { 49 | 50 | ext = argsify(ext) 51 | let cards = [] 52 | let { page = 1, id } = ext 53 | 54 | const url = appConfig.site + `/index.php/vod/show/id/${id}/page/${page}.html` 55 | const { data } = await $fetch.get(url, { 56 | headers: { 57 | 'User-Agent': UA, 58 | }, 59 | }) 60 | 61 | const $ = cheerio.load(data) 62 | 63 | const videos = $('#main .module-item') 64 | videos.each((_, e) => { 65 | const href = $(e).find('.module-item-pic a').attr('href') 66 | const title = $(e).find('.module-item-pic a').attr('title') 67 | const cover = $(e).find('.module-item-pic img').attr('data-src') 68 | const remarks = $(e).find('.module-item-text').text() 69 | 70 | cards.push({ 71 | vod_id: href, 72 | vod_name: title, 73 | vod_pic: cover, 74 | vod_remarks: remarks, 75 | 76 | ext: { 77 | url: `${appConfig.site}${href}`, 78 | }, 79 | }) 80 | }) 81 | 82 | return jsonify({ 83 | list: cards, 84 | }) 85 | } 86 | 87 | async function getTracks(ext) { 88 | ext = argsify(ext) 89 | let tracks = [] 90 | let url = ext.url 91 | 92 | const { data } = await $fetch.get(url, { 93 | headers: { 94 | 'User-Agent': UA, 95 | }, 96 | }) 97 | 98 | const $ = cheerio.load(data) 99 | 100 | const playlist = $('.module-player-list .module-row-one') 101 | playlist.each((_, e) => { 102 | const name = $(e).find('.module-row-title h4').text().replace('- 第1集', '') 103 | const panShareUrl = $(e).find('.module-row-title p').text() 104 | tracks.push({ 105 | name: name.trim(), 106 | pan: panShareUrl, 107 | }) 108 | }) 109 | 110 | return jsonify({ 111 | list: [ 112 | { 113 | title: '默认分组', 114 | tracks, 115 | }, 116 | ], 117 | }) 118 | } 119 | 120 | async function getPlayinfo(ext) { 121 | return jsonify({ urls: [] }) 122 | } 123 | 124 | async function search(ext) { 125 | ext = argsify(ext) 126 | let cards = [] 127 | 128 | let text = encodeURIComponent(ext.text) 129 | let page = ext.page || 1 130 | let url = `${appConfig.site}/index.php/vod/search/page/${page}/wd/${text}.html` 131 | 132 | const { data } = await $fetch.get(url, { 133 | headers: { 134 | 'User-Agent': UA, 135 | }, 136 | }) 137 | 138 | const $ = cheerio.load(data) 139 | 140 | const videos = $('#main .module-search-item') 141 | videos.each((_, e) => { 142 | const href = $(e).find('.video-info-header h3 a').attr('href') 143 | const title = $(e).find('.video-info-header h3 a').attr('title') 144 | const cover = $(e).find('.module-item-pic img').attr('data-src') 145 | const remarks = $(e).find('.video-serial').text() 146 | 147 | cards.push({ 148 | vod_id: href, 149 | vod_name: title, 150 | vod_pic: cover, 151 | vod_remarks: remarks, 152 | ext: { 153 | url: `${appConfig.site}${href}`, 154 | }, 155 | }) 156 | }) 157 | 158 | return jsonify({ 159 | list: cards, 160 | }) 161 | } 162 | -------------------------------------------------------------------------------- /XPTV/JS/age.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/age.js 2 | //老登 3 | const cheerio = createCheerio() 4 | const UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" 5 | const headers = { 6 | 'Referer': 'https://www.agedm.io/', 7 | 'Origin': 'https://www.agedm.io/', 8 | 'User-Agent': UA, 9 | } 10 | 11 | const appConfig = { 12 | ver: 1, 13 | title: "AGE", 14 | site: "https://www.agedm.io/#/", 15 | tabs: [{ 16 | name: '最近更新', 17 | ext: { 18 | id: 0, 19 | }, 20 | }] 21 | } 22 | 23 | async function getConfig() { 24 | return jsonify(appConfig) 25 | } 26 | 27 | async function getCards(ext) { 28 | ext = argsify(ext) 29 | let cards = [] 30 | let id = ext.id 31 | let page = ext.page || 1 32 | 33 | const url = `https://api.agedm.io/v2/catalog?genre=all&label=all&letter=all&order=time®ion=all&resource=all&season=all&status=all&year=all&size=20&page=${page}` 34 | 35 | const { data } = await $fetch.get(url, { 36 | headers 37 | }) 38 | 39 | argsify(data).videos?.forEach( each => { 40 | cards.push({ 41 | vod_id: `${each.id}`, 42 | vod_name: each.name, 43 | vod_pic: each.cover, 44 | vod_remarks: each.uptodate, 45 | ext: { 46 | url: `https://api.agedm.io/v2/detail/${each.id}`, 47 | }, 48 | }); 49 | }) 50 | 51 | return jsonify({ 52 | list: cards, 53 | }); 54 | } 55 | 56 | async function getTracks(ext) { 57 | ext = argsify(ext) 58 | let groups = [] 59 | let url = ext.url 60 | 61 | // 发送请求 62 | const { data } = await $fetch.get(url, { 63 | headers 64 | }); 65 | 66 | const json = argsify(data) 67 | const player_label_arr = json.player_label_arr 68 | const playlists = json.video.playlists 69 | const vip = json.player_jx.vip 70 | const zj = json.player_jx.zj 71 | const player_vip = json.player_vip 72 | 73 | for (var key in playlists) { 74 | if (!key.includes('m3u8')){ 75 | continue 76 | } 77 | let v = playlists[key] 78 | let group = { 79 | title: player_label_arr[key], 80 | tracks: [], 81 | } 82 | v.forEach( each => { 83 | if (each.length == 2) { 84 | let path = `${zj}${each[1]}` 85 | if (player_vip.hasOwnProperty(key)) { 86 | path = `${vip}${each[1]}` 87 | } 88 | group.tracks.push({ 89 | name: each[0], 90 | pan: '', 91 | ext: { 92 | url: path 93 | } 94 | }) 95 | } 96 | }) 97 | if (group.tracks.length > 0) { 98 | groups.push(group) 99 | } 100 | } 101 | 102 | return jsonify({ list: groups }) 103 | } 104 | 105 | async function getPlayinfo(ext) { 106 | ext = argsify(ext) 107 | let url = ext.url 108 | const { data } = await $fetch.get(url, { 109 | headers 110 | }) 111 | const m3u = data.match(/Vurl = '(.+?)'/)[1] 112 | return jsonify({ 'urls': [m3u] }) 113 | } 114 | 115 | async function search(ext) { 116 | ext = argsify(ext) 117 | let cards = []; 118 | 119 | let text = encodeURIComponent(ext.text) 120 | let page = ext.page || 1 121 | 122 | const url = `https://api.agedm.io/v2/search?query=${text}&page=${page}` 123 | const { data } = await $fetch.get(url, { 124 | headers 125 | }) 126 | 127 | argsify(data).data?.videos?.forEach( each => { 128 | cards.push({ 129 | vod_id: `${each.id}`, 130 | vod_name: each.name, 131 | vod_pic: each.cover, 132 | vod_remarks: each.uptodate, 133 | ext: { 134 | url: `https://api.agedm.io/v2/detail/${each.id}`, 135 | }, 136 | }); 137 | }) 138 | 139 | return jsonify({ 140 | list: cards, 141 | }); 142 | } 143 | -------------------------------------------------------------------------------- /XPTV/JS/huban.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/huban.js 2 | const cheerio = createCheerio() 3 | 4 | const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' 5 | 6 | const appConfig = { 7 | ver: 1, 8 | title: '虎斑', 9 | site: 'http://103.45.162.207:20720', 10 | tabs: [ 11 | { 12 | name: '電影', 13 | ext: { 14 | id: 1, 15 | }, 16 | }, 17 | { 18 | name: '劇集', 19 | ext: { 20 | id: 2, 21 | }, 22 | }, 23 | { 24 | name: '動漫', 25 | ext: { 26 | id: 4, 27 | }, 28 | }, 29 | { 30 | name: '綜藝', 31 | ext: { 32 | id: 3, 33 | }, 34 | }, 35 | { 36 | name: '短劇', 37 | ext: { 38 | id: 6, 39 | }, 40 | }, 41 | { 42 | name: '精片', 43 | ext: { 44 | id: 5, 45 | }, 46 | }, 47 | 48 | ], 49 | } 50 | 51 | async function getConfig() { 52 | return jsonify(appConfig) 53 | } 54 | 55 | async function getCards(ext) { 56 | 57 | ext = argsify(ext) 58 | let cards = [] 59 | let { page = 1, id } = ext 60 | 61 | const url = appConfig.site + `/index.php/vod/show/id/${id}/page/${page}.html` 62 | const { data } = await $fetch.get(url, { 63 | headers: { 64 | 'User-Agent': UA, 65 | }, 66 | }) 67 | 68 | const $ = cheerio.load(data) 69 | 70 | const videos = $('#main .module-item') 71 | videos.each((_, e) => { 72 | const href = $(e).find('.module-item-pic a').attr('href') 73 | const title = $(e).find('.module-item-pic a').attr('title') 74 | const cover = $(e).find('.module-item-pic img').attr('data-src') 75 | const remarks = $(e).find('.module-item-text').text() 76 | 77 | cards.push({ 78 | vod_id: href, 79 | vod_name: title, 80 | vod_pic: cover, 81 | vod_remarks: remarks, 82 | 83 | ext: { 84 | url: `${appConfig.site}${href}`, 85 | }, 86 | }) 87 | }) 88 | 89 | return jsonify({ 90 | list: cards, 91 | }) 92 | } 93 | 94 | async function getTracks(ext) { 95 | ext = argsify(ext) 96 | let tracks = [] 97 | let url = ext.url 98 | 99 | const { data } = await $fetch.get(url, { 100 | headers: { 101 | 'User-Agent': UA, 102 | }, 103 | }) 104 | 105 | const $ = cheerio.load(data) 106 | 107 | const playlist = $('.module-player-list .module-row-one') 108 | playlist.each((_, e) => { 109 | const panShareUrl = $(e).find('.module-row-title p').text() 110 | tracks.push({ 111 | name: '网盘', 112 | pan: panShareUrl, 113 | }) 114 | }) 115 | 116 | return jsonify({ 117 | list: [ 118 | { 119 | title: '默认分组', 120 | tracks, 121 | }, 122 | ], 123 | }) 124 | } 125 | 126 | async function getPlayinfo(ext) { 127 | return jsonify({ urls: [] }) 128 | } 129 | 130 | async function search(ext) { 131 | ext = argsify(ext) 132 | let cards = [] 133 | 134 | let text = encodeURIComponent(ext.text) 135 | let page = ext.page || 1 136 | let url = `${appConfig.site}/index.php/vod/search/page/${page}/wd/${text}.html` 137 | 138 | const { data } = await $fetch.get(url, { 139 | headers: { 140 | 'User-Agent': UA, 141 | }, 142 | }) 143 | 144 | const $ = cheerio.load(data) 145 | 146 | const videos = $('#main .module-search-item') 147 | videos.each((_, e) => { 148 | const href = $(e).find('.video-info-header h3 a').attr('href') 149 | const title = $(e).find('.video-info-header h3 a').attr('title') 150 | const cover = $(e).find('.module-item-pic img').attr('data-src') 151 | const remarks = $(e).find('.video-serial').text() 152 | 153 | cards.push({ 154 | vod_id: href, 155 | vod_name: title, 156 | vod_pic: cover, 157 | vod_remarks: remarks, 158 | ext: { 159 | url: `${appConfig.site}${href}`, 160 | }, 161 | }) 162 | }) 163 | 164 | return jsonify({ 165 | list: cards, 166 | }) 167 | } 168 | -------------------------------------------------------------------------------- /XPTV/JS/star2.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/star2.js 2 | const cheerio = createCheerio() 3 | 4 | const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' 5 | 6 | const appConfig = { 7 | ver: 1, 8 | title: 'star2', 9 | site: 'https://1.star2.cn', 10 | tabs: [ 11 | { 12 | name: '電影', 13 | ext: { 14 | id: 'mv', 15 | }, 16 | }, 17 | { 18 | name: '国劇', 19 | ext: { 20 | id: 'ju', 21 | }, 22 | }, 23 | { 24 | name: '外劇', 25 | ext: { 26 | id: 'wj', 27 | }, 28 | }, 29 | { 30 | name: '韩日', 31 | ext: { 32 | id: 'rh', 33 | }, 34 | }, 35 | { 36 | name: '英美', 37 | ext: { 38 | id: 'ym', 39 | }, 40 | }, 41 | { 42 | name: '短劇', 43 | ext: { 44 | id: 'dj', 45 | }, 46 | }, 47 | { 48 | name: '動漫', 49 | ext: { 50 | id: 'dm', 51 | }, 52 | }, 53 | { 54 | name: '綜藝', 55 | ext: { 56 | id: 'zy', 57 | }, 58 | }, 59 | ], 60 | } 61 | 62 | async function getConfig() { 63 | return jsonify(appConfig) 64 | } 65 | 66 | async function getCards(ext) { 67 | ext = argsify(ext) 68 | 69 | let cards = [] 70 | let { page = 1, id } = ext 71 | 72 | const url = appConfig.site + `/${id}_${page}` 73 | const { data } = await $fetch.get(url, { 74 | headers: { 75 | 'User-Agent': UA, 76 | }, 77 | }) 78 | 79 | const $ = cheerio.load(data) 80 | 81 | const videos = $('div.a') 82 | videos.each((_, e) => { 83 | const href = $(e).find('a.main').attr('href') 84 | const title = $(e).find('a.main').text() 85 | const match1 = title.match(/\.(.*?)$/); 86 | const remarks = match1 && match1[1] ? match1[1] : ''; 87 | const match = title.match(/】(.*?)\./); 88 | const dramaName = match && match[1] ? match[1] : title; 89 | cards.push({ 90 | vod_id: href, 91 | vod_name: dramaName, 92 | vod_remarks: remarks, 93 | ext: { 94 | url: `${appConfig.site}${href}`, 95 | }, 96 | }) 97 | }) 98 | 99 | return jsonify({ 100 | list: cards, 101 | }) 102 | } 103 | 104 | async function getTracks(ext) { 105 | ext = argsify(ext) 106 | let tracks = [] 107 | let url = ext.url 108 | 109 | const { data } = await $fetch.get(url, { 110 | headers: { 111 | 'User-Agent': UA, 112 | }, 113 | }) 114 | 115 | const $ = cheerio.load(data) 116 | 117 | const playlist = $('.dlipp-cont-bd') 118 | playlist.each((_, e) => { 119 | const panShareUrl = $(e).find('a').attr('href') 120 | tracks.push({ 121 | name: '网盘', 122 | pan: panShareUrl, 123 | }) 124 | }) 125 | 126 | return jsonify({ 127 | list: [ 128 | { 129 | title: '默认分组', 130 | tracks, 131 | }, 132 | ], 133 | }) 134 | } 135 | 136 | async function getPlayinfo(ext) { 137 | return jsonify({ urls: [] }) 138 | } 139 | 140 | async function search(ext) { 141 | ext = argsify(ext) 142 | let cards = [] 143 | 144 | let text = encodeURIComponent(ext.text) 145 | let page = ext.page || 1 146 | let url = `${appConfig.site}/search/?keyword=${text}&page=${page}` 147 | 148 | const { data } = await $fetch.get(url, { 149 | headers: { 150 | 'User-Agent': UA, 151 | }, 152 | }) 153 | 154 | const $ = cheerio.load(data) 155 | 156 | const videos = $('div.a') 157 | videos.each((_, e) => { 158 | const href = $(e).find('a.main').attr('href') 159 | const title = $(e).find('a.main').text() 160 | const match1 = title.match(/\.(.*?)$/); 161 | const remarks = match1 && match1[1] ? match1[1] : ''; 162 | const match = title.match(/】(.*?)\./); 163 | const dramaName = match && match[1] ? match[1] : title; 164 | cards.push({ 165 | vod_id: href, 166 | vod_name: dramaName, 167 | vod_remarks: remarks, 168 | ext: { 169 | url: `${appConfig.site}${href}`, 170 | }, 171 | }) 172 | }) 173 | 174 | return jsonify({ 175 | list: cards, 176 | }) 177 | } 178 | -------------------------------------------------------------------------------- /XPTV/JS/EXPORNTOONS.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/EXPORNTOONS.js 2 | const UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_2 like Mac OS X) AppleWebKit/604.1.14 (KHTML, like Gecko)' 3 | const cheerio = createCheerio() 4 | let appConfig = { 5 | ver: 1, 6 | title: 'exporntoons', 7 | site: 'https://exporntoons.net', 8 | tabs: [ 9 | { 10 | name: '最新', 11 | ui: 1, 12 | ext: { 13 | id: 'now', 14 | }, 15 | }, 16 | ], 17 | } 18 | 19 | async function getConfig() { 20 | return jsonify(appConfig) 21 | } 22 | 23 | async function getCards(ext) { 24 | ext = argsify(ext) 25 | let cards = [] 26 | let { page = 1, id } = ext 27 | 28 | const url = appConfig.site + `/${id}?p=${page}` 29 | 30 | const { data } = await $fetch.get(url, { 31 | headers: { 32 | 'User-Agent': UA, 33 | }, 34 | }) 35 | if (data.includes('Just a moment...')) { 36 | $utils.openSafari(url, UA) 37 | } 38 | 39 | const $ = cheerio.load(data) 40 | 41 | const videos = $('.item') 42 | 43 | videos.each((_, e) => { 44 | const href = $(e).find('.item_link').attr('href') 45 | const title = $(e).find('.title').text().trim() 46 | const cover = $(e).find('.i_img img').attr('data-src') 47 | let obj = { 48 | vod_id: href, 49 | vod_name: title, 50 | vod_pic: cover, 51 | ui: 1, 52 | ext: { 53 | url: `${appConfig.site}${href}`, 54 | }, 55 | } 56 | 57 | cards.push(obj) 58 | }) 59 | 60 | return jsonify({ 61 | list: cards, 62 | }) 63 | } 64 | async function getTracks(ext) { 65 | ext = argsify(ext) 66 | let url = ext.url 67 | let tracks = [] 68 | 69 | const { data } = await $fetch.get(url, { 70 | headers: { 71 | 'User-Agent': UA, 72 | }, 73 | }) 74 | 75 | const playlistMatch = data.match(/window\.playlist\s*=\s*({[^;]+});/) 76 | if (playlistMatch && playlistMatch[1]) { 77 | try { 78 | const playlist = JSON.parse(playlistMatch[1]) 79 | 80 | if (playlist.sources && Array.isArray(playlist.sources)) { 81 | playlist.sources.forEach(source => { 82 | if (source.file && source.label) { 83 | tracks.push({ 84 | name: source.label + 'p', 85 | pan: '', 86 | ext: { 87 | url: source.file, 88 | type: source.type || 'mp4' 89 | } 90 | }) 91 | } 92 | }) 93 | } 94 | 95 | 96 | if (tracks.length > 0) { 97 | 98 | const defaultSource = playlist.sources.find(source => source.default) || playlist.sources[0] 99 | if (defaultSource) { 100 | tracks.unshift({ 101 | name: '自动', 102 | pan: '', 103 | ext: { 104 | url: defaultSource.file, 105 | type: defaultSource.type || 'mp4' 106 | } 107 | }) 108 | } 109 | } 110 | 111 | } catch (error) { 112 | console.error('解析playlist失败:', error) 113 | } 114 | } 115 | 116 | return jsonify({ 117 | list: [ 118 | { 119 | title: '视频质量', 120 | tracks, 121 | }, 122 | ], 123 | }) 124 | } 125 | 126 | async function getPlayinfo(ext) { 127 | ext = argsify(ext) 128 | const url = ext.url 129 | const type = ext.type || 'mp4' 130 | 131 | return jsonify({ 132 | urls: [url], 133 | type: type 134 | }) 135 | } 136 | async function search(ext) { 137 | ext = argsify(ext) 138 | let cards = [] 139 | 140 | let text = encodeURIComponent(ext.text) 141 | let page = ext.page || 1 142 | let url = `${appConfig.site}/video/${text}?p=${page}` 143 | const { data } = await $fetch.get(url, { 144 | headers: { 145 | 'User-Agent': UA, 146 | }, 147 | }) 148 | const $ = cheerio.load(data) 149 | 150 | const videos = $('.item') 151 | 152 | videos.each((_, e) => { 153 | const href = $(e).find('.item_link').attr('href') 154 | const title = $(e).find('.title').text().trim() 155 | const cover = $(e).find('.i_img img').attr('data-src') 156 | let obj = { 157 | vod_id: href, 158 | vod_name: title, 159 | vod_pic: cover, 160 | ui: 1, 161 | ext: { 162 | url: `${appConfig.site}${href}`, 163 | }, 164 | } 165 | cards.push(obj) 166 | }) 167 | 168 | return jsonify({ 169 | list: cards, 170 | }) 171 | } 172 | -------------------------------------------------------------------------------- /XPTV/JS/wogg.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/wogg.js 2 | const cheerio = createCheerio() 3 | const UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_2 like Mac OS X) AppleWebKit/604.1.14 (KHTML, like Gecko)' 4 | 5 | const appConfig = { 6 | ver: 1, 7 | title: '玩偶哥哥', 8 | site: 'https://www.wogg.one', 9 | 10 | tabs: [ 11 | { 12 | name: '电影', 13 | ext: { 14 | id: '1', 15 | }, 16 | }, 17 | { 18 | name: '剧集', 19 | ext: { 20 | id: '2', 21 | }, 22 | }, 23 | { 24 | name: '臻彩视界', 25 | ext: { 26 | id: '44', 27 | }, 28 | }, 29 | { 30 | name: '动漫', 31 | ext: { 32 | id: '3', 33 | }, 34 | }, 35 | { 36 | name: '综艺', 37 | ext: { 38 | id: '4', 39 | }, 40 | }, 41 | { 42 | name: '短剧', 43 | ext: { 44 | id: '6', 45 | }, 46 | }, 47 | { 48 | name: '音乐', 49 | ext: { 50 | id: '5', 51 | }, 52 | }, 53 | ], 54 | } 55 | 56 | async function getConfig() { 57 | return jsonify(appConfig) 58 | } 59 | 60 | async function getCards(ext) { 61 | ext = argsify(ext) 62 | let cards = [] 63 | let { page = 1, id } = ext 64 | 65 | const url = appConfig.site + `/vodshow/${id}--------${page}---.html` 66 | 67 | const { data } = await $fetch.get(url, { 68 | headers: { 69 | 'User-Agent': UA, 70 | }, 71 | }) 72 | 73 | const $ = cheerio.load(data) 74 | 75 | const t1 = $('title').text() 76 | if (t1 === 'Just a moment...') { 77 | $utils.openSafari(appConfig.site, UA) 78 | } 79 | 80 | const videos = $('.module-item') 81 | videos.each((_, e) => { 82 | const href = $(e).find('.module-item-pic a').attr('href') 83 | const title = $(e).find('.module-item-pic img').attr('alt') 84 | const cover = $(e).find('.module-item-pic img').attr('data-src') 85 | const text = $(e).find('.module-item-text').eq(0).text() 86 | //const lb = $(e).find('.module-item-caption span').eq(1).text().replace('玩偶', '') 87 | const dq = $(e).find('.module-item-caption span').eq(2).text().replace(/中国大陆|中国中国大陆/, '国产').replace('中国香港', '港剧').replace('中国台湾', '台剧') 88 | 89 | const remarks = (`${dq} ${text}`).trim() 90 | let obj = { 91 | vod_id: href, 92 | vod_name: title, 93 | vod_pic: cover, 94 | vod_remarks: remarks, 95 | 96 | ext: { 97 | url: `${appConfig.site}${href}`, 98 | }, 99 | } 100 | 101 | cards.push(obj) 102 | }) 103 | 104 | return jsonify({ 105 | list: cards, 106 | }) 107 | } 108 | 109 | async function getTracks(ext) { 110 | ext = argsify(ext) 111 | let tracks = [] 112 | let url = ext.url 113 | 114 | const { data } = await $fetch.get(url, { 115 | headers: { 116 | 'User-Agent': UA, 117 | }, 118 | }) 119 | 120 | const $ = cheerio.load(data) 121 | 122 | const playlist = $('.module-row-title') 123 | playlist.each((_, e) => { 124 | const name = $(e).find('h4').text().replace(' - 玩偶哥哥', '') 125 | const panShareUrl = $(e).find('p').text() 126 | 127 | tracks.push({ 128 | name: name, 129 | pan: panShareUrl, 130 | }) 131 | }) 132 | 133 | return jsonify({ 134 | list: [ 135 | { 136 | title: '默认分组', 137 | tracks, 138 | }, 139 | ], 140 | }) 141 | } 142 | 143 | async function getPlayinfo(ext) { 144 | return jsonify({ urls: [] }) 145 | } 146 | 147 | async function search(ext) { 148 | ext = argsify(ext) 149 | let cards = [] 150 | 151 | let text = encodeURIComponent(ext.text) 152 | let page = ext.page || 1 153 | let url = `${appConfig.site}/vodsearch/${text}----------${page}---.html` 154 | 155 | const { data } = await $fetch.get(url, { 156 | headers: { 157 | 'User-Agent': UA, 158 | }, 159 | }) 160 | 161 | const $ = cheerio.load(data) 162 | 163 | const videos = $('.module-search-item') 164 | videos.each((_, e) => { 165 | const href = $(e).find('.video-serial').attr('href') 166 | const title = $(e).find('.lazyload').attr('alt') 167 | const cover = $(e).find('.lazyload').attr('data-src') 168 | const remarks = $(e).find('.video-serial').text() 169 | cards.push({ 170 | vod_id: href, 171 | vod_name: title, 172 | vod_pic: cover, 173 | vod_remarks: remarks, 174 | 175 | ext: { 176 | url: `${appConfig.site}${href}`, 177 | }, 178 | }) 179 | }) 180 | return jsonify({ 181 | list: cards, 182 | }) 183 | } 184 | -------------------------------------------------------------------------------- /XPTV/JS/koreapornmovie.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/KoreaPornMovie.js 2 | //来自群友“夢” 3 | const cheerio = createCheerio() 4 | 5 | const UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.1 Mobile/15E148 Safari/604.1' 6 | 7 | let appConfig = { 8 | ver: 1, 9 | title: 'KoreaPornMovie', 10 | site: 'https://koreanpornmovie.com', 11 | tabs: [ 12 | { 13 | name: '首页', 14 | ext: { 15 | tip: '', 16 | }, 17 | }, 18 | { 19 | name: '三级', 20 | ext: { 21 | tip: '18-movies', 22 | }, 23 | }, 24 | ], 25 | } 26 | 27 | async function getConfig() { 28 | return jsonify(appConfig) 29 | } 30 | 31 | async function getCards(ext) { 32 | ext = argsify(ext) 33 | let cards = [] 34 | let { tip, page = 1 } = ext 35 | let url = `${appConfig.site}/page/${page}/` 36 | if (tip) { 37 | url = `${appConfig.site}/tag/${tip}/page/${page}/` 38 | } 39 | const { data } = await $fetch.get(url, { 40 | headers: { 41 | 'User-Agent': UA, 42 | }, 43 | }) 44 | 45 | const $ = cheerio.load(data) 46 | 47 | $('#main .videos-list article').each((_, element) => { 48 | const href = $(element).find('a').attr('href') 49 | const title = $(element).find('a').attr('title') 50 | const cover = $(element).find('img').attr('data-src') || $(element).find('img').attr('src') 51 | const duration = $(element).find('.duration').text() 52 | cards.push({ 53 | vod_id: href, 54 | vod_name: title, 55 | vod_pic: cover, 56 | vod_duration: duration, 57 | ext: { 58 | url: href, 59 | }, 60 | }) 61 | }) 62 | 63 | return jsonify({ 64 | list: cards, 65 | }) 66 | } 67 | 68 | async function getTracks(ext) { 69 | ext = argsify(ext) 70 | let tracks = [] 71 | let url = ext.url 72 | 73 | const { data } = await $fetch.get(url, { 74 | headers: { 75 | 'User-Agent': UA, 76 | }, 77 | }) 78 | 79 | const $ = cheerio.load(data) 80 | const videourl = $('.video-player').find('meta[itemprop="contentURL"]').attr('content') || $(element).find('video source[type="video/mp4"]').attr('src') 81 | if (videourl) { 82 | tracks.push({ 83 | name: '播放', 84 | ext: { 85 | url: videourl, 86 | }, 87 | }) 88 | } 89 | return jsonify({ 90 | list: [ 91 | { 92 | title: '默认分组', 93 | tracks, 94 | }, 95 | ], 96 | }) 97 | } 98 | 99 | async function getPlayinfo(ext) { 100 | ext = argsify(ext) 101 | const playUrl = ext.url 102 | 103 | return jsonify({ 104 | urls: [playUrl], 105 | headers: [{ 106 | 'User-Agent': UA, 107 | 'Referer': 'https://koreanpornmovie.com/' 108 | }] 109 | }) 110 | } 111 | 112 | async function search(ext) { 113 | ext = argsify(ext) 114 | let cards = [] 115 | let text = encodeURIComponent(ext.text) 116 | let page = ext.page || 1 117 | let url = `${appConfig.site}/page/${page}/?s=${text}` 118 | 119 | const { data } = await $fetch.get(url, { 120 | headers: { 121 | 'User-Agent': UA, 122 | }, 123 | }) 124 | 125 | const $ = cheerio.load(data) 126 | 127 | $('section #main article').each((_, element) => { 128 | const href = $(element).find('a').attr('href') 129 | const title = $(element).find('a').attr('title') 130 | const cover = $(element).find('img').attr('data-src') || $(element).find('img').attr('src') 131 | const duration = $(element).find('.duration').text() 132 | cards.push({ 133 | vod_id: href, 134 | vod_name: title, 135 | vod_pic: cover, 136 | vod_duration: duration, 137 | ext: { 138 | url: href, 139 | }, 140 | }) 141 | }) 142 | 143 | return jsonify({ 144 | list: cards, 145 | }) 146 | } 147 | -------------------------------------------------------------------------------- /XPTV/JS/xzys.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/xzys.js 2 | const cheerio = createCheerio() 3 | const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' 4 | 5 | const appConfig = { 6 | ver: 1, 7 | title: '校长影视', 8 | site: 'https://xzys.fun', 9 | 10 | tabs: [ 11 | { 12 | name: '电视剧', 13 | ext: { 14 | id: 'dsj', 15 | }, 16 | }, 17 | { 18 | name: '电影', 19 | ext: { 20 | id: 'dy', 21 | }, 22 | }, 23 | { 24 | name: '动漫', 25 | ext: { 26 | id: 'dm', 27 | }, 28 | }, 29 | { 30 | name: '纪录片', 31 | ext: { 32 | id: 'jlp', 33 | }, 34 | }, 35 | { 36 | name: '综艺', 37 | ext: { 38 | id: 'zy', 39 | }, 40 | }, 41 | ], 42 | } 43 | 44 | async function getConfig() { 45 | return jsonify(appConfig) 46 | } 47 | 48 | async function getCards(ext) { 49 | ext = argsify(ext) 50 | let cards = [] 51 | let { page = 1, id } = ext 52 | 53 | const url = appConfig.site + `/${id}.html?page=${page}` 54 | 55 | const { data } = await $fetch.get(url, { 56 | headers: { 57 | 'User-Agent': UA, 58 | }, 59 | }) 60 | 61 | const $ = cheerio.load(data) 62 | 63 | const videos = $('.container .list-boxes .left_ly a') 64 | videos.each((_, e) => { 65 | const href = $(e).attr('href') 66 | const title = $(e).find('img').attr('alt') 67 | const cover = $(e).find('img').attr('src') 68 | if (title === '网盘选择问题') return 69 | let obj = { 70 | vod_id: href, 71 | vod_name: title, 72 | vod_pic: cover, 73 | vod_remarks: '', 74 | 75 | ext: { 76 | url: `${appConfig.site}${href}`, 77 | }, 78 | } 79 | 80 | cards.push(obj) 81 | }) 82 | 83 | return jsonify({ 84 | list: cards, 85 | }) 86 | } 87 | 88 | async function getTracks(ext) { 89 | ext = argsify(ext) 90 | let tracks = [] 91 | let url = ext.url 92 | 93 | const { data } = await $fetch.get(url, { 94 | headers: { 95 | 'User-Agent': UA, 96 | }, 97 | }) 98 | 99 | const $ = cheerio.load(data) 100 | 101 | const playlist = $('.col-md-9 .article-box p') 102 | playlist.each((_, e) => { 103 | const name = $(e).find('.btn-info').text() 104 | const panShareUrl = $(e).find('a').attr('href') 105 | if (!/夸克|阿里|UC|115|天翼/.test(name)) return 106 | tracks.push({ 107 | name: name.trim(), 108 | pan: panShareUrl, 109 | }) 110 | }) 111 | 112 | return jsonify({ 113 | list: [ 114 | { 115 | title: '默认分组', 116 | tracks, 117 | }, 118 | ], 119 | }) 120 | } 121 | 122 | async function getPlayinfo(ext) { 123 | return jsonify({ urls: [] }) 124 | } 125 | 126 | async function search(ext) { 127 | ext = argsify(ext) 128 | let cards = [] 129 | 130 | let text = encodeURIComponent(ext.text) 131 | let page = ext.page || 1 132 | let url = `${appConfig.site}/search.html?keyword=${text}&page=${page}` 133 | 134 | const { data } = await $fetch.get(url, { 135 | headers: { 136 | 'User-Agent': UA, 137 | }, 138 | }) 139 | 140 | const $ = cheerio.load(data) 141 | 142 | const videos = $('#container .list-boxes .left_ly a') 143 | videos.each((_, e) => { 144 | const href = $(e).attr('href') 145 | const title = $(e).find('img').attr('alt') 146 | const cover = $(e).find('img').attr('src') 147 | 148 | cards.push({ 149 | vod_id: href, 150 | vod_name: title, 151 | vod_pic: cover, 152 | vod_remarks: '', 153 | 154 | ext: { 155 | url: `${appConfig.site}${href}`, 156 | }, 157 | }) 158 | }) 159 | return jsonify({ 160 | list: cards, 161 | }) 162 | } 163 | -------------------------------------------------------------------------------- /XPTV/JS/avdb.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/Yswag/xptv-extensions/main/js/avdb.js 2 | const UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_2 like Mac OS X) AppleWebKit/604.1.14 (KHTML, like Gecko)' 3 | 4 | let appConfig = { 5 | ver: 20251202, 6 | title: 'avdb', 7 | site: 'https://avdbapi.com/api.php/provide/vod', 8 | } 9 | 10 | async function getConfig() { 11 | let config = appConfig 12 | config.tabs = await getTabs() 13 | return jsonify(appConfig) 14 | } 15 | 16 | async function getTabs() { 17 | let tabs = [] 18 | let url = appConfig.site 19 | 20 | const { data } = await $fetch.get(url, { 21 | headers: { 22 | 'User-Agent': UA, 23 | }, 24 | }) 25 | 26 | argsify(data).class.forEach((e) => { 27 | tabs.push({ 28 | id: e.type_id, 29 | name: e.type_name, 30 | ext: { 31 | id: e.type_id, 32 | }, 33 | ui: 1, 34 | }) 35 | }) 36 | 37 | return tabs 38 | } 39 | 40 | async function getCards(ext) { 41 | ext = argsify(ext) 42 | let cards = [] 43 | let { id, page = 1 } = ext 44 | 45 | try { 46 | const url = appConfig.site + `?t=${id}&ac=detail&pg=${page}` 47 | 48 | const { data } = await $fetch.get(url, { 49 | headers: { 50 | 'User-Agent': UA, 51 | }, 52 | }) 53 | 54 | argsify(data).list.forEach((e) => { 55 | cards.push({ 56 | vod_id: `${e.id}`, 57 | vod_name: e.name, 58 | vod_pic: e.poster_url, 59 | vod_remarks: e.tag, 60 | vod_pubdate: e.created_at, 61 | vod_duration: e.time, 62 | ext: { 63 | id: `${e.id}`, 64 | }, 65 | }) 66 | }) 67 | 68 | return jsonify({ 69 | list: cards, 70 | }) 71 | } catch (error) { 72 | $print(error) 73 | } 74 | } 75 | 76 | async function getTracks(ext) { 77 | ext = argsify(ext) 78 | let tracks = [] 79 | let id = ext.id 80 | let url = appConfig.site + `?ac=detail&ids=${id}` 81 | 82 | const { data } = await $fetch.get(url, { 83 | headers: { 84 | 'User-Agent': UA, 85 | }, 86 | }) 87 | 88 | let vod_play_url = argsify(data).list[0].episodes.server_data.Full.link_embed 89 | tracks.push({ 90 | name: argsify(data).list[0].episodes.server_name, 91 | pan: '', 92 | ext: { 93 | url: vod_play_url, 94 | }, 95 | }) 96 | 97 | return jsonify({ 98 | list: [ 99 | { 100 | title: '默认分组', 101 | tracks, 102 | }, 103 | ], 104 | }) 105 | } 106 | 107 | async function getPlayinfo(ext) { 108 | ext = argsify(ext) 109 | let url = ext.url 110 | 111 | const { data } = await $fetch.get(url, { 112 | headers: { 113 | 'User-Agent': UA, 114 | Referer: `https://avdbapi.com/`, 115 | }, 116 | }) 117 | let obj = data.match(/playerInstance\.setup\(\s*(\{[\s\S]*?\})\s*\);/)[1] 118 | const aboutlink = obj.match(/aboutlink:\s*["']([^"']+)["']/)[1] 119 | const file = obj.match(/file:\s*["']([^"']+)["']/)[1] 120 | 121 | let playUrl = aboutlink + file 122 | 123 | return jsonify({ urls: [playUrl], headers: [{ 'User-Agent': UA, Referer: `${url}/` }] }) 124 | } 125 | 126 | async function search(ext) { 127 | ext = argsify(ext) 128 | let cards = [] 129 | 130 | const text = encodeURIComponent(ext.text) 131 | const page = ext.page || 1 132 | const url = `${appConfig.site}?ac=detail&wd=${text}&pg=${page}` 133 | 134 | const { data } = await $fetch.get(url, { 135 | headers: { 136 | 'User-Agent': UA, 137 | }, 138 | }) 139 | 140 | argsify(data).list.forEach((e) => { 141 | cards.push({ 142 | vod_id: `${e.id}`, 143 | vod_name: e.name, 144 | vod_pic: e.poster_url, 145 | vod_remarks: e.tag, 146 | vod_pubdate: e.created_at, 147 | vod_duration: e.time, 148 | ext: { 149 | id: `${e.id}`, 150 | }, 151 | }) 152 | }) 153 | 154 | return jsonify({ 155 | list: cards, 156 | }) 157 | } 158 | -------------------------------------------------------------------------------- /XPTV/JS/ole.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/ole.js 2 | const cheerio = createCheerio() 3 | const UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" 4 | const headers = { 5 | 'Referer': 'https://www.olehdtv.com/', 6 | 'Origin': 'https://www.olehdtv.com', 7 | 'User-Agent': UA, 8 | } 9 | 10 | const appConfig = { 11 | ver: 1, 12 | title: "欧乐影院", 13 | site: "https://www.olehdtv.com", 14 | tabs: [{ 15 | name: '首页', 16 | ext: { 17 | url: '/index.php', 18 | hasMore: false 19 | }, 20 | }, { 21 | name: '电影', 22 | ext: { 23 | url: '/index.php/vod/show/id/1.html' 24 | }, 25 | }, { 26 | name: '电视剧', 27 | ext: { 28 | url: '/index.php/vod/show/id/2.html', 29 | }, 30 | }, { 31 | name: '综艺', 32 | ext: { 33 | url: '/index.php/vod/show/id/3.html', 34 | }, 35 | }, { 36 | name: '动漫', 37 | ext: { 38 | url: '/index.php/vod/show/id/4.html' 39 | }, 40 | }] 41 | } 42 | 43 | async function getConfig() { 44 | return jsonify(appConfig) 45 | } 46 | 47 | async function getCards(ext) { 48 | ext = argsify(ext) 49 | let cards = [] 50 | let url = ext.url 51 | let page = ext.page || 1 52 | let hasMore = ext.hasMore || true 53 | 54 | if (!hasMore && page > 1) { 55 | return jsonify({ 56 | list: cards, 57 | }) 58 | } 59 | 60 | if (page > 1) { 61 | url = appConfig.site + url.replace('.html', `/page/${page}.html`) 62 | } else { 63 | url = appConfig.site + url 64 | } 65 | 66 | const { data } = await $fetch.get(url, { 67 | headers 68 | }) 69 | 70 | const $ = cheerio.load(data) 71 | $('.vodlist_item > a').each((_, each) => { 72 | const path = $(each).attr('href') 73 | cards.push({ 74 | vod_id: path, 75 | vod_name: $(each).attr('title'), 76 | vod_pic: $(each).attr('data-original'), 77 | vod_remarks: $(each).find('span.text_right > em.voddate').text(), 78 | ext: { 79 | url: appConfig.site + path, 80 | }, 81 | }) 82 | }) 83 | 84 | return jsonify({ 85 | list: cards, 86 | }) 87 | } 88 | 89 | async function getTracks(ext) { 90 | const { url } = argsify(ext) 91 | let groups = [] 92 | 93 | const { data } = await $fetch.get(url, { 94 | headers 95 | }) 96 | 97 | $print('***data: ' + data) 98 | const $ = cheerio.load(data) 99 | let group = { 100 | title: '在线', 101 | tracks: [] 102 | } 103 | $('.content_playlist.list_scroll > li > a').each((_, each) => { 104 | group.tracks.push({ 105 | name: $(each).text(), 106 | pan: '', 107 | ext: { 108 | url: appConfig.site + $(each).attr('href') 109 | } 110 | }) 111 | }) 112 | 113 | if (group.tracks.length > 0) { 114 | groups.push(group) 115 | } 116 | 117 | return jsonify({ list: groups }) 118 | } 119 | 120 | async function getPlayinfo(ext) { 121 | const { url } = argsify(ext) 122 | const { data } = await $fetch.get(url, { 123 | headers 124 | }) 125 | const obj = JSON.parse(data.match(/player_aaaa=(.+?)<\/script>/)[1]) 126 | const m3u = obj.url 127 | $print(`***m3u: ${m3u}`) 128 | return jsonify({ 'urls': [m3u] }) 129 | } 130 | 131 | async function search(ext) { 132 | ext = argsify(ext) 133 | let cards = []; 134 | 135 | let text = encodeURIComponent(ext.text) 136 | let page = ext.page || 1 137 | if (page > 1) { 138 | return jsonify({ 139 | list: cards, 140 | }) 141 | } 142 | 143 | const url = appConfig.site + `/index.php/vod/search.html?wd=${text}&submit=` 144 | const { data } = await $fetch.get(url, { 145 | headers 146 | }) 147 | 148 | const $ = cheerio.load(data) 149 | $('a.vodlist_thumb').each((_, each) => { 150 | const path = $(each).attr('href') 151 | cards.push({ 152 | vod_id: path, 153 | vod_name: $(each).attr('title'), 154 | vod_pic: $(each).attr('data-original'), 155 | vod_remarks: $(each).find('span.text_right').text(), 156 | ext: { 157 | url: appConfig.site + path, 158 | }, 159 | }) 160 | }) 161 | 162 | return jsonify({ 163 | list: cards, 164 | }) 165 | } 166 | 167 | function dictToURI(dict) { 168 | var str = []; 169 | for(var p in dict){ 170 | str.push(encodeURIComponent(p) + "=" + encodeURIComponent(dict[p])); 171 | } 172 | return str.join("&"); 173 | } 174 | -------------------------------------------------------------------------------- /XPTV/JS/yunpanres.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/Yswag/xptv-extensions/main/js/yunpanres.js 2 | const cheerio = createCheerio() 3 | 4 | const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' 5 | 6 | const appConfig = { 7 | ver: 1, 8 | title: '云盘资源网', 9 | site: 'https://res.yunpan.win', 10 | tabs: [ 11 | { 12 | name: '全部', 13 | ext: { 14 | id: '', 15 | }, 16 | }, 17 | { 18 | name: '电影', 19 | ext: { 20 | id: '电影', 21 | }, 22 | }, 23 | { 24 | name: '电视剧', 25 | ext: { 26 | id: '电视剧', 27 | }, 28 | }, 29 | { 30 | name: '动画', 31 | ext: { 32 | id: '动画', 33 | }, 34 | }, 35 | { 36 | name: '纪录片', 37 | ext: { 38 | id: '纪录片', 39 | }, 40 | }, 41 | { 42 | name: '综艺', 43 | ext: { 44 | id: '综艺', 45 | }, 46 | }, 47 | ], 48 | } 49 | 50 | async function getConfig() { 51 | return jsonify(appConfig) 52 | } 53 | 54 | async function getCards(ext) { 55 | ext = argsify(ext) 56 | let cards = [] 57 | let { page = 1, id } = ext 58 | id = encodeURIComponent(id) 59 | 60 | const url = appConfig.site + `/?PageIndex=${page}&PageSize=50&Keyword=&Type=${id}` 61 | 62 | const { data } = await $fetch.get(url, { 63 | headers: { 64 | 'User-Agent': UA, 65 | }, 66 | }) 67 | 68 | const $ = cheerio.load(data) 69 | 70 | const videos = $('.col') 71 | videos.each((_, e) => { 72 | const action = $(e).find('.card-link').eq(1).attr('onclick') 73 | const panUrl = action.match(/open\(\'(.*)\'\)/)[1] 74 | 75 | const title = $(e).find('h5.card-title').text() 76 | const panType = $(e).find('h5.card-title span').text() 77 | const name = title.replace(panType, '') 78 | 79 | const cover = $(e).find('img').attr('src') 80 | cards.push({ 81 | vod_id: panUrl, 82 | vod_name: name, 83 | vod_pic: `${appConfig.site}${cover}`, 84 | vod_remarks: panType, 85 | ext: { 86 | name, 87 | url: panUrl, 88 | }, 89 | }) 90 | }) 91 | 92 | return jsonify({ 93 | list: cards, 94 | }) 95 | } 96 | 97 | async function getTracks(ext) { 98 | ext = argsify(ext) 99 | let { url, name } = ext 100 | 101 | return jsonify({ 102 | list: [ 103 | { 104 | title: '默认分组', 105 | tracks: [ 106 | { 107 | name, 108 | pan: url, 109 | }, 110 | ], 111 | }, 112 | ], 113 | }) 114 | } 115 | 116 | async function getPlayinfo(ext) { 117 | return jsonify({ urls: [] }) 118 | } 119 | 120 | async function search(ext) { 121 | ext = argsify(ext) 122 | let cards = [] 123 | 124 | let text = encodeURIComponent(ext.text) 125 | let page = ext.page || 1 126 | let url = `${appConfig.site}/?PageIndex=${page}&PageSize=50&Keyword=${text}` 127 | 128 | const { data } = await $fetch.get(url, { 129 | headers: { 130 | 'User-Agent': UA, 131 | }, 132 | }) 133 | 134 | const $ = cheerio.load(data) 135 | 136 | const videos = $('.col') 137 | videos.each((_, e) => { 138 | const action = $(e).find('.card-link').eq(1).attr('onclick') 139 | const panUrl = action.match(/open\(\'(.*)\'\)/)[1] 140 | 141 | const title = $(e).find('h5.card-title').text() 142 | const panType = $(e).find('h5.card-title span').text() 143 | const name = title.replace(panType, '') 144 | 145 | const cover = $(e).find('img').attr('src') 146 | cards.push({ 147 | vod_id: panUrl, 148 | vod_name: name, 149 | vod_pic: `${appConfig.site}${cover}`, 150 | vod_remarks: panType, 151 | ext: { 152 | name, 153 | url: panUrl, 154 | }, 155 | }) 156 | }) 157 | 158 | return jsonify({ 159 | list: cards, 160 | }) 161 | } 162 | -------------------------------------------------------------------------------- /XPTV/JS/ystt.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/ystt.js 2 | //来自‘夢’ 3 | const cheerio = createCheerio(); 4 | 5 | const UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_2_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.2.1 Mobile/15E148 Safari/604.1'; 6 | 7 | let appConfig = { 8 | ver: 1, 9 | title: '影视天堂', 10 | site: 'https://ysttv.com', 11 | tabs: [ 12 | { name: '电影', ext: { id: 1 } }, 13 | { name: '电视', ext: { id: 2 } }, 14 | { name: '陆剧', ext: { id: 2, area: '大陆' } }, 15 | { name: '台剧', ext: { id: 2, area: '台湾' } }, 16 | { name: '香剧', ext: { id: 2, area: '香港' } }, 17 | { name: '美剧', ext: { id: 2, area: '美国' } }, 18 | { name: '韩剧', ext: { id: 2, area: '韩国' } }, 19 | { name: '日剧', ext: { id: 2, area: '日本' } }, 20 | { name: '综艺', ext: { id: 3 } }, 21 | { name: '动漫', ext: { id: 4 } }, 22 | { name: '短剧', ext: { id: 5 } } 23 | ] 24 | }; 25 | 26 | async function getConfig() { 27 | return JSON.stringify(appConfig); 28 | } 29 | 30 | async function getCards(ext) { 31 | ext = JSON.parse(ext); 32 | let cards = []; 33 | let { id, area, page = 1 } = ext; 34 | 35 | let url = `${appConfig.site}/library/index/`; 36 | url += area 37 | ? `c/${id}/t/all/y/all/a/${area}/s/1/page/${page}` 38 | : `c/${id}/t/all/y/all/s/1/page/${page}`; 39 | 40 | const { data } = await $fetch.get(url, { 41 | headers: { 'User-Agent': UA } 42 | }); 43 | 44 | const $ = cheerio.load(data); 45 | 46 | $('main ul.mb-5 > li').each((_, element) => { 47 | if ($(element).find('.subtitle').text().includes('伦理')) return; 48 | const href = $(element).find('a').attr('href'); 49 | const pic = $(element).find('img').attr('data-src') || $(element).find('img').attr('src'); 50 | const name = $(element).find('a').attr('title'); 51 | const remark = parseFloat($(element).find('.tag.bg-dx-blue').text()).toFixed(1) || $(element).find('.text-white').text(); 52 | cards.push({ 53 | vod_id: href, 54 | vod_name: name, 55 | vod_pic: pic, 56 | vod_remarks: remark, 57 | ext: { url: `${appConfig.site}${href}` } 58 | }); 59 | }); 60 | 61 | return JSON.stringify({ list: cards }); 62 | } 63 | 64 | async function getTracks(ext) { 65 | ext = JSON.parse(ext); 66 | let list = []; 67 | let url = ext.url; 68 | 69 | const { data } = await $fetch.get(url, { 70 | headers: { 'User-Agent': UA } 71 | }); 72 | 73 | const $ = cheerio.load(data); 74 | let tracks = []; 75 | 76 | $('.overflow-auto > ul > li').each((_, element) => { 77 | const name = $(element).find('a').text().trim(); 78 | const href = $(element).find('a').attr('href'); 79 | tracks.push({ 80 | name: name, 81 | pan: '', 82 | ext: { url: `${appConfig.site}${href}` } 83 | }); 84 | }); 85 | 86 | list.push({ 87 | title: '默认分组', 88 | tracks: tracks 89 | }); 90 | 91 | return JSON.stringify({ list: list }); 92 | } 93 | 94 | async function getPlayinfo(ext) { 95 | ext = JSON.parse(ext); 96 | const url = ext.url; 97 | 98 | const { data } = await $fetch.get(url, { 99 | headers: { 'User-Agent': UA } 100 | }); 101 | 102 | const $ = cheerio.load(data); 103 | const playUrl = $('#mse').attr('data-url'); 104 | 105 | return JSON.stringify({ urls: [playUrl], headers: [{ 'User-Agent': UA }] }); 106 | } 107 | 108 | async function search(ext) { 109 | ext = JSON.parse(ext); 110 | let cards = []; 111 | 112 | let text = encodeURIComponent(ext.text); 113 | let page = ext.page || 1; 114 | let url = `${appConfig.site}/search/index/type/1/keyword/${text}/page/${page}`; 115 | 116 | const { data } = await $fetch.get(url, { 117 | headers: { 'User-Agent': UA } 118 | }); 119 | 120 | const $ = cheerio.load(data); 121 | 122 | $('main ul.grid > li').each((_, element) => { 123 | const href = $(element).find('a').attr('href'); 124 | const pic = $(element).find('img').attr('data-src') || $(element).find('img').attr('src'); 125 | const name = $(element).find('a').attr('title'); 126 | cards.push({ 127 | vod_id: href, 128 | vod_name: name, 129 | vod_pic: pic, 130 | vod_remarks: '', 131 | ext: { url: `${appConfig.site}${href}` } 132 | }); 133 | }); 134 | 135 | return JSON.stringify({ list: cards }); 136 | } 137 | -------------------------------------------------------------------------------- /XPTV/JS/kbjfan.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/Yswag/xptv-extensions/main/js/kbjfan.js 2 | const cheerio = createCheerio() 3 | 4 | const UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.1 Mobile/15E148 Safari/604.1' 5 | 6 | let appConfig = { 7 | ver: 20250317, 8 | title: 'kbjfan', 9 | site: 'https://www.kbjfan.com', 10 | tabs: [ 11 | { 12 | name: 'Korean BJ Dance', 13 | ext: { 14 | typeurl: 'koreanbjdance', 15 | }, 16 | ui: 1, 17 | }, 18 | { 19 | name: 'Korean BJ Nude', 20 | ext: { 21 | typeurl: 'koreanbjnude', 22 | }, 23 | ui: 1, 24 | }, 25 | ], 26 | } 27 | 28 | async function getConfig() { 29 | return jsonify(appConfig) 30 | } 31 | 32 | async function getCards(ext) { 33 | ext = argsify(ext) 34 | let cards = [] 35 | let { page = 1, typeurl } = ext 36 | let url = `${appConfig.site}/${typeurl}` 37 | 38 | if (page > 1) { 39 | url += `/page/${page}` 40 | } 41 | 42 | const { data } = await $fetch.get(url, { 43 | headers: { 44 | 'User-Agent': UA, 45 | }, 46 | }) 47 | 48 | const $ = cheerio.load(data) 49 | 50 | $('.posts-item').each((_, element) => { 51 | const href = $(element).find('.item-heading a').attr('href') 52 | const title = $(element).find('.item-heading a').text() 53 | const cover = $(element).find('.item-thumbnail img').attr('data-src') 54 | const pubdate = $(element).find('.meta-author span').text() 55 | cards.push({ 56 | vod_id: href, 57 | vod_name: title, 58 | vod_pic: cover, 59 | vod_pubdate: pubdate, 60 | ext: { 61 | url: href, 62 | }, 63 | }) 64 | }) 65 | 66 | return jsonify({ 67 | list: cards, 68 | }) 69 | } 70 | 71 | async function getTracks(ext) { 72 | ext = argsify(ext) 73 | let tracks = [] 74 | let url = ext.url 75 | 76 | const { data } = await $fetch.get(url, { 77 | headers: { 78 | 'User-Agent': UA, 79 | }, 80 | }) 81 | 82 | const $ = cheerio.load(data) 83 | let playlist = $('.dplayer-featured a') 84 | 85 | if (playlist.length) { 86 | playlist.each((_, element) => { 87 | let name = $(element).text().trim() 88 | let url = $(element).attr('video-url') 89 | 90 | tracks.push({ 91 | name: name, 92 | pan: '', 93 | ext: { 94 | url: url, 95 | }, 96 | }) 97 | }) 98 | } else { 99 | let playUrl = $('#posts-pay .new-dplayer').attr('video-url') 100 | 101 | tracks.push({ 102 | name: '播放', 103 | pan: '', 104 | ext: { 105 | url: playUrl, 106 | }, 107 | }) 108 | } 109 | 110 | return jsonify({ 111 | list: [ 112 | { 113 | title: '默认分组', 114 | tracks, 115 | }, 116 | ], 117 | }) 118 | } 119 | 120 | async function getPlayinfo(ext) { 121 | ext = argsify(ext) 122 | const url = ext.url 123 | 124 | return jsonify({ urls: [url] }) 125 | } 126 | 127 | async function search(ext) { 128 | ext = argsify(ext) 129 | let cards = [] 130 | 131 | let text = encodeURIComponent(ext.text) 132 | let page = ext.page || 1 133 | let url = `${appConfig.site}/?s=${text}` 134 | 135 | if (page > 1) { 136 | url = `${appConfig.site}/page/${page}/?s=${text}` 137 | } 138 | 139 | const { data } = await $fetch.get(url, { 140 | headers: { 141 | 'User-Agent': UA, 142 | }, 143 | }) 144 | 145 | const $ = cheerio.load(data) 146 | 147 | $('.posts-item').each((_, element) => { 148 | const href = $(element).find('.item-heading a').attr('href') 149 | const title = $(element).find('.item-heading a').text() 150 | const cover = $(element).find('.item-thumbnail img').attr('data-src') 151 | const pubdate = $(element).find('.meta-author span').text() 152 | cards.push({ 153 | vod_id: href, 154 | vod_name: title, 155 | vod_pic: cover, 156 | vod_pubdate: pubdate, 157 | ext: { 158 | url: href, 159 | }, 160 | }) 161 | }) 162 | 163 | return jsonify({ 164 | list: cards, 165 | }) 166 | } 167 | -------------------------------------------------------------------------------- /XPTV/JS/mucpan.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/kingreevice/my_xptv/main/js/mucpan.js 2 | //昊 3 | const cheerio = createCheerio() 4 | 5 | // 預先定義請求使用的 user-agent 6 | const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' 7 | 8 | const appConfig = { 9 | ver: 1, 10 | title: '小米UC资源站|昊', 11 | site: 'http://www.mucpan.cc', 12 | tabs: [ 13 | { 14 | name: '全部小米电影', 15 | ext: { 16 | id: 20, 17 | }, 18 | }, 19 | { 20 | name: '小米电影片库', 21 | ext: { 22 | id: 21, 23 | }, 24 | }, 25 | { 26 | name: '小米动漫片库', 27 | ext: { 28 | id: 22, 29 | }, 30 | }, 31 | { 32 | name: '小米综艺片库', 33 | ext: { 34 | id: 23, 35 | }, 36 | }, 37 | { 38 | name: '小米少儿片库', 39 | ext: { 40 | id: 24, 41 | }, 42 | }, 43 | ], 44 | } 45 | async function getConfig() { 46 | return jsonify(appConfig) 47 | } 48 | async function getCards(ext) { 49 | ext = argsify(ext) 50 | let cards = [] 51 | // let page = ext.page 52 | // let id = ext.id 53 | let { page = 1, id } = ext 54 | const url = appConfig.site + `/index.php/vod/show/id/${id}/page/${page}.html` 55 | const { data } = await $fetch.get(url, { 56 | headers: { 57 | 'User-Agent': UA, 58 | }, 59 | }) 60 | const $ = cheerio.load(data) 61 | const videos = $('.module-item') 62 | videos.each((_, e) => { 63 | const href = $(e).find('.module-item-cover a').attr('href') 64 | const title = $(e).find('.module-item-cover a').attr('title') 65 | const cover = $(e).find('img').attr('src') 66 | const remarks = $(e).find('.module-item-text').text() 67 | cards.push({ 68 | vod_id: href, 69 | vod_name: title, 70 | vod_pic: cover, 71 | vod_remarks: remarks, 72 | ext: { 73 | url: `${appConfig.site}${href}`, 74 | }, 75 | }) 76 | }) 77 | 78 | return jsonify({ 79 | list: cards, 80 | }) 81 | } 82 | async function getTracks(ext) { 83 | ext = argsify(ext) 84 | let tracks = [] 85 | let url = ext.url 86 | const { data } = await $fetch.get(url, { 87 | headers: { 88 | 'User-Agent': UA, 89 | }, 90 | }) 91 | 92 | const $ = cheerio.load(data) 93 | 94 | const playlist = $('.module-row-one .module-row-info .module-row-text') 95 | playlist.each((_, e) => { 96 | const name = $(e).attr('title').replace('复制', '').replace('第1集下载地址', '') 97 | const ShareUrl = $(e).attr('data-clipboard-text') 98 | tracks.push({ 99 | name:name.trim(), 100 | pan: ShareUrl , 101 | ext: { 102 | url: '', 103 | }, 104 | }) 105 | }) 106 | 107 | return jsonify({ 108 | list: [ 109 | { 110 | title: '默认分组', 111 | tracks, 112 | }, 113 | ], 114 | }) 115 | } 116 | 117 | async function getPlayinfo(ext) { 118 | return jsonify({ urls: [] }) 119 | } 120 | 121 | async function search(ext) { 122 | ext = argsify(ext) 123 | let cards = [] 124 | 125 | let text = encodeURIComponent(ext.text) 126 | //let page = ext.page || 1 127 | let url = `${appConfig.site}/index.php/vod/search.html?wd=${text}` 128 | 129 | const { data } = await $fetch.get(url, { 130 | headers: { 131 | 'User-Agent': UA, 132 | }, 133 | }) 134 | 135 | const $ = cheerio.load(data); 136 | 137 | const videos = $('div.module-search-item'); 138 | videos.each((_, e) => { 139 | const img = $(e).find('div.module-item-pic img'); 140 | const title = img.attr('alt'); // 提取标题 141 | const cover = img.attr('data-src') || img.attr('src'); // 提取封面地址 142 | 143 | const serialLink = $(e).find('div.video-info div.video-info-header a.video-serial'); 144 | const href = serialLink.attr('href'); // 提取链接 145 | const remarks = serialLink.text().trim(); // 提取更新信息 146 | 147 | cards.push({ 148 | vod_id: href, 149 | vod_name: title, 150 | vod_pic: cover, 151 | vod_remarks: remarks, 152 | ext: { 153 | url: href.startsWith('http') ? href : `${appConfig.site}${href}`, // 拼接完整链接 154 | }, 155 | }); 156 | }); 157 | 158 | 159 | 160 | return jsonify({ 161 | list: cards, 162 | }) 163 | } 164 | -------------------------------------------------------------------------------- /XPTV/JS/hohoj.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/Yswag/xptv-extensions/main/js/hohoj.js 2 | // 來自群友:夢 3 | const cheerio = createCheerio() 4 | 5 | const UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.1 Mobile/15E148 Safari/604.1' 6 | 7 | let appConfig = { 8 | ver: 1, 9 | title: 'HOHOJ', 10 | site: 'https://hohoj.tv', 11 | tabs: [ 12 | { 13 | name: '全部', 14 | ext: { 15 | type: 'all', 16 | }, 17 | ui: 1, 18 | }, 19 | { 20 | name: '欧美', 21 | ext: { 22 | type: 'europe', 23 | }, 24 | ui: 1, 25 | }, 26 | { 27 | name: '中字', 28 | ext: { 29 | type: 'chinese', 30 | }, 31 | ui: 1, 32 | }, 33 | { 34 | name: '无码', 35 | ext: { 36 | type: 'uncensored', 37 | }, 38 | ui: 1, 39 | }, 40 | { 41 | name: '有码', 42 | ext: { 43 | type: 'censored', 44 | }, 45 | ui: 1, 46 | }, 47 | ], 48 | } 49 | 50 | async function getConfig() { 51 | return jsonify(appConfig) 52 | } 53 | 54 | async function getCards(ext) { 55 | ext = argsify(ext) 56 | let cards = [] 57 | let { type, page = 1 } = ext 58 | let curl = `${appConfig.site}/search?type=${type}&p=${page}&order=popular` 59 | 60 | const { data } = await $fetch.get(curl, { 61 | headers: { 62 | 'User-Agent': UA, 63 | }, 64 | }) 65 | 66 | const $ = cheerio.load(data) 67 | 68 | $('.video-item.col-lg-3.col-md-3.col-sm-6.col-6.mt-4').each((_, element) => { 69 | const videoid = $(element) 70 | .find('a') 71 | .attr('href') 72 | .match(/id=(\d+)/)[1] 73 | const title = $(element).find('.video-item-title.mt-1').text() 74 | const cover = $(element).find('img').attr('src') 75 | const remarks = $(element).find('.video-item-badge').text() 76 | cards.push({ 77 | vod_id: videoid, 78 | vod_name: title, 79 | vod_pic: cover, 80 | vod_remarks: remarks, 81 | ext: { 82 | id: videoid, 83 | }, 84 | }) 85 | }) 86 | 87 | return jsonify({ 88 | list: cards, 89 | }) 90 | } 91 | 92 | async function getTracks(ext) { 93 | ext = argsify(ext) 94 | let tracks = [] 95 | let url = `${appConfig.site}/embed?id=${ext.id}` 96 | 97 | const { data } = await $fetch.get(url, { 98 | headers: { 99 | 'User-Agent': UA, 100 | }, 101 | }) 102 | 103 | const $ = cheerio.load(data) 104 | $('video#my-video').each((_, element) => { 105 | const videourl = $(element).attr('src') 106 | tracks.push({ 107 | name: '播放', 108 | ext: { 109 | url: videourl, 110 | }, 111 | }) 112 | }) 113 | return jsonify({ 114 | list: [ 115 | { 116 | title: '默认分组', 117 | tracks, 118 | }, 119 | ], 120 | }) 121 | } 122 | 123 | async function getPlayinfo(ext) { 124 | ext = argsify(ext) 125 | const playUrl = ext.url 126 | 127 | return jsonify({ urls: [playUrl] }) 128 | } 129 | 130 | async function search(ext) { 131 | ext = argsify(ext) 132 | let cards = [] 133 | let text = encodeURIComponent(ext.text) 134 | let page = ext.page || 1 135 | let url = `${appConfig.site}/search?text=${text}&p=${page}` 136 | 137 | const { data } = await $fetch.get(url, { 138 | headers: { 139 | 'User-Agent': UA, 140 | }, 141 | }) 142 | 143 | const $ = cheerio.load(data) 144 | 145 | $('.video-item.col-lg-3.col-md-3.col-sm-6.col-6.mt-4').each((_, element) => { 146 | const videoid = $(element) 147 | .find('a') 148 | .attr('href') 149 | .match(/id=(\d+)/)[1] 150 | const title = $(element).find('.video-item-title.mt-1').text() 151 | const cover = $(element).find('img').attr('src') 152 | const remarks = $(element).find('.video-item-badge').text() 153 | cards.push({ 154 | vod_id: videoid, 155 | vod_name: title, 156 | vod_pic: cover, 157 | vod_remarks: remarks, 158 | ext: { 159 | id: videoid, 160 | }, 161 | }) 162 | }) 163 | return jsonify({ 164 | list: cards, 165 | }) 166 | } 167 | -------------------------------------------------------------------------------- /XPTV/JS/anime1.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/Yswag/xptv-extensions/main/js/anime1.js 2 | const cheerio = createCheerio() 3 | 4 | let UA = 5 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36' 6 | 7 | let appConfig = { 8 | ver: 20251206, 9 | title: 'anime1', 10 | site: 'https://anime1.me', 11 | tabs: [ 12 | { 13 | id: '1', 14 | name: 'list', 15 | ext: {}, 16 | }, 17 | ], 18 | } 19 | 20 | async function getConfig() { 21 | return jsonify(appConfig) 22 | } 23 | 24 | async function getCards(ext) { 25 | ext = argsify(ext) 26 | let cards = [] 27 | let { page = 1 } = ext 28 | 29 | if (page > 1) return 30 | try { 31 | const url = appConfig.site + `/animelist.json` 32 | const { data } = await $fetch.get(url, { 33 | headers: { 34 | 'User-Agent': UA, 35 | }, 36 | }) 37 | 38 | argsify(data).forEach((e) => { 39 | cards.push({ 40 | vod_id: `${e[0]}`, 41 | vod_name: e[1], 42 | vod_pic: '', 43 | vod_remarks: e[2] || '', 44 | vod_pubdate: e[3] || '', 45 | ext: { 46 | id: `${e[0]}`, 47 | }, 48 | }) 49 | }) 50 | 51 | return jsonify({ 52 | list: cards, 53 | }) 54 | } catch (error) { 55 | $print(error) 56 | } 57 | } 58 | 59 | async function getTracks(ext) { 60 | ext = argsify(ext) 61 | let tracks = [] 62 | let { id, href } = ext 63 | let url = href ? href : appConfig.site + `/?cat=${id}` 64 | 65 | const { data } = await $fetch.get(url, { 66 | headers: { 67 | 'User-Agent': UA, 68 | }, 69 | }) 70 | 71 | const $ = cheerio.load(data) 72 | $('#main > article').each((_, e) => { 73 | let name = $(e).find('.entry-title a').text() 74 | let href = $(e).find('.entry-title a').attr('href') 75 | 76 | tracks.push({ 77 | name, 78 | pan: '', 79 | ext: { 80 | href, 81 | }, 82 | }) 83 | }) 84 | 85 | return jsonify({ 86 | list: [ 87 | { 88 | title: '默认分组', 89 | tracks, 90 | }, 91 | ], 92 | }) 93 | } 94 | 95 | async function getPlayinfo(ext) { 96 | ext = argsify(ext) 97 | let { href } = ext 98 | let api = 'https://v.anime1.me/api' 99 | try { 100 | const { data } = await $fetch.get(href, { 101 | headers: { 'User-Anent': UA }, 102 | }) 103 | const $ = cheerio.load(data) 104 | let apireq = $('.vjscontainer > video').attr('data-apireq') 105 | const apires = await $fetch.post(api, `d=${apireq}`, { 106 | headers: { 107 | 'User-Agent': UA, 108 | 'Content-Type': 'application/x-www-form-urlencoded', 109 | }, 110 | }) 111 | 112 | let playUrl = argsify(apires.data).s[0].src 113 | let headers = apires.respHeaders 114 | 115 | let set_cookie = headers['Set-Cookie'] 116 | let cookie = '' 117 | set_cookie.split(',').forEach((e) => { 118 | cookie += `${e.split(';')[0]}; ` 119 | }) 120 | 121 | playUrl = playUrl.startsWith('https:') ? playUrl : 'https:' + playUrl 122 | return jsonify({ urls: [playUrl], headers: [{ 'User-Agent': UA, Cookie: cookie }] }) 123 | } catch (error) { 124 | $print(error) 125 | } 126 | } 127 | 128 | async function search(ext) { 129 | ext = argsify(ext) 130 | let cards = [] 131 | 132 | const text = encodeURIComponent(ext.text) 133 | const page = ext.page || 1 134 | const url = `${appConfig.site}/page/${page}?s=${text}` 135 | 136 | const { data } = await $fetch.get(url, { 137 | headers: { 138 | 'User-Agent': UA, 139 | }, 140 | }) 141 | 142 | try { 143 | const $ = cheerio.load(data) 144 | $('#main > article').each((_, e) => { 145 | let name = $(e).find('.entry-footer .cat-links a').text() 146 | let href = $(e).find('.entry-footer .cat-links a').attr('href') 147 | 148 | cards.push({ 149 | vod_id: href, 150 | vod_name: name, 151 | vod_pic: '', 152 | ext: { 153 | href, 154 | }, 155 | }) 156 | }) 157 | } catch (error) { 158 | console.log(error) 159 | } 160 | 161 | return jsonify({ 162 | list: cards, 163 | }) 164 | } 165 | -------------------------------------------------------------------------------- /XPTV/JS/hjkk.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/Yswag/xptv-extensions/main/js/hjkk.js 2 | const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' 3 | 4 | let appConfig = { 5 | ver: 1, 6 | title: '韓劇看看', 7 | site: 'https://www.hanjukankan.com', 8 | tabs: [ 9 | { 10 | name: '韓劇', 11 | ext: { 12 | id: 1, 13 | url: 'https://www.hanjukankan.com/xvs@id@xatxbtxctxdtxetxftxgtxht@page@atbtct.html', 14 | }, 15 | }, 16 | { 17 | name: '韓影', 18 | ext: { 19 | id: 2, 20 | url: 'https://www.hanjukankan.com/xvs@id@xatxbtxctxdtxetxftxgtxht@page@atbtct.html', 21 | }, 22 | }, 23 | { 24 | name: '韓綜', 25 | ext: { 26 | id: 3, 27 | url: 'https://www.hanjukankan.com/xvs@id@xatxbtxctxdtxetxftxgtxht@page@atbtct.html', 28 | }, 29 | }, 30 | ], 31 | } 32 | 33 | async function getConfig() { 34 | return jsonify(appConfig) 35 | } 36 | 37 | async function getCards(ext) { 38 | ext = argsify(ext) 39 | let cards = [] 40 | let { id, page = 1, url } = ext 41 | 42 | url = url.replace('@id@', id).replace('@page@', page) 43 | 44 | const { data } = await $fetch.get(url, { 45 | headers: { 46 | 'User-Agent': UA, 47 | }, 48 | }) 49 | 50 | const elems = $html.elements(data, '.module-poster-item') 51 | elems.forEach((element) => { 52 | const href = $html.attr(element, 'a', 'href') 53 | const title = $html.attr(element, 'a', 'title') 54 | const cover = $html.attr(element, '.module-item-pic img', 'data-original') 55 | const subTitle = $html.text(element, '.module-item-note') 56 | cards.push({ 57 | vod_id: href, 58 | vod_name: title, 59 | vod_pic: cover, 60 | vod_remarks: subTitle, 61 | ext: { 62 | url: `${appConfig.site}${href}`, 63 | }, 64 | }) 65 | }) 66 | 67 | return jsonify({ 68 | list: cards, 69 | }) 70 | } 71 | 72 | async function getTracks(ext) { 73 | ext = argsify(ext) 74 | let tracks = [] 75 | let url = ext.url 76 | 77 | const { data } = await $fetch.get(url, { 78 | headers: { 79 | 'User-Agent': UA, 80 | }, 81 | }) 82 | 83 | const elems = $html.elements(data, '#panel1 .module-play-list-link') 84 | elems.forEach((e) => { 85 | const name = $html.text(e, 'span') 86 | const href = $html.attr(e, 'a', 'href') 87 | tracks.push({ 88 | name: name, 89 | pan: '', 90 | ext: { 91 | url: `${appConfig.site}${href}`, 92 | }, 93 | }) 94 | }) 95 | 96 | return jsonify({ 97 | list: [ 98 | { 99 | title: '默认分组', 100 | tracks, 101 | }, 102 | ], 103 | }) 104 | } 105 | 106 | async function getPlayinfo(ext) { 107 | ext = argsify(ext) 108 | const url = ext.url 109 | 110 | const { data } = await $fetch.get(url, { 111 | headers: { 112 | 'User-Agent': UA, 113 | }, 114 | }) 115 | 116 | const html = data.match(/r player_.*?=(.*?) { 139 | const href = $html.attr(element, '.module-card-item-poster', 'href') 140 | const title = $html.text(element, '.module-card-item-title strong') 141 | const cover = $html.attr(element, '.module-item-pic img', 'data-original') 142 | const subTitle = $html.text(element, '.module-item-note') 143 | cards.push({ 144 | vod_id: href, 145 | vod_name: title, 146 | vod_pic: cover, 147 | vod_remarks: subTitle, 148 | ext: { 149 | url: `${appConfig.site}${href}`, 150 | }, 151 | }) 152 | }) 153 | 154 | return jsonify({ 155 | list: cards, 156 | }) 157 | } 158 | -------------------------------------------------------------------------------- /XPTV/JS/apple.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/Yswag/xptv-extensions/main/js/apple.js 2 | const CryptoJS = createCryptoJS() 3 | 4 | const UA = 'okhttp/3.12.11' 5 | 6 | let appConfig = { 7 | ver: 20250511, 8 | title: '小蘋果', 9 | // site: 'http://item.xpgcom.com', 10 | site: 'http://194.147.100.13', 11 | tabs: [ 12 | { 13 | name: '电影', 14 | ext: { 15 | id: 1, 16 | }, 17 | }, 18 | { 19 | name: '电视', 20 | ext: { 21 | id: 2, 22 | }, 23 | }, 24 | { 25 | name: '综艺', 26 | ext: { 27 | id: 3, 28 | }, 29 | }, 30 | { 31 | name: '动漫', 32 | ext: { 33 | id: 4, 34 | }, 35 | }, 36 | ], 37 | } 38 | 39 | async function getConfig() { 40 | return jsonify(appConfig) 41 | } 42 | 43 | async function getCards(ext) { 44 | ext = argsify(ext) 45 | let cards = [] 46 | let { id, page = 1 } = ext 47 | 48 | const url = appConfig.site + `/api.php/v2.vod/androidfilter10086?page=${page}&type=${id}` 49 | 50 | const { data } = await $fetch.get(url, { 51 | headers: { 52 | 'User-Agent': UA, 53 | }, 54 | }) 55 | 56 | argsify(data).data.forEach((e) => { 57 | cards.push({ 58 | vod_id: e.id.toString(), 59 | vod_name: e.name, 60 | vod_pic: e.pic, 61 | vod_remarks: e.state, 62 | ext: { 63 | url: `${appConfig.site}/api.php/v3.vod/androiddetail2?vod_id=${e.id}`, 64 | }, 65 | }) 66 | }) 67 | 68 | return jsonify({ 69 | list: cards, 70 | }) 71 | } 72 | 73 | async function getTracks(ext) { 74 | ext = argsify(ext) 75 | let tracks = [] 76 | let url = ext.url 77 | 78 | const { data } = await $fetch.get(url, { 79 | headers: { 80 | 'User-Agent': UA, 81 | }, 82 | }) 83 | 84 | let playlist = argsify(data).data.urls 85 | playlist.forEach((e) => { 86 | const name = e.key 87 | const url = e.url 88 | if (name.includes('及时雨')) return 89 | tracks.push({ 90 | name: name, 91 | pan: '', 92 | ext: { 93 | key: url, 94 | }, 95 | }) 96 | }) 97 | 98 | return jsonify({ 99 | list: [ 100 | { 101 | title: '默认分组', 102 | tracks, 103 | }, 104 | ], 105 | }) 106 | } 107 | 108 | async function getPlayinfo(ext) { 109 | ext = argsify(ext) 110 | let key = ext.key 111 | const url = `http://c.xpgtv.net/m3u8/${key}.m3u8` 112 | const headers = { 113 | token2: 'SnAXiSW8vScXE0Z9aDOnK5xffbO75w1+uPom3WjnYfVEA1oWtUdi2Ihy1N8=', 114 | token: 'ElEDlwCVgXcFHFhddiq2JKteHofExRBUrfNlmHrWetU3VVkxnzJAodl52N9EUFS+Dig2A/fBa/V9RuoOZRBjYvI+GW8kx3+xMlRecaZuECdb/3AdGkYpkjW3wCnpMQxf8vVeCz5zQLDr8l8bUChJiLLJLGsI+yiNskiJTZz9HiGBZhZuWh1mV1QgYah5CLTbSz8=', 115 | version: 'XPGBOX com.phoenix.tv1.5.7', 116 | user_id: 'XPGBOX', 117 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36', 118 | screenx: '1280', 119 | screeny: '720', 120 | // timestamp: `${Math.floor(Date.now() / 1000)}`, 121 | } 122 | // const str = `||||DC6FFCB55FA||861824127032820||12702720||Asus/Asus/ASUS_I003DD:7.1.2/20171130.376229:user/release-keysXPGBOX com.phoenix.tv1.3.3${headers.timestamp}` 123 | // headers.hash = CryptoJS.MD5(str).toString().toLowerCase().substring(8, 12) 124 | headers.hash = 'd78a' 125 | headers.timestamp = '1743060300' 126 | 127 | return jsonify({ urls: [url], headers: [headers] }) 128 | } 129 | 130 | async function search(ext) { 131 | ext = argsify(ext) 132 | let cards = [] 133 | 134 | const text = encodeURIComponent(ext.text) 135 | const page = ext.page || 1 136 | const url = `${appConfig.site}/api.php/v2.vod/androidsearch10086?page=${page}&wd=${text}` 137 | 138 | const { data } = await $fetch.get(url, { 139 | headers: { 140 | 'User-Agent': UA, 141 | }, 142 | }) 143 | 144 | argsify(data).data.forEach((e) => { 145 | cards.push({ 146 | vod_id: e.id.toString(), 147 | vod_name: e.name, 148 | vod_pic: e.pic, 149 | vod_remarks: e.state, 150 | ext: { 151 | url: `${appConfig.site}/api.php/v3.vod/androiddetail2?vod_id=${e.id}`, 152 | }, 153 | }) 154 | }) 155 | 156 | return jsonify({ 157 | list: cards, 158 | }) 159 | } 160 | -------------------------------------------------------------------------------- /XPTV/JS/yunpan8.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/yunpan8.js 2 | //小改 3 | const cheerio = createCheerio() 4 | 5 | const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' 6 | 7 | const appConfig = { 8 | ver: 1, 9 | title: '云盘吧', 10 | site: 'https://yunpan8.net', 11 | } 12 | 13 | async function getConfig() { 14 | let config = appConfig 15 | config.tabs = await getTabs() 16 | return jsonify(config) 17 | } 18 | 19 | async function getTabs() { 20 | let url = appConfig.site + '/tags' 21 | let tabs = [] 22 | let ignore = ['求助', '公告', '游戏', '书籍', '软件', '课程', '音乐', '其他', '百度网盘', '迅雷云盘'] 23 | function isIgnoreClassName(className) { 24 | return ignore.some((element) => className.includes(element)) 25 | } 26 | 27 | const { data } = await $fetch.get(url, { 28 | headers: { 29 | 'User-Agent': UA, 30 | }, 31 | }) 32 | const $ = cheerio.load(data) 33 | const script = $('#flarum-json-payload').text() 34 | const json = argsify(script) 35 | json.apiDocument.data.forEach((e) => { 36 | const name = e.attributes.name 37 | if (isIgnoreClassName(name)) { 38 | return 39 | } 40 | const id = e.attributes.slug 41 | tabs.push({ 42 | name, 43 | ext: { 44 | id, 45 | }, 46 | }) 47 | }) 48 | 49 | return tabs 50 | } 51 | 52 | async function getCards(ext) { 53 | ext = argsify(ext) 54 | let cards = [] 55 | let { page = 1, id } = ext 56 | 57 | const offset = 20 * (page - 1) 58 | const url = `${appConfig.site}/api/discussions?include=user%2ClastPostedUser%2Ctags%2Ctags.parent%2CfirstPost&filter%5Btag%5D=${id}&sort&page%5Boffset%5D=${offset}` 59 | 60 | const { data } = await $fetch.get(url, { 61 | headers: { 62 | 'User-Agent': UA, 63 | }, 64 | }) 65 | 66 | const json = argsify(data) 67 | const videos = json.data 68 | videos.forEach((e) => { 69 | const title = e.attributes.title 70 | const match = title.match(/《(.*?)》/); 71 | const dramaName = match && match[1] ? match[1] : title; 72 | const id = e.attributes.slug 73 | const createdAt = e.attributes.createdAt.split('+')[0].replace('T', ' ') 74 | 75 | cards.push({ 76 | vod_id: id, 77 | vod_name: dramaName, 78 | vod_pic: '', 79 | vod_pubdate: createdAt, 80 | ext: { 81 | id, 82 | }, 83 | }) 84 | }) 85 | 86 | return jsonify({ 87 | list: cards, 88 | }) 89 | } 90 | 91 | async function getTracks(ext) { 92 | ext = argsify(ext) 93 | let id = ext.id 94 | let tracks = [] 95 | 96 | const url = `${appConfig.site}/d/${id}` 97 | const { data } = await $fetch.get(url, { 98 | headers: { 99 | 'User-Agent': UA, 100 | }, 101 | }) 102 | const $ = cheerio.load(data) 103 | const html = $('noscript#flarum-content').text() 104 | const $2 = cheerio.load(html) 105 | const urls = $2('a') 106 | urls.each((_, e) => { 107 | const panShareUrl = $(e).attr('href') 108 | const name = $(e).prev('strong').text().replace(':', '') 109 | tracks.push({ 110 | name, 111 | pan: panShareUrl, 112 | }) 113 | }) 114 | 115 | return jsonify({ 116 | list: [ 117 | { 118 | title: '默认分组', 119 | tracks, 120 | }, 121 | ], 122 | }) 123 | } 124 | 125 | async function getPlayinfo(ext) { 126 | return jsonify({ urls: [] }) 127 | } 128 | 129 | async function search(ext) { 130 | ext = argsify(ext) 131 | let cards = [] 132 | let text = encodeURIComponent(ext.text) 133 | let url = `${appConfig.site}/?sort=top&q=${text}` 134 | 135 | const { data } = await $fetch.get(url, { 136 | headers: { 137 | 'User-Agent': UA, 138 | }, 139 | }) 140 | 141 | const $ = cheerio.load(data) 142 | 143 | const videos = $('.DiscussionListItem-main') 144 | videos.each((_, e) => { 145 | const href = $(e).attr('href') 146 | const title = $(e).find('.DiscussionListItem-title').text() 147 | const match = title.match(/《(.*?)》/); 148 | const dramaName = match && match[1] ? match[1] : title; 149 | 150 | cards.push({ 151 | vod_id: href, 152 | vod_name: dramaName, 153 | ext: { 154 | 'url': `${appConfig.site}${href}`, 155 | }, 156 | }) 157 | }) 158 | 159 | return jsonify({ 160 | list: cards, 161 | }) 162 | } 163 | -------------------------------------------------------------------------------- /XPTV/JS/madou.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/Yswag/xptv-extensions/main/js/madou.js 2 | const cheerio = createCheerio() 3 | 4 | const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' 5 | 6 | let appConfig = { 7 | ver: 1, 8 | title: '麻豆社', 9 | site: 'https://madou.club', 10 | } 11 | 12 | async function getConfig() { 13 | let config = appConfig 14 | config.tabs = await getTabs() 15 | return jsonify(config) 16 | } 17 | 18 | async function getTabs() { 19 | let list = [] 20 | let ignore = ['首页', '其他', '热门标签', '筛选'] 21 | function isIgnoreClassName(className) { 22 | return ignore.some((element) => className.includes(element)) 23 | } 24 | 25 | const { data } = await $fetch.get(appConfig.site, { 26 | headers: { 27 | 'User-Agent': UA, 28 | }, 29 | }) 30 | const $ = cheerio.load(data) 31 | 32 | let allClass = $('.sitenav a') 33 | allClass.each((_, e) => { 34 | const name = $(e).text() 35 | const href = $(e).attr('href') 36 | const isIgnore = isIgnoreClassName(name) 37 | if (isIgnore) return 38 | 39 | list.push({ 40 | name, 41 | ext: { 42 | url: href, 43 | }, 44 | }) 45 | }) 46 | 47 | return list 48 | } 49 | 50 | async function getCards(ext) { 51 | ext = argsify(ext) 52 | let cards = [] 53 | let { page = 1, url } = ext 54 | 55 | if (page > 1) { 56 | url = url + '/page/' + page 57 | } 58 | 59 | const { data } = await $fetch.get(url, { 60 | headers: { 61 | 'User-Agent': UA, 62 | }, 63 | }) 64 | 65 | const $ = cheerio.load(data) 66 | 67 | $('.excerpts-wrapper article').each((_, element) => { 68 | const href = $(element).find('a').attr('href') 69 | const title = $(element).find('h2').text() 70 | const cover = $(element).find('img').attr('data-src') 71 | const subTitle = $(element).find('.post-view').text().trim() 72 | cards.push({ 73 | vod_id: href, 74 | vod_name: title, 75 | vod_pic: cover, 76 | vod_remarks: subTitle, 77 | ext: { 78 | url: href, 79 | }, 80 | }) 81 | }) 82 | 83 | return jsonify({ 84 | list: cards, 85 | }) 86 | } 87 | 88 | async function getTracks(ext) { 89 | ext = argsify(ext) 90 | let tracks = [] 91 | let url = ext.url 92 | 93 | const { data } = await $fetch.get(url, { 94 | headers: { 95 | 'User-Agent': UA, 96 | }, 97 | }) 98 | 99 | const $ = cheerio.load(data) 100 | 101 | let w = $('.article-content iframe').attr('src') 102 | let dash = w.match(/^(https?:\/\/[^\/]+)/)[1] 103 | let dashResp = (await $fetch.get(w, { headers: { 'User-Agent': UA } })).data 104 | let $2 = cheerio.load(dashResp) 105 | let html2 = $2('body script').eq(5).text() 106 | let token = html2.match(/var token = "(.+)";/)[1] 107 | let m3u8 = html2.match(/var m3u8 = '(.+)';/)[1] 108 | 109 | let playUrl = dash + m3u8 + '?token=' + token 110 | tracks.push({ 111 | name: '播放', 112 | pan: '', 113 | ext: { 114 | url: playUrl, 115 | }, 116 | }) 117 | 118 | return jsonify({ 119 | list: [ 120 | { 121 | title: '默认分组', 122 | tracks, 123 | }, 124 | ], 125 | }) 126 | } 127 | 128 | async function getPlayinfo(ext) { 129 | ext = argsify(ext) 130 | const url = ext.url 131 | 132 | return jsonify({ urls: [url] }) 133 | } 134 | 135 | async function search(ext) { 136 | ext = argsify(ext) 137 | let cards = [] 138 | 139 | let text = encodeURIComponent(ext.text) 140 | let page = ext.page || 1 141 | let url = appConfig.site + `/page/${page}?s=${text}` 142 | 143 | const { data } = await $fetch.get(url, { 144 | headers: { 145 | 'User-Agent': UA, 146 | }, 147 | }) 148 | 149 | const $ = cheerio.load(data) 150 | 151 | $('.excerpts-wrapper article').each((_, element) => { 152 | const href = $(element).find('a').attr('href') 153 | const title = $(element).find('h2').text() 154 | const cover = $(element).find('img').attr('data-src') 155 | const subTitle = $(element).find('.post-view').text().trim() 156 | cards.push({ 157 | vod_id: href, 158 | vod_name: title, 159 | vod_pic: cover, 160 | vod_remarks: subTitle, 161 | ext: { 162 | url: href, 163 | }, 164 | }) 165 | }) 166 | 167 | return jsonify({ 168 | list: cards, 169 | }) 170 | } 171 | -------------------------------------------------------------------------------- /XPTV/JS/SpankBang.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/SpankBang.js 2 | const UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_2 like Mac OS X) AppleWebKit/604.1.14 (KHTML, like Gecko)' 3 | const cheerio = createCheerio() 4 | let appConfig = { 5 | ver: 1, 6 | title: 'spankbang', 7 | site: 'https://jp.spankbang.com', 8 | tabs: [ 9 | { 10 | name: '最新', 11 | ui: 1, 12 | ext: { 13 | id: 'new_videos', 14 | }, 15 | }, 16 | ], 17 | } 18 | 19 | async function getConfig() { 20 | return jsonify(appConfig) 21 | } 22 | 23 | async function getCards(ext) { 24 | ext = argsify(ext) 25 | let cards = [] 26 | let { page = 1, id } = ext 27 | 28 | const url = appConfig.site + `/${id}/${page}` 29 | 30 | const { data } = await $fetch.get(url, { 31 | headers: { 32 | 'User-Agent': UA, 33 | }, 34 | }) 35 | if (data.includes('Just a moment...')) { 36 | $utils.openSafari(url, UA) 37 | } 38 | 39 | const $ = cheerio.load(data) 40 | 41 | const videos = $('.video-item') 42 | 43 | videos.each((_, e) => { 44 | const href = $(e).find('a.thumb').attr('href') 45 | const title = $(e).find('img.cover').attr('alt') 46 | const cover = $(e).find('img.cover').attr('data-src') 47 | let obj = { 48 | vod_id: href, 49 | vod_name: title, 50 | vod_pic: cover, 51 | ui: 1, 52 | ext: { 53 | url: `${appConfig.site}${href}`, 54 | }, 55 | } 56 | 57 | cards.push(obj) 58 | }) 59 | 60 | return jsonify({ 61 | list: cards, 62 | }) 63 | } 64 | async function getTracks(ext) { 65 | ext = argsify(ext) 66 | let url = ext.url 67 | let tracks = [] 68 | 69 | const { data } = await $fetch.get(url, { 70 | headers: { 71 | 'User-Agent': UA, 72 | }, 73 | }) 74 | 75 | // 从script标签中提取stream_data信息 76 | const streamDataMatch = data.match(/var stream_data\s*=\s*({[^;]+});/) 77 | if (streamDataMatch && streamDataMatch[1]) { 78 | try { 79 | // 将单引号转换为双引号以便JSON解析 80 | const jsonString = streamDataMatch[1].replace(/'/g, '"') 81 | const streamData = JSON.parse(jsonString) 82 | 83 | // 处理不同分辨率的视频源 84 | const qualityOrder = ['240p', '320p', '480p', '720p', '1080p', '4k'] 85 | 86 | qualityOrder.forEach(quality => { 87 | if (streamData[quality] && Array.isArray(streamData[quality]) && streamData[quality].length > 0) { 88 | const videoUrl = streamData[quality][0] 89 | tracks.push({ 90 | name: quality.toUpperCase(), 91 | pan: '', 92 | ext: { 93 | url: videoUrl, 94 | type: 'mp4' 95 | } 96 | }) 97 | } 98 | }) 99 | 100 | // 处理m3u8格式的流 101 | if (streamData.m3u8 && streamData.m3u8.length > 0) { 102 | tracks.push({ 103 | name: 'M3U8 (自适应)', 104 | pan: '', 105 | ext: { 106 | url: streamData.m3u8[0], 107 | type: 'm3u8' 108 | } 109 | }) 110 | } 111 | 112 | if (tracks.length > 0) { 113 | let defaultUrl = '' 114 | let defaultType = 'mp4' 115 | 116 | if (streamData.main && streamData.main.length > 0) { 117 | defaultUrl = streamData.main[0] 118 | } else if (tracks.length > 0) { 119 | defaultUrl = tracks[0].ext.url 120 | defaultType = tracks[0].ext.type 121 | } 122 | 123 | if (defaultUrl) { 124 | tracks.unshift({ 125 | name: '自动', 126 | pan: '', 127 | ext: { 128 | url: defaultUrl, 129 | type: defaultType 130 | } 131 | }) 132 | } 133 | } 134 | 135 | } catch (error) { 136 | // 静默处理错误 137 | } 138 | } 139 | 140 | return jsonify({ 141 | list: [ 142 | { 143 | title: '视频质量', 144 | tracks, 145 | }, 146 | ], 147 | }) 148 | } 149 | 150 | async function getPlayinfo(ext) { 151 | ext = argsify(ext) 152 | const url = ext.url 153 | const type = ext.type || 'mp4' 154 | 155 | return jsonify({ 156 | urls: [url], 157 | type: type 158 | }) 159 | } 160 | async function search(ext) { 161 | ext = argsify(ext) 162 | let cards = [] 163 | 164 | let text = encodeURIComponent(ext.text) 165 | let page = ext.page || 1 166 | let url = `${appConfig.site}/s/${text}/${page}/` 167 | const { data } = await $fetch.get(url, { 168 | headers: { 169 | 'User-Agent': UA, 170 | }, 171 | }) 172 | const $ = cheerio.load(data) 173 | 174 | const videos = $('.js-video-item') 175 | 176 | videos.each((_, e) => { 177 | const href = $(e).find('a[href*="/video/"]').attr('href') 178 | 179 | const title = $(e).find('img').attr('alt') 180 | 181 | const cover = $(e).find('img').attr('data-src') || $(e).find('img').attr('src') 182 | 183 | let obj = { 184 | vod_id: href, 185 | vod_name: title, 186 | vod_pic: cover, 187 | ui: 1, 188 | ext: { 189 | url: `${appConfig.site}${href}`, 190 | }, 191 | } 192 | cards.push(obj) 193 | }) 194 | return jsonify({ 195 | list: cards, 196 | }) 197 | } 198 | -------------------------------------------------------------------------------- /XPTV/JS/wobg.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/Yswag/xptv-extensions/main/js/wobg.js 2 | const cheerio = createCheerio() 3 | 4 | const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' 5 | 6 | const appConfig = { 7 | ver: 1, 8 | title: '正奕', 9 | site: 'http://jnczyl.top:8900', 10 | tabs: [ 11 | { 12 | name: '電影', 13 | ext: { 14 | id: 24, 15 | }, 16 | }, 17 | { 18 | name: '劇集', 19 | ext: { 20 | id: 25, 21 | }, 22 | }, 23 | { 24 | name: '動漫', 25 | ext: { 26 | id: 26, 27 | }, 28 | }, 29 | { 30 | name: '綜藝', 31 | ext: { 32 | id: 27, 33 | }, 34 | }, 35 | { 36 | name: '音樂', 37 | ext: { 38 | id: 28, 39 | }, 40 | }, 41 | { 42 | name: '短劇', 43 | ext: { 44 | id: 29, 45 | }, 46 | }, 47 | { 48 | name: '紀錄片', 49 | ext: { 50 | id: 30, 51 | }, 52 | }, 53 | { 54 | name: '4K高碼', 55 | ext: { 56 | id: 31, 57 | }, 58 | }, 59 | ], 60 | } 61 | 62 | async function getConfig() { 63 | return jsonify(appConfig) 64 | } 65 | 66 | async function getCards(ext) { 67 | ext = argsify(ext) 68 | let cards = [] 69 | let { page = 1, id } = ext 70 | 71 | const url = appConfig.site + `/index.php/vod/show/id/${id}/page/${page}.html` 72 | 73 | const { data } = await $fetch.get(url, { 74 | headers: { 75 | 'User-Agent': UA, 76 | }, 77 | }) 78 | 79 | const $ = cheerio.load(data) 80 | 81 | const videos = $('#main .module-item') 82 | videos.each((_, e) => { 83 | const href = $(e).find('.module-item-pic a').attr('href') 84 | const title = $(e).find('.module-item-pic img').attr('alt') 85 | const cover = $(e).find('.module-item-pic img').attr('data-src') 86 | const remarks = $(e).find('.module-item-text').text() 87 | cards.push({ 88 | vod_id: href, 89 | vod_name: title, 90 | vod_pic: cover, 91 | vod_remarks: remarks, 92 | ext: { 93 | url: `${appConfig.site}${href}`, 94 | }, 95 | }) 96 | }) 97 | 98 | return jsonify({ 99 | list: cards, 100 | }) 101 | } 102 | 103 | async function getTracks(ext) { 104 | ext = argsify(ext) 105 | let tracks = [] 106 | let url = ext.url 107 | 108 | const { data } = await $fetch.get(url, { 109 | headers: { 110 | 'User-Agent': UA, 111 | }, 112 | }) 113 | 114 | const $ = cheerio.load(data) 115 | 116 | const playlist = $('.module-player-list .module-row-one') 117 | playlist.each((_, e) => { 118 | const name = $(e).find('.module-row-title h4').text().replace('- 第1集', '') 119 | const panShareUrl = $(e).find('.module-row-title p').text() 120 | tracks.push({ 121 | name: name.trim(), 122 | pan: panShareUrl, 123 | }) 124 | }) 125 | 126 | return jsonify({ 127 | list: [ 128 | { 129 | title: '默认分组', 130 | tracks, 131 | }, 132 | ], 133 | }) 134 | } 135 | 136 | async function getPlayinfo(ext) { 137 | return jsonify({ urls: [] }) 138 | } 139 | 140 | async function search(ext) { 141 | ext = argsify(ext) 142 | let cards = [] 143 | 144 | let text = encodeURIComponent(ext.text) 145 | let page = ext.page || 1 146 | let url = `${appConfig.site}/index.php/vod/search/page/${page}/wd/${text}.html` 147 | 148 | const { data } = await $fetch.get(url, { 149 | headers: { 150 | 'User-Agent': UA, 151 | }, 152 | }) 153 | 154 | const $ = cheerio.load(data) 155 | 156 | const videos = $('#main .module-search-item') 157 | videos.each((_, e) => { 158 | const href = $(e).find('.video-info-header h3 a').attr('href') 159 | const title = $(e).find('.module-item-pic img').attr('alt') 160 | const cover = $(e).find('.module-item-pic img').attr('data-src') 161 | const remarks = $(e).find('.video-serial').text() 162 | cards.push({ 163 | vod_id: href, 164 | vod_name: title, 165 | vod_pic: cover, 166 | vod_remarks: remarks, 167 | ext: { 168 | url: `${appConfig.site}${href}`, 169 | }, 170 | }) 171 | }) 172 | 173 | return jsonify({ 174 | list: cards, 175 | }) 176 | } 177 | -------------------------------------------------------------------------------- /XPTV/JS/91jav.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/Yswag/xptv-extensions/main/js/91jav.js 2 | // 來自群友:夢 3 | const cheerio = createCheerio() 4 | 5 | const UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.1 Mobile/15E148 Safari/604.1' 6 | 7 | let appConfig = { 8 | ver: 1, 9 | title: '91Jav', 10 | // 91jav.fun 11 | site: 'https://jdkir.triutpw.cc', 12 | } 13 | 14 | async function getConfig() { 15 | let config = appConfig 16 | config.tabs = await getTabs() 17 | return jsonify(config) 18 | } 19 | 20 | async function getTabs() { 21 | let list = [] 22 | let ignore = ['首页'] 23 | function isIgnoreClassName(className) { 24 | return ignore.some((element) => className.includes(element)) 25 | } 26 | let classurl = `${appConfig.site}/index/getMvStyle/order/count` 27 | 28 | const { data } = await $fetch.get(classurl, { 29 | headers: { 30 | 'User-Agent': UA, 31 | }, 32 | }) 33 | const $ = cheerio.load(data) 34 | 35 | let allClass = $('.pb-3.pb-e-lg-40 .col-6.col-sm-4.col-lg-3') 36 | allClass.each((_, e) => { 37 | const name = $(e).find('h4').text() 38 | const href = $(e).find('a').attr('href') 39 | const isIgnore = isIgnoreClassName(name) 40 | if (isIgnore) return 41 | 42 | list.push({ 43 | name, 44 | ext: { 45 | typeurl: href, 46 | }, 47 | ui: 1, 48 | }) 49 | }) 50 | 51 | return list 52 | } 53 | 54 | async function getCards(ext) { 55 | ext = argsify(ext) 56 | let cards = [] 57 | let { page = 1, typeurl } = ext 58 | let url = `${appConfig.site}${typeurl}` 59 | 60 | if (page > 1) { 61 | url = `${appConfig.site}${typeurl}/sort/update/page/${page}` 62 | } 63 | 64 | const { data } = await $fetch.get(url, { 65 | headers: { 66 | 'User-Agent': UA, 67 | }, 68 | }) 69 | 70 | const $ = cheerio.load(data) 71 | 72 | $('.pb-3.pb-e-lg-40 .col-6.col-sm-4.col-lg-3').each((_, element) => { 73 | const href = $(element).find('.title a').attr('href') 74 | const title = $(element).find('.title a').text() 75 | // const cover = $(element).find('.zximg').attr('z-image-loader-url') 76 | const subTitle = $(element).find('.label').text() 77 | cards.push({ 78 | vod_id: href, 79 | vod_name: title, 80 | vod_pic: '', 81 | vod_duration: subTitle, 82 | ext: { 83 | url: `${appConfig.site}${href}`, 84 | }, 85 | }) 86 | }) 87 | 88 | return jsonify({ 89 | list: cards, 90 | }) 91 | } 92 | 93 | async function getTracks(ext) { 94 | ext = argsify(ext) 95 | let tracks = [] 96 | let url = ext.url 97 | 98 | const { data } = await $fetch.get(url, { 99 | headers: { 100 | 'User-Agent': UA, 101 | }, 102 | }) 103 | 104 | let playUrl = data.match(/var hlsUrl = "(.*?)";/)[1] 105 | 106 | tracks.push({ 107 | name: '播放', 108 | pan: '', 109 | ext: { 110 | url: playUrl, 111 | }, 112 | }) 113 | 114 | return jsonify({ 115 | list: [ 116 | { 117 | title: '默认分组', 118 | tracks, 119 | }, 120 | ], 121 | }) 122 | } 123 | 124 | async function getPlayinfo(ext) { 125 | ext = argsify(ext) 126 | const url = ext.url 127 | 128 | return jsonify({ urls: [url] }) 129 | } 130 | 131 | async function search(ext) { 132 | ext = argsify(ext) 133 | let cards = [] 134 | 135 | let text = encodeURIComponent(ext.text) 136 | let page = ext.page || 1 137 | let url = `${appConfig.site}/search/index/keyword/${text}` 138 | 139 | if (page > 1) { 140 | url = `${appConfig.site}/search/index/keyword/${text}/page/${page}` 141 | } 142 | 143 | const { data } = await $fetch.get(url, { 144 | headers: { 145 | 'User-Agent': UA, 146 | }, 147 | }) 148 | 149 | const $ = cheerio.load(data) 150 | 151 | $('.pb-3.pb-e-lg-40 .col-6.col-sm-4.col-lg-3').each((_, element) => { 152 | const href = $(element).find('.title a').attr('href') 153 | const title = $(element).find('.title a').text() 154 | const cover = appConfig.site + $(element).find('img').attr('src') 155 | const subTitle = $(element).find('.label').text() 156 | cards.push({ 157 | vod_id: href, 158 | vod_name: title, 159 | vod_pic: '', 160 | vod_duration: subTitle, 161 | ext: { 162 | url: `${appConfig.site}${href}`, 163 | }, 164 | }) 165 | }) 166 | 167 | return jsonify({ 168 | list: cards, 169 | }) 170 | } 171 | -------------------------------------------------------------------------------- /XPTV/JS/ouge.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/ouge.js 2 | //来自“梅花” 3 | const cheerio = createCheerio() 4 | // const CryptoJS = createCryptoJS() 5 | // const JSEncrypt = loadJSEncrypt() 6 | /* 7 | 以上是可以調用的第三方庫,使用方法自行查閱文檔 8 | 內置方法有: 9 | $print: 等同於 console.log 10 | $fetch: http client,可發送 get 及 post 請求 11 | get: $fetch.get(url,options) 12 | post: $fetch.post(url,postData,options) 13 | argsify, jsonify: 等同於 JSON 的 parse 及 stringify 14 | $html: 內置的 html 解析方法,建議用 cheerio 替代 15 | $cache: 可將數據存入緩存 16 | set: $cache.set(key, value) 17 | get: $cache.get(key) 18 | */ 19 | 20 | // 預先定義請求使用的 user-agent 21 | const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' 22 | 23 | const appConfig = { 24 | ver: 1, 25 | title: '欧歌', 26 | site: 'https://woog.nxog.eu.org', 27 | // 定義分類 28 | tabs: [ 29 | // name 為分類名,ext 可以傳入任意參數由 getCards 接收 30 | { 31 | name: '電影', 32 | ext: { 33 | id: 1, 34 | }, 35 | }, 36 | { 37 | name: '劇集', 38 | ext: { 39 | id: 2, 40 | }, 41 | }, 42 | { 43 | name: '短劇', 44 | ext: { 45 | id: 5, 46 | }, 47 | }, 48 | { 49 | name: '動漫', 50 | ext: { 51 | id: 3, 52 | }, 53 | }, 54 | { 55 | name: '綜藝', 56 | ext: { 57 | id: 4, 58 | }, 59 | }, 60 | ], 61 | } 62 | 63 | // 進入源時調用,ver,title,site,tabs 為必須項 64 | async function getConfig() { 65 | return jsonify(appConfig) 66 | } 67 | 68 | // 取得分類的影片列表,ext 為 tabs 定義的 ext 加上頁碼(page) 69 | async function getCards(ext) { 70 | // 將 JSON 字符串轉為 JS 對象 71 | ext = argsify(ext) 72 | // 定義一個空的卡片數組 73 | let cards = [] 74 | // 從 ext 中解構賦值取出頁數及分類 id,等同於: 75 | // let page = ext.page 76 | // let id = ext.id 77 | let { page = 1, id } = ext 78 | 79 | // 定義請求的 URL 80 | const url = appConfig.site + `/index.php/vod/show/id/${id}/page/${page}.html` 81 | 82 | // 使用內置的 http client 發起請求獲取 html 83 | const { data } = await $fetch.get(url, { 84 | headers: { 85 | 'User-Agent': UA, 86 | }, 87 | }) 88 | 89 | // 用 cheerio 解析 html 90 | const $ = cheerio.load(data) 91 | 92 | // 用 css 選擇器選出影片列表 93 | const videos = $('#main .module-item') 94 | // 遍歷所有影片 95 | videos.each((_, e) => { 96 | const href = $(e).find('.module-item-pic a').attr('href') 97 | const title = $(e).find('.module-item-pic img').attr('alt') 98 | const cover = $(e).find('.module-item-pic img').attr('data-src') 99 | const remarks = $(e).find('.module-item-text').text() 100 | // 將每個影片加入 cards 數組中 101 | cards.push({ 102 | vod_id: href, 103 | vod_name: title, 104 | vod_pic: cover, 105 | vod_remarks: remarks, // 海報右上角的子標題 106 | // ext 會傳給 getTracks 107 | ext: { 108 | url: `${appConfig.site}${href}`, 109 | }, 110 | }) 111 | }) 112 | 113 | return jsonify({ 114 | list: cards, 115 | }) 116 | } 117 | 118 | // 取得播放列表 119 | async function getTracks(ext) { 120 | ext = argsify(ext) 121 | let tracks = [] 122 | let url = ext.url 123 | 124 | const { data } = await $fetch.get(url, { 125 | headers: { 126 | 'User-Agent': UA, 127 | }, 128 | }) 129 | 130 | const $ = cheerio.load(data) 131 | 132 | const playlist = $('.module-player-list .module-row-one') 133 | playlist.each((_, e) => { 134 | const name = $(e).find('.module-row-title h4').text().replace(' - 公众号欧歌app', '') 135 | // 網盤的分享連結 136 | const panShareUrl = $(e).find('.module-row-title p').text() 137 | tracks.push({ 138 | name: name.trim(), 139 | pan: panShareUrl, 140 | }) 141 | }) 142 | 143 | return jsonify({ 144 | // list 返回一個數組,用於區分不同線路(參考 AGE 動漫及 girigiri 動漫),但功能未實現目前只會讀取第一項 145 | list: [ 146 | { 147 | title: '默认分组', 148 | tracks, 149 | }, 150 | ], 151 | }) 152 | } 153 | 154 | // 網盤源不需要寫播放 155 | async function getPlayinfo(ext) { 156 | return jsonify({ urls: [] }) 157 | } 158 | 159 | // search 的寫法跟 getCards 一樣,唯一不同就是由分類 id 改為關鍵字 160 | async function search(ext) { 161 | ext = argsify(ext) 162 | let cards = [] 163 | 164 | // 必須把中文編碼否則 iOS 16 會報錯 165 | let text = encodeURIComponent(ext.text) 166 | let page = ext.page || 1 167 | let url = `${appConfig.site}/index.php/vod/search/page/${page}/wd/${text}.html` 168 | 169 | const { data } = await $fetch.get(url, { 170 | headers: { 171 | 'User-Agent': UA, 172 | }, 173 | }) 174 | 175 | const $ = cheerio.load(data) 176 | 177 | const videos = $('#main .module-search-item') 178 | videos.each((_, e) => { 179 | const href = $(e).find('.module-item-pic a').attr('href') 180 | const title = $(e).find('.module-item-pic img').attr('alt') 181 | const cover = $(e).find('.module-item-pic img').attr('data-src') 182 | const remarks = $(e).find('.video-serial').text() 183 | cards.push({ 184 | vod_id: href, 185 | vod_name: title, 186 | vod_pic: cover, 187 | vod_remarks: remarks, 188 | ext: { 189 | url: `${appConfig.site}${href}`, 190 | }, 191 | }) 192 | }) 193 | 194 | return jsonify({ 195 | list: cards, 196 | }) 197 | } 198 | -------------------------------------------------------------------------------- /XPTV/JS/xhamster.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/Yswag/xptv-extensions/main/js/xhamster.js 2 | const cheerio = createCheerio() 3 | 4 | const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' 5 | 6 | let appConfig = { 7 | ver: 1, 8 | title: 'xhamster', 9 | site: 'https://zh.xhamster.com', 10 | tabs: [ 11 | { 12 | name: 'newest', 13 | ext: { 14 | href: '/newest', 15 | }, 16 | ui: 1, 17 | }, 18 | { 19 | name: 'weekly best', 20 | ext: { 21 | href: '/best/weekly', 22 | }, 23 | ui: 1, 24 | }, 25 | { 26 | name: '4k', 27 | ext: { 28 | href: '/4k', 29 | }, 30 | ui: 1, 31 | }, 32 | ], 33 | } 34 | 35 | async function getConfig() { 36 | return jsonify(appConfig) 37 | } 38 | 39 | async function getCards(ext) { 40 | ext = argsify(ext) 41 | let cards = [] 42 | let { page = 1, href } = ext 43 | 44 | let url = appConfig.site + href 45 | if (page > 1) { 46 | url = url + `/${page}` 47 | } 48 | 49 | const { data } = await $fetch.get(url, { 50 | headers: { 51 | 'User-Agent': UA, 52 | }, 53 | }) 54 | 55 | const $ = cheerio.load(data) 56 | 57 | $('.thumb-list__item').each((_, element) => { 58 | const href = $(element).find('a.video-thumb__image-container').attr('href') 59 | const title = $(element).find('.thumb-image-container__image').attr('alt') 60 | const cover = $(element).find('.thumb-image-container__image').attr('src') 61 | const subTitle = $(element).find('.video-thumb-views').text().trim() || '' 62 | const duration = $(element).find('.thumb-image-container__duration').text().trim() || '' 63 | cards.push({ 64 | vod_id: href, 65 | vod_name: title, 66 | vod_pic: cover, 67 | vod_remarks: subTitle, 68 | vod_duration: duration, 69 | vod_pubdate: '', 70 | ext: { 71 | url: href, 72 | }, 73 | }) 74 | }) 75 | 76 | return jsonify({ 77 | list: cards, 78 | }) 79 | } 80 | 81 | async function getTracks(ext) { 82 | ext = argsify(ext) 83 | let tracks = [] 84 | let url = ext.url 85 | 86 | const { data } = await $fetch.get(url, { 87 | headers: { 88 | 'User-Agent': UA, 89 | }, 90 | }) 91 | 92 | const $ = cheerio.load(data) 93 | const script = $('#initials-script').text() 94 | let window = {} 95 | eval(script) 96 | const videos = window.initials.xplayerSettings.sources.standard.h264 97 | videos.forEach((e) => { 98 | tracks.push({ 99 | name: e.label, 100 | pan: '', 101 | ext: { 102 | url: e.url, 103 | referer: url, 104 | }, 105 | }) 106 | }) 107 | 108 | return jsonify({ 109 | list: [ 110 | { 111 | title: '默认分组', 112 | tracks, 113 | }, 114 | ], 115 | }) 116 | } 117 | 118 | async function getPlayinfo(ext) { 119 | ext = argsify(ext) 120 | const url = ext.url 121 | const headers = { 122 | 'User-Agent': UA, 123 | Referer: ext.referer + '/', 124 | } 125 | 126 | return jsonify({ urls: [url], headers: [headers] }) 127 | } 128 | 129 | async function search(ext) { 130 | ext = argsify(ext) 131 | let cards = [] 132 | 133 | let text = encodeURIComponent(ext.text) 134 | let page = ext.page || 1 135 | let url = `${appConfig.site}/search/${text}?page=${page}` 136 | 137 | const { data } = await $fetch.get(url, { 138 | headers: { 139 | 'User-Agent': UA, 140 | }, 141 | }) 142 | 143 | const $ = cheerio.load(data) 144 | 145 | $('.thumb-list__item').each((_, element) => { 146 | const href = $(element).find('a.video-thumb__image-container').attr('href') 147 | const title = $(element).find('.thumb-image-container__image').attr('alt') 148 | const cover = $(element).find('.thumb-image-container__image').attr('src') 149 | const subTitle = $(element).find('.video-thumb-views').text().trim() || '' 150 | const duration = $(element).find('.thumb-image-container__duration').text().trim() || '' 151 | cards.push({ 152 | vod_id: href, 153 | vod_name: title, 154 | vod_pic: cover, 155 | vod_remarks: subTitle, 156 | vod_duration: duration, 157 | vod_pubdate: '', 158 | ext: { 159 | url: href, 160 | }, 161 | }) 162 | }) 163 | 164 | return jsonify({ 165 | list: cards, 166 | }) 167 | } 168 | -------------------------------------------------------------------------------- /XPTV/JS/taiav.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/taiav.js 2 | const UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.1.1 Mobile/15E148 Safari/604.1' 3 | 4 | let appConfig = { 5 | ver: 1, 6 | title: 'Taiav', 7 | site: 'https://taiav.com', 8 | cdn: 'https://v15cdn.snmovie.com', 9 | tabs: [ 10 | { 11 | name: '网红主播', 12 | ext: { 13 | tip: 'category', 14 | class: '网红主播' 15 | }, 16 | }, 17 | { 18 | name: '国产AV', 19 | ext: { 20 | tip: 'category', 21 | class: '国产AV' 22 | }, 23 | }, 24 | { 25 | name: '有码', 26 | ui: 1, 27 | ext: { 28 | tip: 'category', 29 | class: '有码' 30 | }, 31 | }, 32 | { 33 | name: '无码', 34 | ui: 1, 35 | ext: { 36 | tip: 'category', 37 | class: '无码' 38 | }, 39 | }, 40 | { 41 | name: 'Onlyfans', 42 | ui: 1, 43 | ext: { 44 | tip: 'tag', 45 | class: 'Onlyfans' 46 | }, 47 | }, 48 | { 49 | name: 'Korean Bj', 50 | ext: { 51 | tip: 'tag', 52 | class: 'Korean Bj' 53 | }, 54 | }, 55 | { 56 | name: '探花', 57 | ext: { 58 | tip: 'tag', 59 | class: '探花' 60 | }, 61 | }, 62 | ], 63 | } 64 | 65 | async function getConfig() { 66 | return jsonify(appConfig) 67 | } 68 | async function getCards(ext) { 69 | ext = argsify(ext) 70 | let cards = [] 71 | let text = encodeURIComponent(ext.class) 72 | let { tip, page = 1 } = ext 73 | let url = `${appConfig.site}/api/getcontents?page=${page}&size=12&${tip}=${text}&type=movie,tv` 74 | const { data } = await $fetch.get(url, { 75 | headers: { 76 | 'User-Agent': UA, 77 | }, 78 | }) 79 | argsify(data).forEach((e) => { 80 | const cover = `${appConfig.site}${e.poster2.url}` 81 | const time = e.duration 82 | const addtime = e.createAt 83 | cards.push({ 84 | vod_id: e._id.toString(), 85 | vod_name: e.originalname, 86 | vod_pic: cover, 87 | vod_remarks: 'HD', 88 | vod_pubdate: addtime, 89 | vod_duration: time, 90 | ext: { 91 | url: `${appConfig.site}/api/getmovie?type=1280&id=${e._id}`, // 拼接URL 92 | }, 93 | }) 94 | }) 95 | return jsonify({ 96 | list: cards, 97 | }) 98 | } 99 | 100 | async function getTracks(ext) { 101 | ext = argsify(ext) 102 | let tracks = [] 103 | let url = ext.url 104 | const { data } = await $fetch.get(url, { 105 | headers: { 106 | 'User-Agent': UA, 107 | }, 108 | }) 109 | let playlist = argsify(data) 110 | const name = '播放' 111 | const m3u8 = playlist.m3u8 112 | tracks.push({ 113 | name: name, 114 | pan: '', 115 | ext: { 116 | playurl: `${appConfig.site}${m3u8}`, 117 | }, 118 | }) 119 | return jsonify({ 120 | list: [ 121 | { 122 | title: '默认分组', 123 | tracks, 124 | }, 125 | ], 126 | }) 127 | } 128 | 129 | async function getPlayinfo(ext) { 130 | ext = argsify(ext) 131 | let playurl = ext.playurl 132 | return jsonify({ 133 | urls: [playurl], 134 | headers: [{ 135 | 'User-Agent': UA, 136 | 'origin': appConfig.site 137 | }] 138 | }) 139 | } 140 | 141 | async function search(ext) { 142 | ext = argsify(ext) 143 | let cards = [] 144 | const text = encodeURIComponent(ext.text) 145 | const page = ext.page || 1 146 | const url = `${appConfig.site}/api/getcontents?page=${page}&size=48&q=${text}&type=movie,tv` 147 | const { data } = await $fetch.get(url, { 148 | headers: { 149 | 'User-Agent': UA, 150 | }, 151 | }) 152 | argsify(data).forEach((e) => { 153 | const cover = `${appConfig.site}${e.poster2.url}` 154 | const time = e.duration 155 | const addtime = e.createAt 156 | cards.push({ 157 | vod_id: e._id.toString(), 158 | vod_name: e.originalname, 159 | vod_pic: cover, 160 | vod_remarks: 'HD', 161 | vod_pubdate: addtime, 162 | vod_duration: time, 163 | ext: { 164 | url: `${appConfig.site}/api/getmovie?type=1280&id=${e._id}`, 165 | }, 166 | }) 167 | }) 168 | return jsonify({ 169 | list: cards, 170 | }) 171 | } 172 | -------------------------------------------------------------------------------- /XPTV/JS/nanfeng.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/Yswag/xptv-extensions/main/js/nanfdj.js 2 | const cheerio = createCheerio() 3 | 4 | const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' 5 | 6 | let appConfig = { 7 | ver: 1, 8 | title: '南風短劇', 9 | site: 'https://www.nanf.cc', 10 | } 11 | 12 | async function getConfig() { 13 | let config = appConfig 14 | config.tabs = await getTabs() 15 | return jsonify(config) 16 | } 17 | 18 | async function getTabs() { 19 | let list = [] 20 | let ignore = ['首页', '热播榜', 'APP下载', '最新短剧'] 21 | function isIgnoreClassName(className) { 22 | return ignore.some((element) => className.includes(element)) 23 | } 24 | 25 | const { data } = await $fetch.get(appConfig.site, { 26 | headers: { 27 | 'User-Agent': UA, 28 | }, 29 | }) 30 | const $ = cheerio.load(data) 31 | 32 | let allClass = $('#DialogMenu ul.menu a') 33 | allClass.each((i, e) => { 34 | const name = $(e).text() 35 | const href = $(e).attr('href') 36 | const isIgnore = isIgnoreClassName(name) 37 | if (isIgnore) return 38 | 39 | list.push({ 40 | name, 41 | ext: { 42 | href: href, 43 | }, 44 | }) 45 | }) 46 | 47 | return list 48 | } 49 | 50 | async function getCards(ext) { 51 | ext = argsify(ext) 52 | let cards = [] 53 | let { page = 1, href } = ext 54 | 55 | const type = href.match(/djtype\/(\d+)\.html/)[1] 56 | const url = appConfig.site + `/djshow/${type}--------${page}---.html` 57 | 58 | const { data } = await $fetch.get(url, { 59 | headers: { 60 | 'User-Agent': UA, 61 | }, 62 | }) 63 | 64 | const $ = cheerio.load(data) 65 | 66 | $('.shoutu-vodlist > li').each((_, e) => { 67 | const href = $(e).find('a.cover-img').attr('href') 68 | const title = $(e).find('a.cover-img').attr('title') 69 | const cover = $(e).find('a.cover-img img').attr('data-original') 70 | cards.push({ 71 | vod_id: href, 72 | vod_name: title, 73 | vod_pic: cover, 74 | vod_remarks: '', 75 | ext: { 76 | url: `${appConfig.site}${href}`, 77 | }, 78 | }) 79 | }) 80 | 81 | return jsonify({ 82 | list: cards, 83 | }) 84 | } 85 | 86 | async function getTracks(ext) { 87 | ext = argsify(ext) 88 | let tracks = [] 89 | let url = ext.url 90 | 91 | const { data } = await $fetch.get(url, { 92 | headers: { 93 | 'User-Agent': UA, 94 | }, 95 | }) 96 | 97 | const $ = cheerio.load(data) 98 | 99 | const name = $('.wp_play > a').text() 100 | const panShareUrl = $('.wp_play > a').attr('href') 101 | tracks.push({ 102 | name, 103 | pan: panShareUrl, 104 | }) 105 | 106 | return jsonify({ 107 | list: [ 108 | { 109 | title: '默认分组', 110 | tracks, 111 | }, 112 | ], 113 | }) 114 | } 115 | 116 | async function getPlayinfo(ext) { 117 | ext = argsify(ext) 118 | const url = ext.url 119 | 120 | const { data } = await $fetch.get(url, { 121 | headers: { 122 | 'User-Agent': UA, 123 | }, 124 | }) 125 | 126 | const $ = cheerio.load(data) 127 | let script = $('.player-box-main script').eq(0).text().replace('var player_aaaa=', '') 128 | let json = JSON.parse(script) 129 | let playUrl = json.url 130 | 131 | return jsonify({ urls: [playUrl] }) 132 | } 133 | 134 | async function search(ext) { 135 | ext = argsify(ext) 136 | let cards = [] 137 | 138 | let text = encodeURIComponent(ext.text) 139 | let page = ext.page || 1 140 | let url = `${appConfig.site}/xvse${text}abcdefghig${page}klm.html` 141 | 142 | const { data } = await $fetch.get(url, { 143 | headers: { 144 | 'User-Agent': UA, 145 | }, 146 | }) 147 | 148 | const $ = cheerio.load(data) 149 | 150 | $('.module-card-item').each((_, element) => { 151 | const href = $(element).find('.module-card-item-poster').attr('href') 152 | const title = $(element).find('.module-card-item-title strong').text() 153 | const cover = $(element).find('.module-item-pic img').attr('data-original') 154 | const subTitle = $(element).find('.module-item-note').text() 155 | cards.push({ 156 | vod_id: href, 157 | vod_name: title, 158 | vod_pic: cover, 159 | vod_remarks: subTitle, 160 | ext: { 161 | url: `${appConfig.site}${href}`, 162 | }, 163 | }) 164 | }) 165 | 166 | return jsonify({ 167 | list: cards, 168 | }) 169 | } 170 | 171 | // module.exports = { getConfig, getCards, getTracks, getPlayinfo, search } 172 | -------------------------------------------------------------------------------- /XPTV/JS/guanying.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/kingreevice/my_xptv/main/js/GYING_2025_2.js 2 | //方佬改进 3 | //2025-2-5由于网站dns劫持,修改 4 | const cheerio = createCheerio() 5 | const UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_2 like Mac OS X) AppleWebKit/604.1.14 (KHTML, like Gecko)' 6 | 7 | const appConfig = { 8 | ver: 1, 9 | title: '观影网', 10 | site: 'https://www.gying.org/', 11 | tabs: [ 12 | { 13 | name: '电影', 14 | ext: { 15 | id: 'mv?page=', 16 | }, 17 | }, 18 | { 19 | name: '剧集', 20 | ext: { 21 | id: 'tv?page=', 22 | }, 23 | }, 24 | { 25 | name: '动漫', 26 | ext: { 27 | id: 'ac?page=', 28 | }, 29 | } 30 | 31 | ], 32 | } 33 | async function getConfig() { 34 | return jsonify(appConfig) 35 | } 36 | 37 | async function getCards(ext) { 38 | ext = argsify(ext) 39 | let cards = [] 40 | let { page = 1, id } = ext 41 | const url =`${appConfig.site}${id}${page}` 42 | //$utils.toastError(url); 43 | const { data } = await $fetch.get(url, { 44 | headers: { 45 | "User-Agent": UA, 46 | }, 47 | }); 48 | const $ = cheerio.load(data) 49 | 50 | const t1 = $('p.error').text() 51 | if ($('p.error').length > 0) { 52 | $utils.openSafari(appConfig.site, UA); 53 | } 54 | 55 | 56 | const scriptContent = $('script').filter((_, script) => { 57 | return $(script).html().includes('_obj.header'); 58 | }).html(); 59 | 60 | const jsonStart = scriptContent.indexOf('{'); 61 | const jsonEnd = scriptContent.lastIndexOf('}') + 1; 62 | const jsonString = scriptContent.slice(jsonStart, jsonEnd); 63 | 64 | const inlistMatch = jsonString.match(/_obj\.inlist=({.*});/); 65 | if (!inlistMatch) { 66 | $utils.toastError("未找到 _obj.inlist 数据"); 67 | } else { 68 | 69 | const inlistData = JSON.parse(inlistMatch[1]); 70 | 71 | inlistData["i"].forEach((item,index)=>{ 72 | 73 | cards.push({ 74 | vod_id: item, 75 | vod_name: inlistData["t"][index], 76 | vod_pic: `https://s.tutu.pm/img/${inlistData["ty"]}/${item}.webp`, 77 | vod_remarks: inlistData["g"][index], 78 | ext: { 79 | url: `${appConfig.site}res/downurl/${inlistData["ty"]}/${item}`, 80 | }, 81 | }) 82 | }) 83 | } 84 | return jsonify({ 85 | list: cards, 86 | }) 87 | } 88 | 89 | async function getTracks(ext) { 90 | 91 | ext = argsify(ext) 92 | let tracks = [] 93 | let url = ext.url 94 | 95 | const { data } = await $fetch.get(url, { 96 | headers: { 97 | 'User-Agent': UA, 98 | }, 99 | }) 100 | const respstr =JSON.parse(data) 101 | 102 | if(respstr.hasOwnProperty('panlist')){ 103 | const regex = { 104 | '中英': /中英/g, 105 | '1080P': /1080P/g, 106 | '杜比': /杜比/g, 107 | '原盘': /原盘/g, 108 | '1080p': /1080p/g, 109 | '双语字幕': /双语字幕/g, 110 | }; 111 | respstr.panlist.url.forEach((item, index) => { 112 | 113 | let name = '' 114 | for (const keyword in regex) { 115 | const matches = respstr.panlist.name[index].match(regex[keyword]); 116 | if(matches){ 117 | 118 | name = `${name}${matches[0]}` 119 | } 120 | 121 | } 122 | //${respstr.panlist.tname[respstr.panlist.type[index]]} 123 | tracks.push({ 124 | name:name, 125 | pan: item, 126 | ext: { 127 | url: '', 128 | }, 129 | }) 130 | }) 131 | }else if(respstr.hasOwnProperty('file')){ 132 | 133 | $utils.toastError('网盘验证掉签请前往主站完成验证数字') 134 | }else{ 135 | 136 | $utils.toastError('没有网盘资源'); 137 | 138 | } 139 | return jsonify({ 140 | list: [ 141 | { 142 | title: '默认分组', 143 | tracks, 144 | }, 145 | ], 146 | }) 147 | } 148 | 149 | async function getPlayinfo(ext) { 150 | ext = argsify(ext) 151 | const url = ext.url 152 | 153 | return jsonify({ urls: [ext.url] }) 154 | } 155 | 156 | async function search(ext) { 157 | ext = argsify(ext) 158 | 159 | 160 | let text = encodeURIComponent(ext.text) 161 | let page = ext.page || 1 162 | let url = `${appConfig.site}/s/1---${page}/${text}` 163 | 164 | const { data } = await $fetch.get(url, { 165 | headers: { 166 | "User-Agent": UA, 167 | }, 168 | }) 169 | 170 | const $ = cheerio.load(data) 171 | let cards = [] 172 | $('.v5d').each((index, element) => { 173 | const name = $(element).find('b').text().trim() || 'N/A'; 174 | const imgUrl = $(element).find('picture source[data-srcset]').attr('data-srcset') || 'N/A'; 175 | 176 | const additionalInfo = $(element).find('p').text().trim() || 'N/A'; 177 | 178 | const pathMatch = $(element).find('a').attr('href') || 'N/A' 179 | cards.push({ 180 | vod_id: pathMatch, 181 | vod_name: name, 182 | vod_pic: imgUrl, 183 | vod_remarks: additionalInfo, 184 | 185 | ext: { 186 | url: `${appConfig.site}/res/downurl${pathMatch}`, 187 | }, 188 | }) 189 | }); 190 | return jsonify({ 191 | list: cards, 192 | }) 193 | } 194 | -------------------------------------------------------------------------------- /XPTV/JS/pandatv.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/pandatv.js 2 | const headers = { 3 | 'Referer': 'https://m.pandalive.co.kr/', 4 | 'Origin': 'https://m.pandalive.co.kr', 5 | 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_2_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.2 Mobile/15E148 Safari/604.1', 6 | }; 7 | 8 | let appConfig = { 9 | ver: 1, 10 | title: 'pandatv', 11 | site: 'https://m.pandalive.co.kr', 12 | tabs: [ 13 | { 14 | name: '最热', 15 | ui: 1, 16 | ext: { 17 | orderBy: 'hot', 18 | onlyNewBj: 'N', 19 | }, 20 | }, 21 | { 22 | name: '最新', 23 | ui: 1, 24 | ext: { 25 | orderBy: 'new', 26 | onlyNewBj: 'N', 27 | }, 28 | }, 29 | { 30 | name: '顺序', 31 | ui: 1, 32 | ext: { 33 | orderBy: 'user', 34 | onlyNewBj: 'N', 35 | }, 36 | }, 37 | { 38 | name: '新BJ', 39 | ui: 1, 40 | ext: { 41 | orderBy: 'user', 42 | onlyNewBj: 'Y', 43 | }, 44 | }, 45 | ], 46 | }; 47 | 48 | async function getConfig() { 49 | return jsonify(appConfig); 50 | } 51 | 52 | async function getCards(ext) { 53 | ext = argsify(ext); 54 | let cards = []; 55 | let { orderBy, onlyNewBj ,page = 1 } = ext; 56 | let url = `${appConfig.site.replace('m', 'api')}/v1/live`; 57 | let offset = 0; 58 | let limit = 80; 59 | 60 | if (page > 1) { 61 | offset = 75 + (page - 2) * 20; 62 | limit = 25; 63 | } 64 | 65 | const body = { 66 | offset: offset, 67 | limit: limit, 68 | orderBy: orderBy, 69 | onlyNewBj: onlyNewBj, 70 | }; 71 | 72 | const { data } = await $fetch.post(url, body, { 73 | headers: headers, 74 | }); 75 | 76 | argsify(data).list.forEach((e) => { 77 | let koreaTime = new Date(e.startTime.replace(' ', 'T')); 78 | koreaTime.setHours(koreaTime.getHours() + 7); 79 | let beijingTime = koreaTime.toISOString().replace('T', ' ').slice(0, 19); 80 | cards.push({ 81 | vod_id: e.userIdx.toString(), 82 | vod_name: e.title, 83 | vod_pic: e.thumbUrl, 84 | vod_remarks: e.sizeHeight + 'P', 85 | vod_pubdate: beijingTime, 86 | vod_duration: e.userNick, 87 | ext: { 88 | userId: e.userId, 89 | }, 90 | }); 91 | }); 92 | 93 | return jsonify({ 94 | list: cards, 95 | }); 96 | } 97 | 98 | async function getTracks(ext) { 99 | ext = argsify(ext); 100 | let tracks = []; 101 | let url = `${appConfig.site.replace('m', 'api')}/v1/live/play`; 102 | let userId = ext.userId; 103 | 104 | const body = { 105 | action: 'watch', 106 | userId: userId, 107 | password: '', 108 | shareLinkType: '', 109 | }; 110 | 111 | const { data } = await $fetch.post(url, body, { 112 | headers: headers, 113 | }); 114 | 115 | const sourceurl = argsify(data).PlayList.hls[0].url + '&player_version=1.22.0'; 116 | 117 | const {data: data2} = await $fetch.get(sourceurl, { 118 | headers: headers, 119 | }); 120 | 121 | data2.split('#EXT-X-MEDIA:').slice(1).map(m3u => { 122 | const name = m3u.match(/NAME="(.*?)"/)[1]; 123 | const link = m3u.match(/https?:\/\/[^\s]+\.m3u8/)[0]; 124 | tracks.push({ 125 | name: name, 126 | ext: { 127 | playurl: link, 128 | }, 129 | }); 130 | }); 131 | 132 | return jsonify({ 133 | list: [ 134 | { 135 | title: '默认分组', 136 | tracks, 137 | }, 138 | ], 139 | }); 140 | } 141 | 142 | async function getPlayinfo(ext) { 143 | ext = argsify(ext); 144 | let playurl = ext.playurl; 145 | return jsonify({ 146 | urls: [playurl], 147 | headers: [headers] 148 | }); 149 | } 150 | 151 | async function search(ext) { 152 | ext = argsify(ext); 153 | let cards = []; 154 | const text = ext.text; 155 | const page = ext.page || 1; 156 | let url = `${appConfig.site.replace('m', 'api')}/v1/live`; 157 | let offset = 0; 158 | let limit = 80; 159 | 160 | if (page > 1) { 161 | offset = 75 + (page - 2) * 20; 162 | limit = 25; 163 | } 164 | 165 | const body = { 166 | offset: offset, 167 | limit: limit, 168 | orderBy: 'user', 169 | searchVal: text, 170 | }; 171 | 172 | const { data } = await $fetch.post(url, body, { 173 | headers: headers, 174 | }); 175 | 176 | argsify(data).list.forEach((e) => { 177 | let koreaTime = new Date(e.startTime.replace(' ', 'T')); 178 | koreaTime.setHours(koreaTime.getHours() + 7); 179 | let beijingTime = koreaTime.toISOString().replace('T', ' ').slice(0, 19); 180 | cards.push({ 181 | vod_id: e.userIdx.toString(), 182 | vod_name: e.title, 183 | vod_pic: e.thumbUrl, 184 | vod_remarks: e.sizeHeight + 'P', 185 | vod_pubdate: beijingTime, 186 | vod_duration: e.userNick, 187 | ext: { 188 | userId: e.userId, 189 | }, 190 | }); 191 | }); 192 | 193 | return jsonify({ 194 | list: cards, 195 | }); 196 | } -------------------------------------------------------------------------------- /XPTV/JS/rou.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/rou.js 2 | //来自群友“tou tie” 3 | const cheerio = createCheerio() 4 | 5 | // 设置User Agent,模拟iPhone浏览器 6 | const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0' 7 | 8 | let appConfig = { 9 | ver: 1, 10 | title: '肉视频', 11 | site: 'https://rou.video', 12 | tabs: [ 13 | { 14 | name: '國產AV', 15 | ui: 1, 16 | ext: { 17 | url: 'https://rou.video/t/國產AV', 18 | }, 19 | }, 20 | { 21 | name: '探花', 22 | ui: 1, 23 | ext: { 24 | url: 'https://rou.video/t/探花', 25 | }, 26 | }, 27 | { 28 | name: '自拍流出', 29 | ui: 1, 30 | ext: { 31 | url: 'https://rou.video/t/自拍流出', 32 | }, 33 | }, 34 | { 35 | name: 'OnlyFans', 36 | ui: 1, 37 | ext: { 38 | url: 'https://rou.video/t/OnlyFans', 39 | }, 40 | }, 41 | { 42 | name: '日本', 43 | ui: 1, 44 | ext: { 45 | url: 'https://rou.video/t/日本', 46 | }, 47 | }, 48 | ], 49 | } 50 | 51 | async function getConfig() { 52 | let config = appConfig 53 | return jsonify(config) 54 | } 55 | 56 | async function getCards(ext) { 57 | ext = argsify(ext) 58 | let cards = [] 59 | let { page = 1, url } = ext 60 | 61 | if (page > 1) { 62 | url += `?order=createdAt&page=${page}` 63 | } 64 | 65 | const { data } = await $fetch.get(url, { 66 | headers: { 67 | 'User-Agent': UA, 68 | }, 69 | }) 70 | 71 | const $ = cheerio.load(data) 72 | 73 | $('.grid.grid-cols-2.mb-6 > div').each((_, element) => { 74 | if ($(element).find('.relative').length == 0) return 75 | const href = $(element).find('.relative a').attr('href') 76 | const title = $(element).find('img:last').attr('alt') 77 | const cover = $(element).find('img').attr('src') 78 | const subTitle = $(element).find('.relative a > div:eq(1)').text() 79 | const hdinfo = $(element).find('.relative a > div:first').text() 80 | cards.push({ 81 | vod_id: href, 82 | vod_name: title, 83 | vod_pic: cover, 84 | vod_remarks: subTitle || hdinfo, 85 | ext: { 86 | url: appConfig.site + href, 87 | }, 88 | }) 89 | }) 90 | 91 | return jsonify({ 92 | list: cards, 93 | }) 94 | } 95 | 96 | async function getTracks(ext) { 97 | ext = argsify(ext) 98 | let tracks = [] 99 | let url = ext.url.match(/https?:\/\/rou\.video\/v\/(\w+)/)[1] 100 | let playUrl = `https://rou.video/api/v/${url}` 101 | tracks.push({ 102 | name: '播放', 103 | pan: '', 104 | ext: { 105 | url: playUrl, 106 | }, 107 | }) 108 | 109 | return jsonify({ 110 | list: [ 111 | { 112 | title: '默认分组', 113 | tracks, 114 | }, 115 | ], 116 | }) 117 | } 118 | 119 | async function getPlayinfo(ext) { 120 | ext = argsify(ext) 121 | const url = ext.url 122 | const { data } = await $fetch.get(url, { 123 | headers: { 124 | 'User-Agent': UA, 125 | }, 126 | }) 127 | const reslut = argsify(data) 128 | 129 | const playurl = reslut.video.videoUrl 130 | 131 | 132 | return jsonify({ urls: [playurl], headers: [{ 'User-Agent': UA }] }) 133 | } 134 | 135 | async function search(ext) { 136 | ext = argsify(ext) 137 | let cards = [] 138 | 139 | let text = encodeURIComponent(ext.text) 140 | let page = ext.page || 1 141 | let url = `${appConfig.site}/search?q=${text}&t=&page=${page}` 142 | 143 | const { data } = await $fetch.get(url, { 144 | headers: { 145 | 'User-Agent': UA, 146 | }, 147 | }) 148 | 149 | const $ = cheerio.load(data) 150 | 151 | $('.grid.grid-cols-2.mb-6 > div').each((_, element) => { 152 | if ($(element).find('.relative').length == 0) return 153 | const href = $(element).find('.relative a').attr('href') 154 | const title = $(element).find('img:last').attr('alt') 155 | const cover = $(element).find('img').attr('src') 156 | const subTitle = $(element).find('.relative a > div:eq(1)').text() 157 | const hdinfo = $(element).find('.relative a > div:first').text() 158 | cards.push({ 159 | vod_id: href, 160 | vod_name: title, 161 | vod_pic: cover, 162 | vod_remarks: subTitle || hdinfo, 163 | ext: { 164 | url: appConfig.site + href, 165 | }, 166 | }) 167 | }) 168 | 169 | return jsonify({ 170 | list: cards, 171 | }) 172 | } -------------------------------------------------------------------------------- /XPTV/JS/jable.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/Yswag/xptv-extensions/main/js/jable.js 2 | const cheerio = createCheerio() 3 | 4 | const UA = 5 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36' 6 | 7 | let appConfig = { 8 | ver: 1, 9 | title: 'jable', 10 | site: 'https://jable.tv', 11 | } 12 | 13 | async function getConfig() { 14 | let config = appConfig 15 | config.tabs = await getTabs() 16 | return jsonify(config) 17 | } 18 | 19 | async function getTabs() { 20 | let list = [] 21 | let ignore = ['首页'] 22 | function isIgnoreClassName(className) { 23 | return ignore.some((element) => className.includes(element)) 24 | } 25 | let classurl = `${appConfig.site}/categories/?mode=async&function=get_block&block_id=list_categories_video_categories_list&sort_by=avg_videos_popularity` 26 | 27 | const { data } = await $fetch.get(classurl, { 28 | headers: { 29 | 'User-Agent': UA, 30 | }, 31 | }) 32 | if (data.includes('Just a moment...')) { 33 | $utils.openSafari(classurl, UA) 34 | } 35 | const $ = cheerio.load(data) 36 | 37 | let allClass = $('.container .col-6.col-sm-4.col-lg-3') 38 | allClass.each((_, e) => { 39 | const name = $(e).find('h4').text() 40 | const href = $(e).find('a').attr('href') 41 | const isIgnore = isIgnoreClassName(name) 42 | if (isIgnore) return 43 | 44 | list.push({ 45 | name, 46 | ext: { 47 | typeurl: href, 48 | }, 49 | ui: 1, 50 | }) 51 | }) 52 | 53 | return list 54 | } 55 | 56 | async function getCards(ext) { 57 | ext = argsify(ext) 58 | let cards = [] 59 | let { page = 1, typeurl } = ext 60 | const url = 61 | typeurl + 62 | `?mode=async&function=get_block&block_id=list_videos_common_videos_list&sort_by=post_date&from=${page}&_=${Date.now()}` 63 | 64 | const { data } = await $fetch.get(url, { 65 | headers: { 66 | 'User-Agent': UA, 67 | Cookie: 'language=cn_CN', 68 | }, 69 | }) 70 | if (data.includes('Just a moment...')) { 71 | $utils.openSafari(url, UA) 72 | } 73 | const $ = cheerio.load(data) 74 | 75 | $('#list_videos_common_videos_list .container .row > div').each( 76 | (_, element) => { 77 | const href = $(element).find('.title a').attr('href') 78 | const title = $(element).find('.title a').text() 79 | const cover = $(element).find('.img-box img').attr('data-src') 80 | const duration = $(element).find('.label').text() 81 | 82 | cards.push({ 83 | vod_id: href, 84 | vod_name: title, 85 | vod_pic: cover, 86 | vod_duration: duration, 87 | ext: { 88 | url: href, 89 | }, 90 | }) 91 | } 92 | ) 93 | 94 | return jsonify({ 95 | list: cards, 96 | }) 97 | } 98 | 99 | async function getTracks(ext) { 100 | ext = argsify(ext) 101 | let tracks = [] 102 | let url = ext.url 103 | 104 | const { data } = await $fetch.get(url, { 105 | headers: { 106 | 'User-Agent': UA, 107 | }, 108 | }) 109 | if (data.includes('Just a moment...')) { 110 | $utils.openSafari(url, UA) 111 | } 112 | const $ = cheerio.load(data) 113 | let script = $('#site-content .container .col') 114 | .eq(0) 115 | .find('section') 116 | .eq(0) 117 | .find('script:last') 118 | .text() 119 | let playUrl = script.match(/var hlsUrl = '(.*)';/)[1] 120 | 121 | tracks.push({ 122 | name: '播放', 123 | pan: '', 124 | ext: { 125 | url: playUrl, 126 | }, 127 | }) 128 | 129 | return jsonify({ 130 | list: [ 131 | { 132 | title: '默认分组', 133 | tracks, 134 | }, 135 | ], 136 | }) 137 | } 138 | 139 | async function getPlayinfo(ext) { 140 | ext = argsify(ext) 141 | const url = ext.url 142 | 143 | return jsonify({ urls: [url] }) 144 | } 145 | 146 | async function search(ext) { 147 | ext = argsify(ext) 148 | let cards = [] 149 | 150 | let text = encodeURIComponent(ext.text) 151 | let page = ext.page || 1 152 | let url = `${ 153 | appConfig.site 154 | }/search/${text}/?mode=async&function=get_block&block_id=list_videos_videos_list_search_result&q=${text}&sort_by=&from=${page}&_=${Date.now()}` 155 | 156 | const { data } = await $fetch.get(url, { 157 | headers: { 158 | 'User-Agent': UA, 159 | }, 160 | }) 161 | 162 | const $ = cheerio.load(data) 163 | 164 | $('#list_videos_videos_list_search_result .container .row > div').each( 165 | (_, element) => { 166 | const href = $(element).find('.title a').attr('href') 167 | const title = $(element).find('.title a').text() 168 | const cover = $(element).find('.img-box img').attr('data-src') 169 | const duration = $(element).find('.label').text() 170 | 171 | cards.push({ 172 | vod_id: href, 173 | vod_name: title, 174 | vod_pic: cover, 175 | vod_duration: duration, 176 | ext: { 177 | url: href, 178 | }, 179 | }) 180 | } 181 | ) 182 | 183 | return jsonify({ 184 | list: cards, 185 | }) 186 | } 187 | -------------------------------------------------------------------------------- /XPTV/JS/ppp.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/ppp.js 2 | // 來自群友:夢 3 | const cheerio = createCheerio() 4 | 5 | const UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.1.1 Mobile/15E148 Safari/604.1' 6 | 7 | let appConfig = { 8 | ver: 1, 9 | title: 'pppPorn', 10 | site: 'https://ppp.porn', 11 | } 12 | async function getConfig() { 13 | let config = appConfig 14 | config.tabs = await getTabs() 15 | return jsonify(config) 16 | } 17 | 18 | async function getTabs() { 19 | let list = [] 20 | 21 | let classUrl = `${appConfig.site}/categories/` 22 | 23 | const { data } = await $fetch.get(classUrl, { 24 | headers: { 25 | 'User-Agent': UA, 26 | 'Referer': 'https://ppp.porn/pp1/', 27 | }, 28 | }) 29 | 30 | const $ = cheerio.load(data) 31 | 32 | $('section.padding-bottom-xl .card-cat-v2').each((_, e) => { 33 | const title = $(e).find('.card-cat-v2__title').text().trim() 34 | const count = $(e).find('.card-cat-v2__count').text().trim() 35 | const name = `${title}(${count})` 36 | const href = $(e).find('a').attr('href') 37 | list.push({ 38 | name, 39 | ui: 1, 40 | ext: { 41 | href: href, 42 | }, 43 | }) 44 | }) 45 | return list 46 | } 47 | 48 | async function getCards(ext) { 49 | ext = argsify(ext) 50 | let cards = [] 51 | let {href, page = 1 } = ext 52 | 53 | let url = `${href}?mode=async&function=get_block&block_id=list_videos_common_videos_list&sort_by=post_date&from=${page}` 54 | 55 | const { data } = await $fetch.get(url, { 56 | headers: { 57 | 'User-Agent': UA, 58 | }, 59 | }) 60 | 61 | const $ = cheerio.load(data) 62 | $('#list_videos_common_videos_list_items .item').each((_, element) => { 63 | const title = $(element).find('h4 a').text().trim() 64 | const cover = $(element).find('img').attr('data-src') 65 | const href = $(element).find('h4 a').attr('href') 66 | const duration = $(element).find('.card-video__duration').text() 67 | cards.push({ 68 | vod_id: href, 69 | vod_name: title, 70 | vod_pic: cover, 71 | vod_duration: duration, 72 | vod_remarks: '', 73 | ext: { 74 | url: href, 75 | }, 76 | }) 77 | }) 78 | return jsonify({ 79 | list: cards, 80 | }) 81 | } 82 | 83 | async function getTracks(ext) { 84 | ext = argsify(ext) 85 | let tracks = [] 86 | let url = ext.url 87 | 88 | const { data } = await $fetch.get(url, { 89 | headers: { 90 | 'User-Agent': UA, 91 | }, 92 | }) 93 | 94 | const $ = cheerio.load(data) 95 | let m3u8Url = null 96 | $('script').each((i, script) => { 97 | const content = $(script).html() 98 | if (content.includes('.m3u8')) { 99 | m3u8Url = content.match(/https?:\/\/[\w./-]+\.m3u8/)[0] 100 | if (m3u8Url) { 101 | tracks.push({ 102 | name: '播放', 103 | ext: { 104 | url: m3u8Url, 105 | }, 106 | }) 107 | } 108 | } 109 | }) 110 | return jsonify({ 111 | list: [ 112 | { 113 | title: '默认分组', 114 | tracks, 115 | }, 116 | ], 117 | }) 118 | } 119 | 120 | async function getPlayinfo(ext) { 121 | ext = argsify(ext) 122 | const url = ext.url 123 | return jsonify({ urls: [url] }) 124 | } 125 | 126 | async function search(ext) { 127 | ext = argsify(ext) 128 | let cards = [] 129 | const text = encodeURIComponent(ext.text) 130 | let page = ext.page || 1 131 | 132 | let url = `${appConfig.site}/search/${text}/?mode=async&function=get_block&block_id=list_videos_videos_list_search_result&q=${text}&category_ids=&sort_by=&from_videos=${page}&from_albums=${page}` 133 | 134 | const { data } = await $fetch.get(url, { 135 | headers: { 136 | 'User-Agent': UA, 137 | }, 138 | }) 139 | 140 | const $ = cheerio.load(data) 141 | $('#list_videos_videos_list_search_result_items .item').each((_, element) => { 142 | const title = $(element).find('h4 a').text().trim() 143 | const cover = $(element).find('img').attr('data-src') 144 | const href = $(element).find('h4 a').attr('href') 145 | const duration = $(element).find('.card-video__duration').text() 146 | cards.push({ 147 | vod_id: href, 148 | vod_name: title, 149 | vod_pic: cover, 150 | vod_duration: duration, 151 | vod_remarks: '', 152 | ext: { 153 | url: href, 154 | }, 155 | }) 156 | }) 157 | return jsonify({ 158 | list: cards, 159 | }) 160 | } 161 | -------------------------------------------------------------------------------- /XPTV/JS/twivideo.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/Yswag/xptv-extensions/main/js/twivideo.js 2 | const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0' 3 | const config = argsify($config_str) 4 | const cheerio = createCheerio() 5 | 6 | let appConfig = { 7 | ver: 20250321, 8 | title: 'twivideo', 9 | site: 'https://twivideo.net/', 10 | tabs: [ 11 | { 12 | name: '新着DL', 13 | ext: { 14 | type: '0', 15 | order: 'post_date', 16 | ty: 'p4', 17 | }, 18 | }, 19 | { 20 | name: 'ランキング (24時間)', 21 | ext: { 22 | type: 'ranking', 23 | order: '24', 24 | ty: 'p6', 25 | }, 26 | }, 27 | { 28 | name: 'ランキング (3日間)', 29 | ext: { 30 | type: 'ranking', 31 | order: '72', 32 | ty: 'p6', 33 | }, 34 | }, 35 | { 36 | name: 'ランキング (1週間)', 37 | ext: { 38 | type: 'ranking', 39 | order: '168', 40 | ty: 'p6', 41 | }, 42 | }, 43 | { 44 | name: '急上昇', 45 | ext: { 46 | type: 'trending', 47 | order: 'r_count', 48 | ty: 'p7', 49 | }, 50 | }, 51 | { 52 | name: '高評価', 53 | ext: { 54 | type: 'likeranking', 55 | order: '24', 56 | ty: 'p6', 57 | }, 58 | }, 59 | ], 60 | } 61 | 62 | async function getConfig() { 63 | return jsonify(appConfig) 64 | } 65 | 66 | async function getCards(ext) { 67 | ext = argsify(ext) 68 | let cards = [] 69 | let { type, order, ty, page = 1 } = ext 70 | 71 | try { 72 | const url = `${appConfig.site}/templates/view_lists.php` 73 | 74 | let offset = (page - 1) * 50 75 | const { data } = await $fetch.post( 76 | url, 77 | { 78 | offset: offset, 79 | limit: 50, 80 | tag: 'null', 81 | type: type, 82 | order: order, 83 | le: 1000, 84 | ty: ty, 85 | offset_int: offset, 86 | }, 87 | { 88 | headers: { 89 | 'User-Agent': UA, 90 | Referer: appConfig.site + '/', 91 | }, 92 | } 93 | ) 94 | 95 | const $ = cheerio.load(data) 96 | 97 | let list = $('div.art_li') 98 | 99 | list.each((_, e) => { 100 | let img = $(e).find('.item_image img').attr('src') 101 | let url = $(e).find('.item_link').attr('href') 102 | cards.push({ 103 | vod_id: url, 104 | // vod_name: $(e).find('.item_link').attr('data-id'), 105 | vod_name: '', 106 | vod_pic: img, 107 | ext: { 108 | id: url, 109 | }, 110 | }) 111 | }) 112 | 113 | return jsonify({ 114 | list: cards, 115 | }) 116 | } catch (error) { 117 | $print(error) 118 | } 119 | } 120 | 121 | async function getTracks(ext) { 122 | ext = argsify(ext) 123 | 124 | let id = ext.id 125 | let tracks = [ 126 | { 127 | name: '播放', 128 | pan: '', 129 | ext: { 130 | id, 131 | }, 132 | }, 133 | ] 134 | 135 | return jsonify({ 136 | list: [ 137 | { 138 | title: '默认分组', 139 | tracks: tracks, 140 | }, 141 | ], 142 | }) 143 | } 144 | 145 | async function getPlayinfo(ext) { 146 | ext = argsify(ext) 147 | let { id } = ext 148 | 149 | return jsonify({ urls: [id], headers: [{ 'User-Agent': UA }] }) 150 | } 151 | 152 | async function search(ext) { 153 | ext = argsify(ext) 154 | let cards = [] 155 | 156 | const text = encodeURIComponent(ext.text) 157 | const page = ext.page || 1 158 | const url = `${appConfig.site}/templates/ajax_twitteroauth_v2.php` 159 | 160 | const { data } = await $fetch.post( 161 | url, 162 | { 163 | url: text, 164 | }, 165 | { 166 | headers: { 167 | 'User-Agent': UA, 168 | Referer: appConfig.site + '/', 169 | }, 170 | } 171 | ) 172 | 173 | const $ = cheerio.load(data) 174 | 175 | cards.push({ 176 | vod_id: $(e).find('.item_link').attr('href'), 177 | vod_name: $(e).find('.item_link').attr('data-id'), 178 | vod_pic: $('img').attr('src'), 179 | ext: { 180 | id: $(e).find('.item_link').attr('href'), 181 | }, 182 | }) 183 | 184 | return jsonify({ 185 | list: cards, 186 | }) 187 | } 188 | -------------------------------------------------------------------------------- /XPTV/JS/sgsd.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/sgsd.js 2 | const cheerio = createCheerio() 3 | 4 | const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' 5 | 6 | const appConfig = { 7 | ver: 1, 8 | title: '追光影视', 9 | site: 'https://www.sgsd.xyz', 10 | tabs: [ 11 | { 12 | name: '全部', 13 | ext: { 14 | id: '/api/movie/list?columnValue=serial&genres=', 15 | }, 16 | }, 17 | { 18 | name: '女频恋爱', 19 | ext: { 20 | id: '/api/movie/list?columnValue=serial&genres=女频恋爱', 21 | }, 22 | }, 23 | { 24 | name: '反转爽剧', 25 | ext: { 26 | id: '/api/movie/list?columnValue=serial&genres=反转爽剧', 27 | }, 28 | }, 29 | { 30 | name: '古装仙侠', 31 | ext: { 32 | id: '/api/movie/list?columnValue=serial&genres=古装仙侠', 33 | }, 34 | }, 35 | { 36 | name: '年代穿越', 37 | ext: { 38 | id: '/api/movie/list?columnValue=serial&genres=年代穿越', 39 | }, 40 | }, 41 | { 42 | name: '脑洞悬疑', 43 | ext: { 44 | id: '/api/movie/list?columnValue=serial&genres=脑洞悬疑', 45 | }, 46 | }, 47 | { 48 | name: '现代都市', 49 | ext: { 50 | id: '/api/movie/list?columnValue=serial&genres=现代都市', 51 | }, 52 | }, 53 | ], 54 | } 55 | 56 | async function getConfig() { 57 | return jsonify(appConfig) 58 | } 59 | 60 | async function getCards(ext) { 61 | ext = argsify(ext) 62 | let cards = [] 63 | let { page = 1, id } = ext 64 | 65 | const url = appConfig.site + id +`&pageNum=${page}&pageSize=30&orderByColumn=createTime&isAsc=desc` 66 | 67 | const { data } = await $fetch.get(url, { 68 | headers: { 69 | 'User-Agent': UA, 70 | }, 71 | }) 72 | 73 | argsify(data).rows.forEach((e) => { 74 | cards.push({ 75 | vod_id: `${e.id}`, 76 | vod_name: e.title, 77 | vod_pic: e.poster, 78 | vod_pubdate: e.createTime.split('T')[0], 79 | ext: { 80 | url: `${appConfig.site}/column/serial/movie/${e.id}`, 81 | }, 82 | }) 83 | }) 84 | 85 | return jsonify({ 86 | list: cards, 87 | }) 88 | } 89 | 90 | async function getTracks(ext) { 91 | ext = argsify(ext) 92 | let tracks = [] 93 | let url = ext.url 94 | 95 | const { data } = await $fetch.get(url, { 96 | headers: { 97 | 'User-Agent': UA, 98 | }, 99 | }) 100 | 101 | const $ = cheerio.load(data) 102 | 103 | const playlist = $('.clearfix > li > a') 104 | playlist.each((_, e) => { 105 | const href = $(e).attr('href') 106 | const fullName = $(e).find('p').text() 107 | const match = fullName.match(/第(\d+)集/) 108 | const name = match ? `第${match[1]}集` : fullName; 109 | tracks.push({ 110 | name, 111 | pan: "", 112 | ext: { 113 | 'url': `${appConfig.site}${href}`, 114 | } 115 | }); 116 | }); 117 | return jsonify({ 118 | 119 | list: [ 120 | { 121 | title: '默认分组', 122 | tracks, 123 | }, 124 | ], 125 | }) 126 | } 127 | 128 | 129 | async function getPlayinfo(ext) { 130 | ext = argsify(ext); 131 | const url = ext.url; 132 | 133 | const { data } = await $fetch.get(url, { 134 | headers: { 135 | 'User-Agent': UA, 136 | }, 137 | }); 138 | 139 | const match = data.match(/]*>/) 140 | let playUrl = null; 141 | 142 | if (match && match[1]) { 143 | playUrl = encodeURI(match[1].trim()); 144 | } 145 | 146 | return jsonify({ urls: playUrl ? [playUrl] : [] }) 147 | 148 | } 149 | async function search(ext) { 150 | 151 | ext = argsify(ext); 152 | let cards = []; 153 | const text = encodeURIComponent(ext.text); 154 | const page = ext.page || 1; 155 | const url = `${appConfig.site}/api/movie/list?title=${text}&pageNum=${page}&pageSize=30`; 156 | 157 | const { data } = await $fetch.get(url, { 158 | headers: { 159 | 'User-Agent': UA, 160 | }, 161 | }); 162 | 163 | argsify(data).rows.forEach((e) => { 164 | cards.push({ 165 | vod_id: `${e.id}`, 166 | vod_name: e.title, 167 | vod_pic: e.poster, 168 | vod_pubdate: e.createTime.split('T')[0], 169 | ext: { 170 | url: `${appConfig.site}/column/serial/movie/${e.id}`, 171 | }, 172 | }); 173 | }); 174 | 175 | return jsonify({ 176 | list: cards, 177 | }); 178 | } 179 | -------------------------------------------------------------------------------- /XPTV/JS/uaa.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/uua.js 2 | //来着群友’夢‘ 3 | const cheerio = createCheerio() 4 | 5 | const UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.1 Mobile/15E148 Safari/604.1' 6 | 7 | let appConfig = { 8 | ver: 1, 9 | title: '有爱爱', 10 | site: 'https://www.uaa.com', 11 | tabs: [ 12 | { 13 | name: '国产视频', 14 | ui: 1, 15 | ext: { 16 | tip: 'chinese-av-porn', 17 | origin: 1, 18 | }, 19 | }, 20 | { 21 | name: '日本AV', 22 | ui: 1, 23 | ext: { 24 | tip: 'jav', 25 | origin: 1, 26 | }, 27 | }, 28 | { 29 | name: '无码流出', 30 | ui: 1, 31 | ext: { 32 | category: '无码流出', 33 | origin: 2, 34 | }, 35 | }, 36 | { 37 | name: 'H动漫', 38 | ui: 1, 39 | ext: { 40 | origin: 3, 41 | }, 42 | }, 43 | ], 44 | } 45 | 46 | async function getConfig() { 47 | return jsonify(appConfig) 48 | } 49 | 50 | async function getCards(ext) { 51 | ext = argsify(ext) 52 | let cards = [] 53 | let { tip, category, origin, page = 1 } = ext 54 | 55 | let url = appConfig.site 56 | 57 | if (tip) { 58 | url += `/${tip}` 59 | if (page > 1) { 60 | url += `?origin=${origin}$sort=1&page=${page}` 61 | } 62 | } else { 63 | url += `/video/list?` 64 | if (category && origin) url += `category=${category}&origin=${origin}` 65 | if (origin && !category) url += `origin=${origin}` 66 | if (page > 1) { 67 | url += `&$sort=1&page=${page}` 68 | } 69 | } 70 | 71 | const { data } = await $fetch.get(url, { 72 | headers: { 73 | 'User-Agent': UA, 74 | }, 75 | }) 76 | 77 | const $ = cheerio.load(data) 78 | 79 | $('li.video_li').each((_, element) => { 80 | const href = $(element).find('.title a').attr('href') 81 | const title = $(element).find('.title a').text() 82 | const cover = $(element).find('.cover').attr('src') || $(element).find('.cover').attr('data-cfsrc') 83 | const pubdate = $(element).find('span').first().text() 84 | cards.push({ 85 | vod_id: href, 86 | vod_name: title, 87 | vod_pic: cover, 88 | vod_pubdate: pubdate, 89 | ext: { 90 | url: `${appConfig.site}${href}`, 91 | }, 92 | }) 93 | }) 94 | 95 | return jsonify({ 96 | list: cards, 97 | }) 98 | } 99 | 100 | async function getTracks(ext) { 101 | ext = argsify(ext) 102 | let tracks = [] 103 | let url = ext.url 104 | 105 | const { data } = await $fetch.get(url, { 106 | headers: { 107 | 'User-Agent': UA, 108 | }, 109 | }) 110 | 111 | const $ = cheerio.load(data) 112 | const videourl = $('#mui-player').attr('src') 113 | tracks.push({ 114 | name: '播放', 115 | ext: { 116 | url: videourl, 117 | }, 118 | }) 119 | 120 | return jsonify({ 121 | list: [ 122 | { 123 | title: '默认分组', 124 | tracks, 125 | }, 126 | ], 127 | }) 128 | } 129 | 130 | async function getPlayinfo(ext) { 131 | ext = argsify(ext) 132 | const playUrl = ext.url 133 | 134 | return jsonify({ 135 | urls: [playUrl], 136 | headers: [{ 137 | 'User-Agent': UA, 138 | 'Referer': 'https://www.uaa.com/', 139 | 'Origin': 'https://www.uaa.com' 140 | }] 141 | }) 142 | } 143 | 144 | async function search(ext) { 145 | ext = argsify(ext) 146 | let cards = [] 147 | let text = encodeURIComponent(ext.text) 148 | let page = ext.page || 1 149 | let url = `${appConfig.site}/video/list?searchType=1&keyword=${text}` 150 | 151 | if(page >1){ 152 | url = `https://www.uaa.com/video/list?keyword=${text}&category=&origin=&tag=&sort=0&page=${page}` 153 | } 154 | 155 | const { data } = await $fetch.get(url, { 156 | headers: { 157 | 'User-Agent': UA, 158 | }, 159 | }) 160 | 161 | const $ = cheerio.load(data) 162 | 163 | $('li.video_li').each((_, element) => { 164 | const href = $(element).find('.title a').attr('href') 165 | const title = $(element).find('.title a').text() 166 | const cover = $(element).find('.cover').attr('src') || $(element).find('.cover').attr('data-cfsrc') 167 | const pubdate = $(element).find('span').first().text() 168 | cards.push({ 169 | vod_id: href, 170 | vod_name: title, 171 | vod_pic: cover, 172 | vod_pubdate: pubdate, 173 | ext: { 174 | url: `${appConfig.site}${href}`, 175 | }, 176 | }) 177 | }) 178 | 179 | return jsonify({ 180 | list: cards, 181 | }) 182 | } 183 | -------------------------------------------------------------------------------- /XPTV/JS/pornhub.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/Yswag/xptv-extensions/main/js/pornhub.js 2 | const cheerio = createCheerio() 3 | 4 | const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' 5 | 6 | let appConfig = { 7 | ver: 1, 8 | title: 'pornhub', 9 | site: 'https://cn.pornhub.com', 10 | tabs: [ 11 | { 12 | name: 'home', 13 | ext: { 14 | id: 'sy', 15 | }, 16 | ui: 1, 17 | }, 18 | { 19 | name: 'newest', 20 | ext: { 21 | id: 'cm', 22 | }, 23 | ui: 1, 24 | }, 25 | { 26 | name: 'most viewed', 27 | ext: { 28 | id: 'mv', 29 | }, 30 | ui: 1, 31 | }, 32 | { 33 | name: 'hottest', 34 | ext: { 35 | id: 'ht', 36 | }, 37 | ui: 1, 38 | }, 39 | { 40 | name: 'top rated', 41 | ext: { 42 | id: 'tr', 43 | }, 44 | ui: 1, 45 | }, 46 | ], 47 | } 48 | 49 | async function getConfig() { 50 | return jsonify(appConfig) 51 | } 52 | 53 | async function getCards(ext) { 54 | ext = argsify(ext) 55 | let cards = [] 56 | let { page = 1, id } = ext 57 | let url = '${ appConfig.site }' 58 | if (id === 'sy') { 59 | url = `${appConfig.site}/video?` 60 | if (page > 1) { 61 | url = url + `page=${page}` 62 | } 63 | } else { 64 | url = `${appConfig.site}/video?o=${id}` 65 | if (page > 1) { 66 | url = url + `&page=${page}` 67 | } 68 | } 69 | 70 | const { data } = await $fetch.get(url, { 71 | headers: { 72 | 'User-Agent': UA, 73 | }, 74 | }) 75 | 76 | const $ = cheerio.load(data) 77 | 78 | $('li.videoBox').each((_, element) => { 79 | const href = $(element).find('.phimage a.img').attr('href') 80 | const title = $(element).find('.title a').attr('title') 81 | const cover = $(element).find('.phimage a.img img').attr('src') || $(element).find('.phimage a.img img').attr('data-mediumthumb') || '' 82 | const subTitle = $(element).find('.views').text().trim() || '' 83 | const duration = $(element).find('.duration').text().trim() || '' 84 | cards.push({ 85 | vod_id: href, 86 | vod_name: title, 87 | vod_pic: cover, 88 | vod_remarks: subTitle, 89 | vod_duration: duration, 90 | ext: { 91 | url: appConfig.site + href, 92 | }, 93 | }) 94 | }) 95 | 96 | return jsonify({ 97 | list: cards, 98 | }) 99 | } 100 | 101 | async function getTracks(ext) { 102 | ext = argsify(ext) 103 | let tracks = [] 104 | let url = ext.url 105 | 106 | const { data } = await $fetch.get(url, { 107 | headers: { 108 | 'User-Agent': UA, 109 | }, 110 | }) 111 | 112 | const jsonStr = data.match(/var flashvars_.* = \{(.*?)\};/)[1] 113 | const json = JSON.parse('{' + jsonStr + '}') 114 | const videos = json.mediaDefinitions.filter((e) => e.format === 'hls') 115 | videos.forEach((e) => { 116 | tracks.push({ 117 | name: e.quality, 118 | pan: '', 119 | ext: { 120 | url: e.videoUrl, 121 | }, 122 | }) 123 | }) 124 | 125 | return jsonify({ 126 | list: [ 127 | { 128 | title: '默认分组', 129 | tracks, 130 | }, 131 | ], 132 | }) 133 | } 134 | 135 | async function getPlayinfo(ext) { 136 | ext = argsify(ext) 137 | const url = ext.url 138 | const headers = { 139 | 'User-Agent': UA, 140 | } 141 | 142 | return jsonify({ urls: [url], headers: [headers] }) 143 | } 144 | 145 | async function search(ext) { 146 | ext = argsify(ext) 147 | let cards = [] 148 | 149 | let text = encodeURIComponent(ext.text) 150 | let page = ext.page || 1 151 | let url = `${appConfig.site}/video/search?search=${text}&page=${page}` 152 | 153 | const { data } = await $fetch.get(url, { 154 | headers: { 155 | 'User-Agent': UA, 156 | }, 157 | }) 158 | 159 | const $ = cheerio.load(data) 160 | 161 | $('li.videoBox').each((_, element) => { 162 | const href = $(element).find('.phimage a.img').attr('href') 163 | const title = $(element).find('.title a').attr('title') 164 | const cover = $(element).find('.phimage a.img img').attr('src') || $(element).find('.phimage a.img img').attr('data-mediumthumb') || '' 165 | const subTitle = $(element).find('.views').text().trim() || '' 166 | const duration = $(element).find('.duration').text().trim() || '' 167 | cards.push({ 168 | vod_id: href, 169 | vod_name: title, 170 | vod_pic: cover, 171 | vod_remarks: subTitle, 172 | vod_duration: duration, 173 | ext: { 174 | url: appConfig.site + href, 175 | }, 176 | }) 177 | }) 178 | 179 | return jsonify({ 180 | list: cards, 181 | }) 182 | } -------------------------------------------------------------------------------- /XPTV/JS/leijing.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/fangkuia/XPTV/main/js/leijing.js 2 | const UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" 3 | const cheerio = createCheerio() 4 | 5 | const appConfig = { 6 | ver: 1, 7 | title: '雷鲸', 8 | site: 'https://www.leijing.xyz', 9 | tabs: [ 10 | { 11 | name: '剧集', 12 | ext: { 13 | id: '?tagId=42204684250355', 14 | }, 15 | }, 16 | { 17 | name: '电影', 18 | ext: { 19 | id: '?tagId=42204681950354', 20 | }, 21 | }, 22 | { 23 | name: '动漫', 24 | ext: { 25 | id: '?tagId=42204792950357', 26 | }, 27 | }, 28 | { 29 | name: '纪录片', 30 | ext: { 31 | id: '?tagId=42204697150356', 32 | }, 33 | }, 34 | { 35 | name: '综艺', 36 | ext: { 37 | id: '?tagId=42210356650363', 38 | }, 39 | }, 40 | { 41 | name: '影视原盘', 42 | ext: { 43 | id: '?tagId=42212287587456', 44 | }, 45 | }, 46 | ], 47 | } 48 | 49 | async function getConfig() { 50 | return jsonify(appConfig) 51 | } 52 | 53 | async function getCards(ext) { 54 | ext = argsify(ext) 55 | let cards = [] 56 | let { page = 1, id } = ext 57 | 58 | const url = appConfig.site + `/${id}&page=${page}` 59 | 60 | const { data } = await $fetch.get(url, { 61 | headers: { 62 | 'Referer': 'https://www.leijing.xyz/', 63 | 'User-Agent': UA, 64 | } 65 | }); 66 | 67 | const $ = cheerio.load(data); 68 | 69 | $('.topicItem').each((index, each) => { 70 | 71 | if ($(each).find('.cms-lock-solid').length > 0) return; 72 | 73 | const href = $(each).find('h2 a').attr('href'); 74 | const title = $(each).find('h2 a').text() 75 | const regex = /(?:【.*?】)?(?:(.*?))?([^\s.(]+(?:\s+[^\s.(]+)*)/; 76 | const match = title.match(regex); 77 | const dramaName = match ? match[1] : title; 78 | const r = $(each).find('.summary').text(); 79 | const tag = $(each).find('.tag').text(); 80 | 81 | if (/content/.test(r) && !/cloud/.test(r)) return; 82 | if (/软件|游戏|书籍|图片|公告|音乐|课程/.test(tag)) return; 83 | 84 | cards.push({ 85 | vod_id: href, 86 | vod_name: dramaName, 87 | vod_pic: '', 88 | vod_remarks: '', 89 | ext: { 90 | url: `https://www.leijing.xyz/${href}`, 91 | }, 92 | }); 93 | }); 94 | 95 | 96 | return jsonify({ 97 | list: cards, 98 | }); 99 | } 100 | 101 | async function getTracks(ext) { 102 | ext = argsify(ext) 103 | var tracks = [] 104 | let url = ext.url 105 | 106 | const { data } = await $fetch.get(url, { 107 | headers: { 108 | 'Referer': 'https://www.leijing.xyz/', 109 | 'User-Agent': UA, 110 | } 111 | }); 112 | 113 | const $ = cheerio.load(data); 114 | const pans = new Set(); 115 | 116 | const urlRegex = /(https?:\/\/[^\s(]+)/g; 117 | 118 | const processUrl = (url) => { 119 | if (url.startsWith('https://cloud.189.cn/') && !pans.has(url)) { 120 | pans.add(url); 121 | tracks.push({ 122 | name: "网盘", 123 | pan: url, 124 | ext: {} 125 | }); 126 | } 127 | }; 128 | 129 | $('div,p,a').each((index, each) => { 130 | const href = ($(each).attr('href') ?? "").replace('http://', 'https://'); 131 | processUrl(href); 132 | 133 | const text = $(each).text().trim(); 134 | const urls = text.match(urlRegex); 135 | if (urls) { 136 | urls.forEach(processUrl); 137 | } 138 | }); 139 | 140 | return jsonify({ list: [{ 141 | title: "默认分组", 142 | tracks, 143 | }]}) 144 | } 145 | 146 | async function getPlayinfo(ext) { 147 | return jsonify({ 'urls': [] }) 148 | } 149 | 150 | async function search(ext) { 151 | ext = argsify(ext) 152 | let cards = [] 153 | 154 | let text = encodeURIComponent(ext.text) 155 | let page = ext.page || 1 156 | let url = `${appConfig.site}/search?keyword=${text}&page=${page}` 157 | 158 | const { data } = await $fetch.get(url, { 159 | headers: { 160 | 'User-Agent': UA, 161 | }, 162 | }) 163 | 164 | 165 | const $ = cheerio.load(data); 166 | 167 | $('.topicItem').each((index, each) => { 168 | if ($(each).find('.cms-lock-solid').length > 0) return; 169 | 170 | const href = $(each).find('h2 a').attr('href'); 171 | const title = $(each).find('h2 a').text() 172 | const regex = /(?:【.*?】)?(?:(.*?))?([^\s.(]+(?:\s+[^\s.(]+)*)/; 173 | const match = title.match(regex); 174 | const dramaName = match ? match[1] : title; 175 | const r = $(each).find('.summary').text(); 176 | const tag = $(each).find('.tag').text(); 177 | 178 | if (/content/.test(r) && !/cloud/.test(r)) return; 179 | if (/软件|游戏|书籍|图片|公告|音乐|课程/.test(tag)) return; 180 | 181 | cards.push({ 182 | vod_id: href, 183 | vod_name: dramaName, 184 | vod_pic: '', 185 | vod_remarks: '', 186 | ext: { 187 | url: `https://www.leijing.xyz/${href}`, 188 | }, 189 | }); 190 | }); 191 | 192 | return jsonify({ 193 | list: cards, 194 | }) 195 | } 196 | -------------------------------------------------------------------------------- /XPTV/JS/4kav.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/Yswag/xptv-extensions/main/js/4kav.js 2 | // tv 3 | 4 | const UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Mobile/15E148 Safari/604.1' 5 | 6 | let appConfig = { 7 | ver: 1, 8 | title: '4k-av', 9 | site: 'https://4kmp.com', 10 | tabs: [ 11 | { 12 | name: '首頁', 13 | ext: { 14 | id: 0, 15 | url: 'https://4kmp.com', 16 | }, 17 | }, 18 | { 19 | name: '電影', 20 | ext: { 21 | id: 1, 22 | url: 'https://4kmp.com/movie', 23 | }, 24 | }, 25 | { 26 | name: '電視劇', 27 | ext: { 28 | id: 2, 29 | url: 'https://4kmp.com/tv', 30 | }, 31 | }, 32 | ], 33 | } 34 | 35 | async function getConfig() { 36 | return jsonify(appConfig) 37 | } 38 | 39 | async function getCards(ext) { 40 | ext = argsify(ext) 41 | // 頁數寫入cache 42 | var lastPage = { 43 | 0: 1, 44 | 1: 1, 45 | 2: 1, 46 | } 47 | let val = $cache.get('av') 48 | if (val) { 49 | lastPage = JSON.parse(val) 50 | } 51 | 52 | let cards = [] 53 | let { id, page = 1, url } = ext 54 | 55 | if (page > 1) { 56 | url += `/page-${lastPage[id] - page + 1}.html` 57 | } 58 | 59 | $print(`url: ${url}`) 60 | 61 | const { data } = await $fetch.get(url, { 62 | headers: { 63 | 'User-Agent': UA, 64 | }, 65 | }) 66 | 67 | const elems = $html.elements(data, '#MainContent_newestlist .virow .NTMitem') 68 | elems.forEach((element) => { 69 | const href = $html.attr(element, '.title a', 'href') 70 | const title = $html.text(element, '.title h2') 71 | const cover = $html.attr(element, '.poster img', 'src') 72 | const subTitle = $html.text(element, 'label[title=分辨率]').split('/')[0] 73 | cards.push({ 74 | vod_id: href, 75 | vod_name: title, 76 | vod_pic: cover, 77 | vod_remarks: subTitle, 78 | ext: { 79 | url: `${appConfig.site}${href}`, 80 | }, 81 | }) 82 | }) 83 | 84 | // get lastpage 85 | if (page == 1) { 86 | const pageNumber = $html.text(data, '#MainContent_header_nav .page-number') 87 | const num = pageNumber.split('/')[1] 88 | lastPage[id] = num 89 | const jsonData = JSON.stringify(lastPage, null, 2) 90 | $cache.set('av', jsonData) 91 | } 92 | 93 | return jsonify({ 94 | list: cards, 95 | }) 96 | } 97 | 98 | async function getTracks(ext) { 99 | ext = argsify(ext) 100 | let tracks = [] 101 | let url = ext.url 102 | 103 | const { data } = await $fetch.get(url, { 104 | headers: { 105 | 'User-Agent': UA, 106 | }, 107 | }) 108 | 109 | // 檢查是不是多集 110 | let playlist = $html.elements(data, '#rtlist li') 111 | if (playlist.length > 0) { 112 | playlist.forEach((element) => { 113 | let name = $html.text(element, 'span') 114 | let url = $html.attr(element, 'img', 'src').replace('screenshot.jpg', '') 115 | tracks.push({ 116 | name: name, 117 | pan: '', 118 | ext: { 119 | url, 120 | }, 121 | }) 122 | }) 123 | } else { 124 | tracks.push({ 125 | name: '播放', 126 | pan: '', 127 | ext: { 128 | url, 129 | }, 130 | }) 131 | } 132 | 133 | return jsonify({ 134 | list: [ 135 | { 136 | title: '默认分组', 137 | tracks, 138 | }, 139 | ], 140 | }) 141 | } 142 | 143 | async function getPlayinfo(ext) { 144 | ext = argsify(ext) 145 | let url = ext.url.replace('www.', '') 146 | 147 | const { data } = await $fetch.get(url, { 148 | headers: { 149 | 'User-Agent': UA, 150 | }, 151 | }) 152 | 153 | let playUrl = $html.attr(data, '#MainContent_videowindow video source', 'src') 154 | 155 | return jsonify({ urls: [playUrl] }) 156 | } 157 | 158 | async function search(ext) { 159 | ext = argsify(ext) 160 | let cards = [] 161 | 162 | let text = encodeURIComponent(ext.text) 163 | let url = appConfig.site + `/s?q=${text}` 164 | 165 | const { data } = await $fetch.get(url, { 166 | headers: { 167 | 'User-Agent': UA, 168 | }, 169 | }) 170 | 171 | const elems = $html.elements(data, '#MainContent_newestlist .virow .NTMitem') 172 | elems.forEach((element) => { 173 | const href = $html.attr(element, '.title a', 'href') 174 | const title = $html.text(element, '.title h2') 175 | const cover = $html.attr(element, '.poster img', 'src') 176 | const subTitle = $html.text(element, 'label[title=分辨率]').split('/')[0] 177 | cards.push({ 178 | vod_id: href, 179 | vod_name: title, 180 | vod_pic: cover, 181 | vod_remarks: subTitle, 182 | ext: { 183 | url: `${appConfig.site}${href}`, 184 | }, 185 | }) 186 | }) 187 | 188 | return jsonify({ 189 | list: cards, 190 | }) 191 | } 192 | -------------------------------------------------------------------------------- /XPTV/JS/jpyy.js: -------------------------------------------------------------------------------- 1 | // 引用链接: https://raw.githubusercontent.com/Yswag/xptv-extensions/main/js/jpyy.js 2 | // 感謝 小了白了兔 3 | //源码来自https://raw.githubusercontent.com/Yswag/xptv-extensions/refs/heads/main/js/jpyy.js 4 | //仅修改配置网址 5 | //配置: {"site":"https://www.jiabaide.cn"} 6 | const CryptoJS = createCryptoJS() 7 | 8 | const UA = 9 | 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_2_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.2 Mobile/15E148 Safari/604.1' 10 | 11 | let $config = argsify($config_str) 12 | let appConfig = { 13 | ver: 1, 14 | title: '金牌影视', 15 | site: $config.site || 'https://www.jiabaide.cn', 16 | tabs: [ 17 | { name: '电影', ext: { id: 1 } }, 18 | { name: '美剧', ext: { id: 2, area: '美国' } }, 19 | { name: '韩剧', ext: { id: 2, area: '韩国' } }, 20 | { name: '日剧', ext: { id: 2, area: '日本' } }, 21 | { name: '陆剧', ext: { id: 2, area: '中国大陆' } }, 22 | { name: '港剧', ext: { id: 2, area: '中国香港' } }, 23 | { name: '台剧', ext: { id: 2, area: '中国台湾' } }, 24 | { name: '泰剧', ext: { id: 2, area: '泰国' } }, 25 | { name: '其他', ext: { id: 2, area: '其他' } }, 26 | { name: '综艺', ext: { id: 3 } }, 27 | { name: '动漫', ext: { id: 4 } }, 28 | ], 29 | } 30 | 31 | async function getConfig() { 32 | return JSON.stringify(appConfig) 33 | } 34 | 35 | async function getCards(ext) { 36 | ext = JSON.parse(ext) 37 | let cards = [] 38 | let { id, area, page = 1 } = ext 39 | 40 | let url = `${appConfig.site}/api/mw-movie/anonymous/video/list?pageNum=${page}&pageSize=30&sort=1&sortBy=1&type1=${id}` 41 | 42 | if (area) { 43 | url = `${appConfig.site}/api/mw-movie/anonymous/video/list?area=${area}&pageNum=${page}&pageSize=30&sort=1&sortBy=1&type1=${id}` 44 | } 45 | 46 | const headers = getHeader(url) 47 | 48 | const response = await $fetch.get(url, { headers: headers }) 49 | const data = response.data 50 | 51 | JSON.parse(data).data.list.forEach((e) => { 52 | const name = e.vodName 53 | if (name.includes('预告')) return 54 | const id = e.vodId 55 | cards.push({ 56 | vod_id: id.toString(), 57 | vod_name: name, 58 | vod_pic: e.vodPic, 59 | vod_remarks: e.vodDoubanScore.toFixed(1), 60 | vod_duration: e.vodRemarks.replace(/\|.*/, '') || e.vodVersion, 61 | vod_pubdate: e.vodPubdate, 62 | ext: { id: id }, 63 | }) 64 | }) 65 | 66 | return JSON.stringify({ list: cards }) 67 | } 68 | 69 | async function getTracks(ext) { 70 | ext = JSON.parse(ext) 71 | 72 | let tracks = [] 73 | let id = ext.id 74 | let url = appConfig.site.replace('www', 'm') + '/detail/' + id 75 | 76 | const { data } = await $fetch.get(url, { headers: { 'User-Agent': UA } }) 77 | 78 | const nidData = '{"' + data.match(/episodeList.*?\[.*?\}\]\}/)[0].replace(/\\\"/g, '"') 79 | JSON.parse(nidData).episodeList.forEach((e) => { 80 | tracks.push({ 81 | name: e.name, 82 | ext: { id: id, nid: e.nid }, 83 | }) 84 | }) 85 | 86 | return JSON.stringify({ list: [{ title: '默认分组', tracks }] }) 87 | } 88 | 89 | async function getPlayinfo(ext) { 90 | ext = JSON.parse(ext) 91 | let { id, nid } = ext 92 | const url = `${appConfig.site}/api/mw-movie/anonymous/v2/video/episode/url?id=${id}&nid=${nid}` 93 | const headers = getHeader(url) 94 | 95 | const { data } = await $fetch.get(url, { headers: headers }) 96 | 97 | let playUrl = JSON.parse(data).data.list[0].url 98 | 99 | return JSON.stringify({ urls: [playUrl] }) 100 | } 101 | 102 | async function search(ext) { 103 | ext = JSON.parse(ext) 104 | let cards = [] 105 | 106 | const text = ext.text 107 | const page = ext.page || 1 108 | const url = `${appConfig.site}/api/mw-movie/anonymous/video/searchByWordPageable?keyword=${encodeURIComponent( 109 | text 110 | )}&pageNum=${page}&pageSize=12&type=false` 111 | const key = `searchByWordPageable?keyword=${text}&pageNum=${page}&pageSize=12&type=false` 112 | const headers = getHeader(key) 113 | 114 | const { data } = await $fetch.get(url, { headers: headers }) 115 | 116 | JSON.parse(data).data.list.forEach((e) => { 117 | const id = e.vodId 118 | cards.push({ 119 | vod_id: id.toString(), 120 | vod_name: e.vodName, 121 | vod_pic: e.vodPic, 122 | vod_remarks: e.vodDoubanScore.toFixed(1), 123 | vod_duration: e.vodRemarks.replace(/\|.*/, '') || e.vodVersion, 124 | vod_pubdate: e.vodPubdate, 125 | ext: { id: id }, 126 | }) 127 | }) 128 | 129 | return JSON.stringify({ list: cards }) 130 | } 131 | 132 | function getHeader(url) { 133 | const signKey = 'cb808529bae6b6be45ecfab29a4889bc' 134 | const dataStr = url.split('?')[1] 135 | const t = Date.now() 136 | const signStr = dataStr + `&key=${signKey}` + `&t=${t}` 137 | 138 | function getUUID() { 139 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (e) => 140 | ('x' === e ? (16 * Math.random()) | 0 : 'r&0x3' | '0x8').toString(16) 141 | ) 142 | } 143 | 144 | const headers = { 145 | 'User-Agent': UA, 146 | deviceId: getUUID(), 147 | t: t.toString(), 148 | sign: CryptoJS.SHA1(CryptoJS.MD5(signStr).toString()).toString(), 149 | } 150 | 151 | return headers 152 | } 153 | --------------------------------------------------------------------------------