330 lines
8.7 KiB
JavaScript
330 lines
8.7 KiB
JavaScript
const cheerio = createCheerio()
|
||
const CryptoJS = createCryptoJS()
|
||
|
||
const appConfig = {
|
||
ver: 1,
|
||
title: '哔滴影视',
|
||
// xlys.me
|
||
site: 'https://xl01.com.de',
|
||
tabs: [
|
||
{
|
||
name: '分類',
|
||
ext: {
|
||
type: 'filter',
|
||
url: '/s/all',
|
||
},
|
||
},
|
||
{
|
||
name: '最新电影',
|
||
ext: {
|
||
url: '/s/all/1?type=0',
|
||
},
|
||
},
|
||
{
|
||
name: '最新剧集',
|
||
ext: {
|
||
url: '/s/all/1?type=1',
|
||
},
|
||
},
|
||
{
|
||
name: '欧美剧集',
|
||
ext: {
|
||
url: '/s/meiju/1',
|
||
},
|
||
},
|
||
{
|
||
name: '日韩剧集',
|
||
ext: {
|
||
url: '/s/hanju/1',
|
||
},
|
||
},
|
||
{
|
||
name: '港台剧集',
|
||
ext: {
|
||
url: '/s/gangtaiju/1',
|
||
},
|
||
},
|
||
{
|
||
name: '动漫',
|
||
ext: {
|
||
url: '/s/donghua/1?type=1',
|
||
},
|
||
},
|
||
],
|
||
}
|
||
const filter = []
|
||
|
||
const UA =
|
||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36'
|
||
const headers = {
|
||
Referer: appConfig.site + '/',
|
||
Origin: appConfig.site,
|
||
'User-Agent': UA,
|
||
}
|
||
|
||
async function getConfig() {
|
||
if (!headers['Cookie']){
|
||
const { respHeaders } = await $fetch.get(appConfig.site + '/zzzzz', {
|
||
headers,
|
||
})
|
||
headers['Cookie'] = respHeaders['Set-Cookie'].split(';')[0]
|
||
}
|
||
|
||
return jsonify(appConfig)
|
||
}
|
||
|
||
async function getCards(ext) {
|
||
ext = argsify(ext)
|
||
let cards = []
|
||
|
||
let page = ext.page || 1
|
||
let url = `${appConfig.site}/s/all/${page}`
|
||
|
||
if (ext.type && ext.type === 'filter' && !ext.filters) {
|
||
const { data } = await $fetch.get(url, {
|
||
headers,
|
||
})
|
||
|
||
const $ = cheerio.load(data)
|
||
cards = await extractCards(url)
|
||
$('.all-filter-wrapper > dl').each((_, e) => {
|
||
const name = $(e).find('dt').text().replace(/:/g, '').trim()
|
||
if (filter.some((f) => f.name === name)) return
|
||
const isCategory = name === '影视类型'
|
||
|
||
const values = []
|
||
let key = ''
|
||
|
||
$(e)
|
||
.find('dd > a')
|
||
.each((_, each) => {
|
||
const subname = $(each).text().trim()
|
||
const path = $(each).attr('href') || ''
|
||
|
||
let value = ''
|
||
let currentKey = ''
|
||
|
||
if (isCategory) {
|
||
// /s/xxx
|
||
value = path.replace('/s/', '')
|
||
currentKey = 'cat'
|
||
} else {
|
||
// /s/all?type=xxx
|
||
const query = path.replace(/\/s\/all\??/, '')
|
||
const [k, v] = query.split('=')
|
||
|
||
currentKey = k
|
||
value = v || ''
|
||
}
|
||
|
||
if (!key) key = currentKey
|
||
|
||
values.push({
|
||
n: subname,
|
||
v: subname === '不限' ? '' : value,
|
||
})
|
||
})
|
||
|
||
filter.push({
|
||
name,
|
||
key,
|
||
init: values[0]?.v || '',
|
||
value: values,
|
||
})
|
||
})
|
||
$print(JSON.stringify(filter))
|
||
|
||
return jsonify({
|
||
list: cards,
|
||
filter,
|
||
})
|
||
} else if (ext.type && ext.type === 'filter' && ext.filters) {
|
||
url = `${appConfig.site}/s/${ext.filters?.cat || 'all'}/${page}?type=${ext.filters?.type || ''}&year=${ext.filters?.year || ''}&order=${ext.filters?.order || ''}`
|
||
if (ext.filters?.area) url += `&area=${ext.filters?.area}`
|
||
|
||
cards = await extractCards(url)
|
||
|
||
return jsonify({
|
||
list: cards,
|
||
filter,
|
||
})
|
||
} else {
|
||
url = url.replace('/1', `/${page}`)
|
||
|
||
cards = await extractCards(url)
|
||
|
||
return jsonify({
|
||
list: cards,
|
||
})
|
||
}
|
||
}
|
||
|
||
async function extractCards(url) {
|
||
let cards = []
|
||
const { data } = await $fetch.get(url, {
|
||
headers,
|
||
})
|
||
|
||
const $ = cheerio.load(data)
|
||
$('.card-link').each((_, each) => {
|
||
const path = $(each).find('a').attr('href')
|
||
cards.push({
|
||
vod_id: path,
|
||
vod_name: $(each).find('.card-title').text(),
|
||
vod_pic: $(each).find('img').attr('src'),
|
||
vod_remarks: $(each).find('span.badge').text(),
|
||
ext: {
|
||
url: appConfig.site + path,
|
||
},
|
||
})
|
||
})
|
||
return cards
|
||
}
|
||
|
||
async function getTracks(ext) {
|
||
const { url } = argsify(ext)
|
||
let groups = []
|
||
|
||
const { data } = await $fetch.get(url, {
|
||
headers,
|
||
})
|
||
const $ = cheerio.load(data)
|
||
let group = {
|
||
title: '在线',
|
||
tracks: [],
|
||
}
|
||
$('a.btn').each((_, each) => {
|
||
let path = $(each).attr('href') ?? ''
|
||
if (path.startsWith('/play/') || path.startsWith('/guoju/play/')) {
|
||
group.tracks.push({
|
||
name: $(each).text(),
|
||
pan: '',
|
||
ext: {
|
||
url: appConfig.site + path,
|
||
},
|
||
})
|
||
}
|
||
})
|
||
groups.push(group)
|
||
return jsonify({ list: groups })
|
||
}
|
||
|
||
async function getPlayinfo(ext) {
|
||
const { url } = argsify(ext)
|
||
const { data } = await $fetch.get(url, {
|
||
headers,
|
||
})
|
||
let pid = data.match(/var pid = (\d+);/)[1]
|
||
let currentTimeMillis = Date.now()
|
||
let str4 = pid + '-' + currentTimeMillis
|
||
let md5Hash = CryptoJS.MD5(str4).toString(CryptoJS.enc.Hex)
|
||
while (md5Hash.length < 32) {
|
||
md5Hash = '0' + md5Hash
|
||
}
|
||
md5Hash = md5Hash.toLowerCase()
|
||
let key = CryptoJS.enc.Utf8.parse(md5Hash.substring(0, 16))
|
||
let encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(str4), key, {
|
||
mode: CryptoJS.mode.ECB,
|
||
padding: CryptoJS.pad.Pkcs7,
|
||
})
|
||
let encryptedHex = encrypted.ciphertext.toString(CryptoJS.enc.Hex)
|
||
let encryptedString = encryptedHex.toUpperCase()
|
||
let lines = appConfig.site + '/lines?t=' + currentTimeMillis + '&sg=' + encryptedString + '&pid=' + pid
|
||
const data2 = (
|
||
await $fetch.get(lines, {
|
||
headers,
|
||
})
|
||
).data
|
||
|
||
if (JSON.parse(data2).data.url3) {
|
||
let url3 = JSON.parse(data2).data.url3
|
||
let play = url3.indexOf(',') !== -1 ? url3.split(',')[0].trim() : url3.trim()
|
||
return jsonify({
|
||
urls: [play],
|
||
headers: [headers],
|
||
})
|
||
} else if (JSON.parse(data2).data.tos) {
|
||
let god = `${appConfig.site}/god/${pid}?type=1`
|
||
let res = await $fetch.post(
|
||
god,
|
||
{
|
||
t: currentTimeMillis,
|
||
sg: encryptedString,
|
||
verifyCode: 888,
|
||
},
|
||
{
|
||
headers: {
|
||
'User-Agent': UA,
|
||
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
||
'X-Requested-With': 'XMLHttpRequest',
|
||
},
|
||
},
|
||
)
|
||
|
||
let playUrl = argsify(res.data).url
|
||
return jsonify({
|
||
urls: [playUrl],
|
||
headers: [{ 'User-Agent': UA }],
|
||
})
|
||
} else {
|
||
let god = `${appConfig.site}/god/${pid}`
|
||
let res = await $fetch.post(
|
||
god,
|
||
{
|
||
t: currentTimeMillis,
|
||
sg: encryptedString,
|
||
verifyCode: 666,
|
||
},
|
||
{
|
||
headers: {
|
||
'User-Agent': UA,
|
||
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
||
'X-Requested-With': 'XMLHttpRequest',
|
||
},
|
||
},
|
||
)
|
||
|
||
let playUrl = argsify(res.data).url
|
||
return jsonify({
|
||
urls: [playUrl],
|
||
headers: [headers],
|
||
})
|
||
}
|
||
}
|
||
|
||
async function search(ext) {
|
||
ext = argsify(ext)
|
||
let cards = []
|
||
|
||
let text = encodeURIComponent(ext.text)
|
||
let page = ext.page || 1
|
||
if (page > 1) {
|
||
return jsonify({
|
||
list: cards,
|
||
})
|
||
}
|
||
|
||
const url = appConfig.site + `/search/${text}?code=112`
|
||
const { data } = await $fetch.get(url, {
|
||
headers,
|
||
})
|
||
|
||
const $ = cheerio.load(data)
|
||
$('div.row').each((_, each) => {
|
||
const a = $(each).find('a.search-movie-title')
|
||
cards.push({
|
||
vod_id: a.attr('href'),
|
||
vod_name: a.attr('title'),
|
||
vod_pic: $(each).find('img.object-cover').attr('src'),
|
||
vod_remarks: '',
|
||
ext: {
|
||
url: appConfig.site + a.attr('href'),
|
||
},
|
||
})
|
||
})
|
||
|
||
return jsonify({
|
||
list: cards,
|
||
})
|
||
}
|