232 lines
5.9 KiB
JavaScript
232 lines
5.9 KiB
JavaScript
import { getStringMD5 } from "./EncryUtils.js";
|
|
import { getddCalcuURL, getddCalcuURL720p } from "./ddCalcuURL.js";
|
|
import { printDebug, printGreen, printRed, printYellow } from "./colorOut.js";
|
|
import { fetchUrl } from "./net.js";
|
|
|
|
/**
|
|
* @typedef {object} SaltSign
|
|
* @property {string} salt 盐值
|
|
* @property {string} sign 签名
|
|
*/
|
|
|
|
/**
|
|
* @param {string} md5 - md5字符串
|
|
* @returns {SaltSign} -
|
|
*/
|
|
function getSaltAndSign(md5) {
|
|
|
|
const salt = 1230024
|
|
const suffix = "3ce941cc3cbc40528bfd1c64f9fdf6c0migu0123"
|
|
const sign = getStringMD5(md5 + suffix)
|
|
return {
|
|
salt: salt,
|
|
sign: sign
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {string} userId - 用户ID
|
|
* @param {string} token - 用户token
|
|
* @param {string} pid - 节目ID
|
|
* @param {number} rateType - 清晰度
|
|
* @returns {object} -
|
|
*/
|
|
async function getAndroidURL(userId, token, pid, rateType) {
|
|
|
|
if (rateType <= 1) {
|
|
return {
|
|
url: "",
|
|
rateType: 0,
|
|
content: null
|
|
}
|
|
}
|
|
// 获取url
|
|
const timestramp = Date.now()
|
|
const appVersion = "26000370"
|
|
let headers = {
|
|
AppVersion: 2600037000,
|
|
TerminalId: "android",
|
|
"X-UP-CLIENT-CHANNEL-ID": "2600037000-99000-200300220100002",
|
|
"appCode": "miguvideo_default_android"
|
|
}
|
|
|
|
// 广东卫视有些特殊
|
|
if (pid == "608831231") {
|
|
rateType = 2
|
|
}
|
|
|
|
if (rateType != 2 && userId != "" && token != "") {
|
|
headers.UserId = userId
|
|
headers.UserToken = token
|
|
}
|
|
// console.log(headers)
|
|
const str = timestramp + pid + appVersion
|
|
const md5 = getStringMD5(str)
|
|
const result = getSaltAndSign(md5)
|
|
|
|
// 请求
|
|
const baseURL = "https://play.miguvideo.com/playurl/v1/play/playurl"
|
|
let params = "?sign=" + result.sign + "&rateType=" + rateType
|
|
+ "&contId=" + pid + "×tamp=" + timestramp + "&salt=" + result.salt
|
|
+ "&flvEnable=true&super4k=true&h265N=true&4kvivid=true&2Kvivid=true&vivid=2"
|
|
let respData = await fetchUrl(baseURL + params, {
|
|
headers: headers
|
|
})
|
|
|
|
if (respData.rid == 'TIPS_NEED_MEMBER') {
|
|
printYellow("该账号没有会员 正在降低画质")
|
|
|
|
params = "?sign=" + result.sign + "&rateType=3"
|
|
+ "&contId=" + pid + "×tamp=" + timestramp + "&salt=" + result.salt
|
|
+ "&flvEnable=true&super4k=true&h265N=true&4kvivid=true&2Kvivid=true&vivid=2"
|
|
respData = await fetchUrl(baseURL + params, {
|
|
headers: headers
|
|
})
|
|
}
|
|
|
|
printDebug(respData)
|
|
// console.log(respData)
|
|
const url = respData.body.urlInfo?.url
|
|
// console.log(rateType)
|
|
// console.log(url)
|
|
if (!url) {
|
|
return {
|
|
url: "",
|
|
rateType: 0,
|
|
content: respData
|
|
}
|
|
}
|
|
pid = respData.body.content.contId
|
|
|
|
// 将URL加密
|
|
const resURL = getddCalcuURL(url, pid, "android", rateType)
|
|
|
|
rateType = respData.body.urlInfo?.rateType
|
|
// console.log("清晰度" + rateType)
|
|
return {
|
|
url: resURL,
|
|
rateType: parseInt(rateType),
|
|
content: respData
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* 旧版高清画质
|
|
* @param {string} pid - 节目ID
|
|
* @returns {object} -
|
|
*/
|
|
async function getAndroidURL720p(pid) {
|
|
// 获取url
|
|
const timestramp = Math.round(Date.now()).toString()
|
|
const appVersion = "2600034600"
|
|
const appVersionID = appVersion + "-99000-201600010010028"
|
|
let headers = {
|
|
AppVersion: `${appVersion}`,
|
|
TerminalId: "android",
|
|
"X-UP-CLIENT-CHANNEL-ID": `${appVersionID}`,
|
|
"appCode": "miguvideo_default_android"
|
|
}
|
|
// console.log(headers)
|
|
const str = timestramp + pid + appVersion.substring(0, 8)
|
|
const md5 = getStringMD5(str)
|
|
|
|
const salt = String(Math.floor(Math.random() * 1000000)).padStart(6, '0') + '25'
|
|
const suffix = "2cac4f2c6c3346a5b34e085725ef7e33migu" + salt.substring(0, 4)
|
|
const sign = getStringMD5(md5 + suffix)
|
|
|
|
let rateType = 3
|
|
// 广东卫视有些特殊
|
|
if (pid == "608831231") {
|
|
rateType = 2
|
|
}
|
|
// 请求
|
|
const baseURL = "https://play.miguvideo.com/playurl/v1/play/playurl"
|
|
const params = "?sign=" + sign + "&rateType=" + rateType
|
|
+ "&contId=" + pid + "×tamp=" + timestramp + "&salt=" + salt + "&flvEnable=true"
|
|
+ "&flvEnable=true&super4k=true&h265N=true&4kvivid=true&2Kvivid=true&vivid=2"
|
|
const respData = await fetchUrl(baseURL + params, {
|
|
headers: headers
|
|
})
|
|
|
|
printDebug(respData)
|
|
// console.dir(respData, { depth: null })
|
|
const url = respData.body.urlInfo?.url
|
|
// console.log(rateType)
|
|
// console.log(url)
|
|
if (!url) {
|
|
return {
|
|
url: "",
|
|
rateType: 0,
|
|
content: respData
|
|
}
|
|
}
|
|
|
|
rateType = respData.body.urlInfo?.rateType
|
|
pid = respData.body.content.contId
|
|
|
|
// 将URL加密
|
|
const resURL = getddCalcuURL720p(url, pid)
|
|
|
|
return {
|
|
url: resURL,
|
|
rateType: parseInt(rateType),
|
|
content: respData
|
|
}
|
|
|
|
}
|
|
|
|
async function get302URL(resObj) {
|
|
try {
|
|
let z = 1
|
|
while (z <= 6) {
|
|
if (z >= 2) {
|
|
printYellow(`获取失败,正在第${z - 1}次重试`)
|
|
}
|
|
const controller = new AbortController()
|
|
const timeoutId = setTimeout(() => {
|
|
controller.abort()
|
|
printRed("请求超时")
|
|
}, 6000);
|
|
const obj = await fetch(`${resObj.url}`, {
|
|
method: "GET",
|
|
redirect: "manual",
|
|
signal: controller.signal
|
|
}).catch(err => {
|
|
clearTimeout(timeoutId);
|
|
console.log(err)
|
|
})
|
|
clearTimeout(timeoutId);
|
|
const location = obj.headers.get("Location")
|
|
|
|
if (location != "" && location != undefined && location != null) {
|
|
if (!location.startsWith("http://bofang")) {
|
|
return location
|
|
}
|
|
}
|
|
if (z != 6) {
|
|
await delay(150)
|
|
}
|
|
z++
|
|
}
|
|
} catch (error) {
|
|
console.log(error)
|
|
}
|
|
printRed(`获取失败,返回原链接`)
|
|
return ""
|
|
}
|
|
|
|
function printLoginInfo(resObj) {
|
|
if (resObj.content.body?.auth?.logined) {
|
|
printGreen("登录认证成功")
|
|
if (resObj.content.body.auth.authResult == "FAIL") {
|
|
printRed(`认证失败 视频内容不完整 可能缺少相关VIP: ${resObj.content.body.auth.resultDesc}`)
|
|
}
|
|
} else {
|
|
printYellow("未登录")
|
|
}
|
|
}
|
|
|
|
export { getAndroidURL, getAndroidURL720p, get302URL, printLoginInfo }
|