65 lines
2.9 KiB
JavaScript
65 lines
2.9 KiB
JavaScript
import './crypto-js.js'
|
|
import './uri.min.js'
|
|
|
|
/**
|
|
* 虎牙 js 本地代理
|
|
* 周星星,proxy://js_proxy?js=../js/huya.js&id=11342412
|
|
*/
|
|
|
|
function decode_live_url_info(anticode) {
|
|
const query = new Uri(`?${anticode}`)
|
|
const fm = base64Decode(query.getQueryParamValue("fm"))
|
|
return {
|
|
hash_prefix: fm.split('_')[0],
|
|
uuid: query.getQueryParamValue("uuid") || '',
|
|
ctype: query.getQueryParamValue("ctype") || '',
|
|
txyp: query.getQueryParamValue("txyp") || '',
|
|
fs: query.getQueryParamValue("fs") || '',
|
|
t: query.getQueryParamValue("t") || '',
|
|
}
|
|
}
|
|
|
|
function get_live_url_info(roomId) {
|
|
const text = http.get(`https://www.huya.com/${roomId}`, {
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36'
|
|
}
|
|
}).text()
|
|
const streamInfo = text.match(/stream: ([\s\S]*?)\n/g)?.[0] ?? text.match(/"stream": "([\s\S]*?)"/g)?.[0]
|
|
if (!streamInfo) return null
|
|
const liveData = JSON.parse(text.match(/stream: ([\s\S]*?)\n/g)?.[0].substring('stream:'.length).trim())
|
|
const live_url_infos = {}
|
|
liveData.data[0].gameStreamInfoList.forEach(streamInfo => {
|
|
let live_url_info = {}
|
|
const sCdnType = streamInfo['sCdnType']
|
|
live_url_info['stream_name'] = streamInfo['sStreamName']
|
|
live_url_info['base_url'] = streamInfo['sHlsUrl']
|
|
live_url_info['hls_url'] = `${streamInfo['sHlsUrl']}/${streamInfo['sStreamName']}.${streamInfo['sHlsUrlSuffix']}`
|
|
live_url_infos[sCdnType] = { ...live_url_info, ...decode_live_url_info(streamInfo['sHlsAntiCode']) }
|
|
})
|
|
return live_url_infos
|
|
}
|
|
|
|
function getRealUrl(roomId, userId = 1463993859134, cnd = 'AL', ratio = '') {
|
|
let urls = []
|
|
let seqid = (new Date().getTime() + userId).toString();
|
|
let wsTime = (Math.floor(Date.now() / 1000) + 3600).toString(16);
|
|
const liveUrlInfos = get_live_url_info(roomId)
|
|
if (!liveUrlInfos) return null
|
|
const liveUrlInfo = liveUrlInfos[cnd] || Object.values(liveUrlInfos)[0]
|
|
if (!liveUrlInfo) return null
|
|
let hash0 = CryptoJS.MD5(`${seqid}|${liveUrlInfo.ctype}|${liveUrlInfo.t}`)
|
|
let hash1 = CryptoJS.MD5(`${liveUrlInfo.hash_prefix}_${userId}_${liveUrlInfo.stream_name}_${hash0}_${wsTime}`)
|
|
let url = '';
|
|
if (liveUrlInfo.ctype.includes('mobile')) {
|
|
return `${liveUrlInfo.hls_url}?wsSecret=${hash1}&wsTime=${wsTime}&uuid=${liveUrlInfo.uuid}&uid=${userId}&seqid=${seqid}&ratio=${ratio}&txyp=${liveUrlInfo.txyp}&fs=${liveUrlInfo.fs}&ctype=${liveUrlInfo.ctype}&ver=1&t=${liveUrlInfo.t}`;
|
|
} else {
|
|
return `${liveUrlInfo.hls_url}?wsSecret=${hash1}&wsTime=${wsTime}&seqid=${seqid}&ctype=${liveUrlInfo.ctype}&ver=1&txyp=${liveUrlInfo.txyp}&fs=${liveUrlInfo.fs}&ratio=${ratio}&u=${userId}&t=${liveUrlInfo.t}&sv=2107230339`;
|
|
}
|
|
}
|
|
|
|
export default function huya_proxy(params) {
|
|
const url = getRealUrl(params.id)
|
|
return url ? [302, "", "", { Location: url, Status: "302 Found" }] : [404, '', '']
|
|
} |