mirror of
https://github.com/develop202/migu_video.git
synced 2025-12-24 02:35:09 +08:00
添加体育
This commit is contained in:
@@ -1,12 +1,15 @@
|
||||
import crypto from 'crypto'
|
||||
import CryptoJS from 'crypto-js';
|
||||
|
||||
const KEY_AES = "MQDUjI19MGe3BhaqTlpc9g==";
|
||||
const IV = "abcdefghijklmnop";
|
||||
|
||||
const RSA_PRIVATE_KEY_PKCS8 = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOhvWsrglBpQGpjB\r8okxLUCaaiKKOytn9EtvytB5tKDchmgkSaXpreWcDy/9imsuOiVCSdBr6hHjrTN7\rQKkA4/QYS8ptiFv1ap61PiAyRFDI1b8wp2haJ6HF1rDShG2XdfWIhLk4Hj6efVZA\rSfa3taM7C8NseWoWh05Cp26g4hXZAgMBAAECgYBzqZXghsisH1hc04ZBRrth/nT6\rIxc2jlA+ia6+9xEvSw2HHSeY7COgsnvMQbpzg1lj2QyqLkkYBdfWWmrerpa/mb7j\rm6w95YKs5Ndii8NhFWvC0eGK8Ygt02DeLohmkQu3B+Yq8JszjB7tQJRR2kdG6cPt\rKp99ZTyyPom/9uD+AQJBAPxCwajHAkCuH4+aKdZhH6n7oDAxZoMH/mihDRxHZJof\rnT+K662QCCIx0kVCl64s/wZ4YMYbP8/PWDvLMNNWC7ECQQDr4V23KRT9fAPAN8vB\rq2NqjLAmEx+tVnd4maJ16Xjy5Q4PSRiAXYLSr9uGtneSPP2fd/tja0IyawlP5UPL\rl76pAkAeXqMWAK+CvfPKxBKZXqQDQOnuI2RmDgZQ7mK3rtirvXae+ciZ4qc4Bqt7\r7yJ3s68YRlHQR+OMzzeeKz47kzZhAkAPteH1ChJw06q4Sb8TdiPX++jbkFiCxgiN\rCsaMTfGVU/Y8xGSSYCgPelEHxu1t2wwVa/tdYs505zYmkSGT1NaJAkBCS5hymXsA\rB92Fx8eGW5WpLfnpvxl8nOcP+eNXobi8Sc6q1FmoHi8snbcmBhidcDdcieKn+DbX\rGG3BQE/OCOkM\r";
|
||||
|
||||
// MD5标准加密
|
||||
/**
|
||||
* MD5 加密
|
||||
* @param {string} str -
|
||||
* @returns {string} -
|
||||
*/
|
||||
function getStringMD5(str) {
|
||||
// 创建 MD5 哈希对象
|
||||
const md5 = crypto.createHash("md5");
|
||||
@@ -17,100 +20,98 @@ function getStringMD5(str) {
|
||||
}
|
||||
|
||||
/**
|
||||
* base64加密
|
||||
* base64 加密
|
||||
* @param {string} str -
|
||||
* @returns {string} -
|
||||
*/
|
||||
function Base64encrypt(str) {
|
||||
// create a buffer
|
||||
const buff = Buffer.from(str, 'utf-8');
|
||||
// encode buffer as Base64
|
||||
return buff.toString('base64')
|
||||
}
|
||||
|
||||
/**
|
||||
* base64解密
|
||||
* base64 解密
|
||||
* @param {string} str -
|
||||
* @returns {string} -
|
||||
*/
|
||||
function Base64decrypt(str) {
|
||||
// create a buffer
|
||||
const buff = Buffer.from(str, 'base64');
|
||||
// encode buffer as Base64
|
||||
return buff.toString('utf-8')
|
||||
}
|
||||
|
||||
// AES 解密方法
|
||||
function AESdecrypt(encryptedText, base64Key) {
|
||||
// 解码 Base64 密钥和密文
|
||||
const keyBytes = CryptoJS.enc.Base64.parse(base64Key);
|
||||
const encryptedBytes = CryptoJS.enc.Base64.parse(encryptedText);
|
||||
/**
|
||||
* AES 加密
|
||||
* @param {string} data -
|
||||
* @param {string} baseKey -
|
||||
* @param {string} ivStr -
|
||||
* @returns {string} -
|
||||
*/
|
||||
function AESencrypt(data, baseKey = KEY_AES, ivStr = IV) {
|
||||
let key = Buffer.from(baseKey, "utf8")
|
||||
let iv = Buffer.from(ivStr, "utf8")
|
||||
|
||||
// 处理 IV
|
||||
const iv = CryptoJS.enc.Utf8.parse(IV);
|
||||
|
||||
// 配置解密参数
|
||||
const decryptOptions = {
|
||||
iv: iv,
|
||||
mode: CryptoJS.mode.CBC,
|
||||
padding: CryptoJS.pad.Pkcs7
|
||||
};
|
||||
|
||||
// 执行 AES 解密
|
||||
const decrypted = CryptoJS.AES.decrypt(
|
||||
{ ciphertext: encryptedBytes },
|
||||
keyBytes,
|
||||
decryptOptions
|
||||
);
|
||||
|
||||
// 将解密结果转为 UTF-8 字符串
|
||||
return decrypted.toString(CryptoJS.enc.Utf8);
|
||||
}
|
||||
|
||||
// AES 加密方法
|
||||
function AESencrypt(str, base64Key) {
|
||||
// 解码 Base64 密钥
|
||||
const keyBytes = CryptoJS.enc.Base64.parse(base64Key);
|
||||
|
||||
// 处理 IV 和明文
|
||||
const iv = CryptoJS.enc.Utf8.parse(IV);
|
||||
const plainBytes = CryptoJS.enc.Utf8.parse(str);
|
||||
|
||||
// 配置加密参数
|
||||
const encryptOptions = {
|
||||
iv: iv,
|
||||
mode: CryptoJS.mode.CBC,
|
||||
padding: CryptoJS.pad.Pkcs7
|
||||
};
|
||||
|
||||
// 执行 AES 加密
|
||||
const encrypted = CryptoJS.AES.encrypt(
|
||||
plainBytes,
|
||||
keyBytes,
|
||||
encryptOptions
|
||||
);
|
||||
|
||||
// 返回 Base64 编码的密文
|
||||
return encrypted.ciphertext.toString(CryptoJS.enc.Base64);
|
||||
// 填充长度
|
||||
if (key.length < 32) {
|
||||
const paddedKey = Buffer.alloc(32);
|
||||
key.copy(paddedKey);
|
||||
key = paddedKey;
|
||||
}
|
||||
if (iv.length < 16) {
|
||||
const paddedIV = Buffer.alloc(16);
|
||||
iv.copy(paddedIV);
|
||||
iv = paddedIV;
|
||||
} const cipher = crypto.createCipheriv("aes-256-cbc", key, iv)
|
||||
const dest = cipher.update(data, "utf8", "base64") + cipher.final("base64")
|
||||
return dest.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
*RSA 加密
|
||||
* AES 解密
|
||||
* @param {string} baseData -
|
||||
* @param {string} baseKey -
|
||||
* @param {string} ivStr -
|
||||
* @returns {string} -
|
||||
*/
|
||||
function RSAencrypt(str) {
|
||||
// 处理密钥:移除 \r 并解码 Base64
|
||||
const keyBytes = Buffer.from(RSA_PRIVATE_KEY_PKCS8.replace(/\r/g, ''), 'base64');
|
||||
function AESdecrypt(baseData, baseKey = KEY_AES, ivStr = IV) {
|
||||
let key = Buffer.from(baseKey, "utf8")
|
||||
let iv = Buffer.from(ivStr, "utf8")
|
||||
|
||||
// 创建私钥对象
|
||||
const privateKey = crypto.createPrivateKey({
|
||||
key: keyBytes,
|
||||
format: 'der',
|
||||
type: 'pkcs8'
|
||||
});
|
||||
|
||||
// 使用私钥加密
|
||||
const encrypted = crypto.privateEncrypt(
|
||||
{ key: privateKey, padding: crypto.constants.RSA_PKCS1_PADDING },
|
||||
Buffer.from(str)
|
||||
);
|
||||
|
||||
return encrypted.toString('base64');
|
||||
// 填充长度
|
||||
if (key.length < 32) {
|
||||
const paddedKey = Buffer.alloc(32);
|
||||
key.copy(paddedKey);
|
||||
key = paddedKey;
|
||||
} if (iv.length < 16) {
|
||||
const paddedIV = Buffer.alloc(16);
|
||||
iv.copy(paddedIV);
|
||||
iv = paddedIV;
|
||||
}
|
||||
const data = Buffer.from(baseData, "utf8")
|
||||
const decipher = crypto.createDecipheriv("aes-256-cbc", key, iv)
|
||||
const dest = Buffer.concat([decipher.update(data), decipher.final()])
|
||||
return dest.toString()
|
||||
}
|
||||
|
||||
export { getStringMD5, KEY_AES, AESdecrypt, AESencrypt, Base64decrypt, Base64encrypt, RSAencrypt }
|
||||
|
||||
/**
|
||||
* RSA 私钥签名加密
|
||||
* @param {string} data -
|
||||
* @param {string} publicKeyBase -
|
||||
* @returns {string} -
|
||||
*/
|
||||
function RSAencrypt(data, publicKeyBase = RSA_PRIVATE_KEY_PKCS8) {
|
||||
const clearKey = publicKeyBase.replace(/\r/g, "")
|
||||
const keyBytes = Buffer.from(clearKey, "base64")
|
||||
const privateKey = crypto.createPrivateKey({
|
||||
key: keyBytes,
|
||||
format: "der",
|
||||
type: "pkcs8"
|
||||
})
|
||||
const dest = crypto.privateEncrypt({
|
||||
key: privateKey,
|
||||
padding: crypto.constants.RSA_PKCS1_PADDING,
|
||||
}, data)
|
||||
return dest.toString("base64")
|
||||
}
|
||||
|
||||
export { getStringMD5, AESdecrypt, AESencrypt, Base64decrypt, Base64encrypt, RSAencrypt }
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
import axios from "axios";
|
||||
import { getStringMD5 } from "./EncryUtils.js";
|
||||
import { getddCalcuURL, getddCalcuURL720p, getEncryptURL } from "./ddCalcuURL.js";
|
||||
import { changedDdCalcu } from "./datas.js";
|
||||
import { getddCalcuURL, getddCalcuURL720p } from "./ddCalcuURL.js";
|
||||
import { printYellow } from "./colorOut.js";
|
||||
|
||||
/**
|
||||
* @typedef {object} SaltSign
|
||||
* @property {string} salt 盐值
|
||||
* @property {string} sign 签名
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {string} md5 - md5字符串
|
||||
* @returns {SaltSign} -
|
||||
*/
|
||||
function getSaltAndSign(md5) {
|
||||
|
||||
const salt = 1230024
|
||||
@@ -15,134 +23,20 @@ function getSaltAndSign(md5) {
|
||||
}
|
||||
}
|
||||
|
||||
function replaceChars(url, pid, rateType) {
|
||||
|
||||
// 参数为空或者不符条件
|
||||
if (!url || rateType <= 1 || rateType >= 5 || !pid) {
|
||||
return ""
|
||||
}
|
||||
const spl = url.split("&ddCalcu=")
|
||||
const prefix = spl[0]
|
||||
let suffix = spl[1]
|
||||
|
||||
suffix = suffix.replace("sv=10000&ct=www", "sv=10004&ct=android")
|
||||
// 默认替换方式
|
||||
let defaultChange = ["x", "a", "y", "a"]
|
||||
let index = [5, 8, 11, 14]
|
||||
// 一些标清不需要改
|
||||
let noChangeStandard = false
|
||||
|
||||
// 替换自定义替换方式
|
||||
if (changedDdCalcu[pid] != undefined) {
|
||||
noChangeStandard = changedDdCalcu[pid].noChangeStandard
|
||||
if (changedDdCalcu[pid]["all"] != undefined) {
|
||||
defaultChange = changedDdCalcu[pid]["all"].data
|
||||
index = changedDdCalcu[pid]["all"].index
|
||||
}
|
||||
if (changedDdCalcu[pid][rateType]) {
|
||||
// 若相邻两个重复可以写另一个的rateType
|
||||
if (!isNaN(changedDdCalcu[pid][rateType])) {
|
||||
const rate = changedDdCalcu[pid][rateType]
|
||||
defaultChange = changedDdCalcu[pid][rate].data
|
||||
index = changedDdCalcu[pid][rate].index
|
||||
} else {
|
||||
defaultChange = changedDdCalcu[pid][rateType].data
|
||||
index = changedDdCalcu[pid][rateType].index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 一些标清需要改
|
||||
if (rateType == 2 && !noChangeStandard) {
|
||||
defaultChange[0] = "v"
|
||||
}
|
||||
|
||||
// 替换
|
||||
for (let i = 0; i < index.length; i++) {
|
||||
suffix[index[i] - 1] = defaultChange[i]
|
||||
}
|
||||
|
||||
return `${prefix}&ddCalcu=${suffix}`
|
||||
}
|
||||
|
||||
async function getAndroidVideoURL(userId, token, exports, pid, rateType) {
|
||||
if (rateType <= 1) {
|
||||
return {
|
||||
url: "",
|
||||
rateType: 0
|
||||
}
|
||||
}
|
||||
if (!exports) {
|
||||
return {
|
||||
url: "",
|
||||
rateType: 0
|
||||
}
|
||||
}
|
||||
// 获取url
|
||||
const timestramp = Date.now()
|
||||
const appVersion = "26000370"
|
||||
let headers = {
|
||||
AppVersion: 2600037000,
|
||||
TerminalId: "android",
|
||||
"X-UP-CLIENT-CHANNEL-ID": "2600037000-99000-200300220100002"
|
||||
}
|
||||
if (rateType != 2) {
|
||||
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"
|
||||
const params = "?sign=" + result.sign + "&rateType=" + rateType
|
||||
+ "&contId=" + pid + "×tamp=" + timestramp + "&salt=" + result.salt
|
||||
const respData = await axios.get(baseURL + params, {
|
||||
headers: headers
|
||||
}).then(r => r.data)
|
||||
|
||||
// console.log(respData)
|
||||
const url = respData.body.urlInfo?.url
|
||||
// console.log(rateType)
|
||||
// console.log(url)
|
||||
if (!url) {
|
||||
return {
|
||||
url: "",
|
||||
rateType: 0
|
||||
}
|
||||
}
|
||||
rateType = parseInt(respData.body.urlInfo?.rateType)
|
||||
|
||||
// 将URL加密
|
||||
const encryURL = getEncryptURL(exports, url)
|
||||
// console.log("加密后:" + encryURL)
|
||||
// 替换字符,拼接结果
|
||||
const resURL = replaceChars(encryURL, pid, rateType)
|
||||
// console.log("app替换后的链接:" + resURL)
|
||||
// console.log("播放画质:" + rateType)
|
||||
return {
|
||||
url: resURL,
|
||||
rateType: rateType
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} userId - 用户ID
|
||||
* @param {string} token - 用户token
|
||||
* @param {string} pid - 节目ID
|
||||
* @param {number} rateType - 清晰度
|
||||
* @returns {} - url: 链接 rateType: 清晰度
|
||||
* @returns {object} -
|
||||
*/
|
||||
async function getAndroidURL(userId, token, pid, rateType) {
|
||||
|
||||
if (rateType <= 1) {
|
||||
return {
|
||||
url: "",
|
||||
rateType: 0
|
||||
rateType: 0,
|
||||
content: null
|
||||
}
|
||||
}
|
||||
// 获取url
|
||||
@@ -172,18 +66,18 @@ async function getAndroidURL(userId, token, pid, rateType) {
|
||||
const baseURL = "https://play.miguvideo.com/playurl/v1/play/playurl"
|
||||
let params = "?sign=" + result.sign + "&rateType=" + rateType
|
||||
+ "&contId=" + pid + "×tamp=" + timestramp + "&salt=" + result.salt
|
||||
let respData = await axios.get(baseURL + params, {
|
||||
let respData = await fetch(baseURL + params, {
|
||||
headers: headers
|
||||
}).then(r => r.data)
|
||||
}).then(r => r.json())
|
||||
|
||||
if (respData.rid == 'TIPS_NEED_MEMBER') {
|
||||
printYellow("该账号没有会员 正在降低画质")
|
||||
|
||||
params = "?sign=" + result.sign + "&rateType=" + (rateType - 1)
|
||||
+ "&contId=" + pid + "×tamp=" + timestramp + "&salt=" + result.salt
|
||||
respData = await axios.get(baseURL + params, {
|
||||
respData = await fetch(baseURL + params, {
|
||||
headers: headers
|
||||
}).then(r => r.data)
|
||||
}).then(r => r.json())
|
||||
}
|
||||
|
||||
// console.dir(respData, { depth: null })
|
||||
@@ -194,7 +88,8 @@ async function getAndroidURL(userId, token, pid, rateType) {
|
||||
if (!url) {
|
||||
return {
|
||||
url: "",
|
||||
rateType: 0
|
||||
rateType: 0,
|
||||
content: respData
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,13 +111,13 @@ async function getAndroidURL(userId, token, pid, rateType) {
|
||||
/**
|
||||
* 旧版高清画质
|
||||
* @param {string} pid - 节目ID
|
||||
* @returns {} - url: 链接 rateType: 清晰度
|
||||
* @returns {object} -
|
||||
*/
|
||||
async function getAndroidURL720p(pid) {
|
||||
// 获取url
|
||||
const timestramp = Math.round(Date.now()).toString()
|
||||
const appVersion = "2600033500"
|
||||
const appVersionID = appVersion + "-99000-201600010010027"
|
||||
const appVersion = "2600034600"
|
||||
const appVersionID = appVersion + "-99000-201600010010028"
|
||||
let headers = {
|
||||
AppVersion: `${appVersion}`,
|
||||
TerminalId: "android",
|
||||
@@ -232,8 +127,8 @@ async function getAndroidURL720p(pid) {
|
||||
const str = timestramp + pid + appVersion.substring(0, 8)
|
||||
const md5 = getStringMD5(str)
|
||||
|
||||
const salt = String( Math.floor(Math.random() * 1000000) ).padStart(6, '0') + '80'
|
||||
const suffix = "16d4328df21a4138859388418bd252c2migu" + salt.substring(0, 4)
|
||||
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
|
||||
@@ -245,18 +140,19 @@ async function getAndroidURL720p(pid) {
|
||||
const baseURL = "https://play.miguvideo.com/playurl/v1/play/playurl"
|
||||
const params = "?sign=" + sign + "&rateType=" + rateType
|
||||
+ "&contId=" + pid + "×tamp=" + timestramp + "&salt=" + salt
|
||||
const respData = await axios.get(baseURL + params, {
|
||||
const respData = await fetch(baseURL + params, {
|
||||
headers: headers
|
||||
}).then(r => r.data)
|
||||
}).then(r => r.json())
|
||||
|
||||
// console.log(respData)
|
||||
// console.dir(respData, { depth: null })
|
||||
const url = respData.body.urlInfo?.url
|
||||
// console.log(rateType)
|
||||
// console.log(url)
|
||||
if (!url) {
|
||||
return {
|
||||
url: "",
|
||||
rateType: 0
|
||||
rateType: 0,
|
||||
content: respData
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,4 +169,4 @@ async function getAndroidURL720p(pid) {
|
||||
|
||||
}
|
||||
|
||||
export { getAndroidVideoURL, getAndroidURL, getAndroidURL720p }
|
||||
export { getAndroidURL, getAndroidURL720p }
|
||||
|
||||
@@ -17,7 +17,7 @@ function printYellow(msg) {
|
||||
}
|
||||
|
||||
function printBlue(msg) {
|
||||
basePrint("\x1B[33m", msg)
|
||||
basePrint("\x1B[34m", msg)
|
||||
}
|
||||
|
||||
function printMagenta(msg) {
|
||||
|
||||
828
utils/datas.js
828
utils/datas.js
@@ -21,830 +21,4 @@ const cntvNames = {
|
||||
"CCTV4美洲": "cctvamerica",
|
||||
}
|
||||
|
||||
|
||||
// 频道信息
|
||||
const channelName = [
|
||||
{
|
||||
cateName: "央视",
|
||||
data: [
|
||||
{ name: "CCTV1综合", pid: "608807420", },
|
||||
{ name: "CCTV2财经", pid: "631780532", },
|
||||
{ name: "CCTV3综艺", pid: "624878271", },
|
||||
{ name: "CCTV4中文国际", pid: "631780421", },
|
||||
{ name: "CCTV5体育", pid: "641886683", },
|
||||
{ name: "CCTV5+体育赛事", pid: "641886773", },
|
||||
{ name: "CCTV6电影", pid: "624878396", },
|
||||
{ name: "CCTV7国防军事", pid: "673168121", },
|
||||
{ name: "CCTV8电视剧", pid: "624878356", },
|
||||
{ name: "CCTV9纪录", pid: "673168140", },
|
||||
{ name: "CCTV10科教", pid: "624878405", },
|
||||
{ name: "CCTV11戏曲", pid: "667987558", },
|
||||
{ name: "CCTV12社会与法", pid: "673168185", },
|
||||
{ name: "CCTV13新闻", pid: "608807423", },
|
||||
{ name: "CCTV14少儿", pid: "624878440", },
|
||||
{ name: "CCTV15音乐", pid: "673168223", },
|
||||
{ name: "CCTV17农业农村", pid: "673168256", },
|
||||
{ name: "CCTV4欧洲", pid: "608807419", },
|
||||
{ name: "CCTV4美洲", pid: "608807416", },
|
||||
{ name: "CGTN外语记录", pid: "609006487", },
|
||||
{ name: "CGTN阿拉伯语", pid: "609154345", },
|
||||
{ name: "CGTN西班牙语", pid: "609006450", },
|
||||
{ name: "CGTN法语", pid: "609006476", },
|
||||
{ name: "CGTN俄语", pid: "609006446", },
|
||||
{ name: "老故事", pid: "884121956", },
|
||||
{ name: "发现之旅", pid: "624878970", },
|
||||
{ name: "中学生", pid: "708869532", },
|
||||
{ name: "CGTN", pid: "609017205", },
|
||||
]
|
||||
},
|
||||
{
|
||||
cateName: "卫视",
|
||||
data: [
|
||||
{ name: "东方卫视", pid: "651632648", },
|
||||
{ name: "江苏卫视", pid: "623899368", },
|
||||
{ name: "广东卫视", pid: "608831231", },
|
||||
{ name: "江西卫视", pid: "783847495", },
|
||||
{ name: "河南卫视", pid: "790187291", },
|
||||
{ name: "陕西卫视", pid: "738910838", },
|
||||
{ name: "大湾区卫视", pid: "608917627", },
|
||||
{ name: "湖北卫视", pid: "947472496", },
|
||||
{ name: "吉林卫视", pid: "947472500", },
|
||||
{ name: "青海卫视", pid: "947472506", },
|
||||
{ name: "东南卫视", pid: "849116810", },
|
||||
{ name: "海南卫视", pid: "947472502", },
|
||||
{ name: "海峡卫视", pid: "849119120", },]
|
||||
},
|
||||
{
|
||||
cateName: "地方",
|
||||
data: [
|
||||
{ name: "上海新闻综合", pid: "651632657", },
|
||||
{ name: "上视东方影视", pid: "617290047", },
|
||||
{ name: "上海第一财经", pid: "608780988", },
|
||||
{ name: "南京新闻综合频道", pid: "838109047", },
|
||||
{ name: "南京教科频道", pid: "838153729", },
|
||||
{ name: "南京十八频道", pid: "838151753", },
|
||||
{ name: "体育休闲频道", pid: "626064707", },
|
||||
{ name: "江苏城市频道", pid: "626064714", },
|
||||
{ name: "江苏国际", pid: "626064674", },
|
||||
{ name: "江苏教育", pid: "628008321", },
|
||||
{ name: "江苏影视频道", pid: "626064697", },
|
||||
{ name: "江苏综艺频道", pid: "626065193", },
|
||||
{ name: "公共新闻频道", pid: "626064693", },
|
||||
{ name: "淮安新闻综合", pid: "639731826", },
|
||||
{ name: "泰州新闻综合", pid: "639731818", },
|
||||
{ name: "连云港新闻综合", pid: "639731715", },
|
||||
{ name: "宿迁新闻综合", pid: "639731832", },
|
||||
{ name: "徐州新闻综合", pid: "639731747", },
|
||||
{ name: "优漫卡通频道", pid: "626064703", },
|
||||
],
|
||||
},
|
||||
{
|
||||
cateName: "影视",
|
||||
data: [
|
||||
{ name: "中国航天“逆袭”之路", pid: "617432318", },
|
||||
{ name: "新片放映厅", pid: "619495952", },
|
||||
{ name: "CHC影迷电影", pid: "952383261", },
|
||||
{ name: "CHC动作电影", pid: "644368714", },
|
||||
{ name: "CHC家庭影院", pid: "644368373", },
|
||||
{ name: "和美乡途轮播台", pid: "713591450", },
|
||||
{ name: "高清大片", pid: "629943678", },
|
||||
{ name: "南方影视", pid: "614961829", },
|
||||
{ name: "红色轮播台", pid: "713600957", },
|
||||
{ name: "华语乐坛最强音", pid: "707671890", },
|
||||
{ name: "周杰伦现场", pid: "625133682", },
|
||||
{ name: "最强综艺趴", pid: "629942228", },
|
||||
{ name: "嘉佳卡通", pid: "614952364", },
|
||||
{ name: "经典动画大集合", pid: "629942219", },
|
||||
{ name: "深度对话", pid: "625703337", },
|
||||
{ name: "CETV1", pid: "923287154", },
|
||||
{ name: "CETV2", pid: "923287211", },
|
||||
{ name: "CETV4", pid: "923287339", },
|
||||
{ name: "新动解码在一线", pid: "713589837", },
|
||||
],
|
||||
},
|
||||
{
|
||||
cateName: "体育",
|
||||
data: [
|
||||
{ name: "赛事最经典", pid: "646596895", },
|
||||
{ name: "掼蛋精英赛", pid: "631354620", },
|
||||
{ name: "体坛名栏汇", pid: "629943305", },
|
||||
{ name: "咪咕24小时体育台", pid: "654102378", },
|
||||
]
|
||||
},
|
||||
{
|
||||
cateName: "熊猫",
|
||||
data: [
|
||||
{ name: "熊猫频道1", pid: "608933610", },
|
||||
{ name: "熊猫频道2", pid: "608933640", },
|
||||
{ name: "熊猫频道3", pid: "608934619", },
|
||||
{ name: "熊猫频道4", pid: "608934721", },
|
||||
{ name: "熊猫频道5", pid: "608935104", },
|
||||
{ name: "熊猫频道6", pid: "608935797", },
|
||||
{ name: "熊猫频道7", pid: "609169286", },
|
||||
{ name: "熊猫频道8", pid: "609169287", },
|
||||
{ name: "熊猫频道9", pid: "609169226", },
|
||||
{ name: "熊猫频道10", pid: "609169285", },
|
||||
]
|
||||
},
|
||||
]
|
||||
|
||||
// 加密字符串替换规则
|
||||
// index 替换字符串位置,从1开始
|
||||
// data 与index一一对应,修改字符为
|
||||
// noChangeStandard 标清下第一个字符是否不需要修改
|
||||
const changedDdCalcu = {
|
||||
// 分类:央视 频道名:CCTV1综合
|
||||
// "608807420": {
|
||||
// "all": {
|
||||
// index: [5, 8, 11, 14],
|
||||
// data: ["x", "a", "a", "a"]
|
||||
// },
|
||||
// },
|
||||
// 分类:央视 频道名:CCTV2财经
|
||||
"631780532": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "z", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:央视 频道名:CCTV3综艺
|
||||
"624878271": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "a", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:央视 频道名:CCTV4中文国际
|
||||
"631780421": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "y", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:央视 频道名:CCTV5体育
|
||||
"641886683": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "w", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:央视 频道名:CCTV5+体育赛事
|
||||
"641886773": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "x", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:央视 频道名:CCTV6电影
|
||||
"624878396": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "b", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:央视 频道名:CCTV7国防军事
|
||||
"673168121": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "d", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:央视 频道名:CCTV8电视剧
|
||||
"624878356": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "b", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:央视 频道名:CCTV9纪录
|
||||
"673168140": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "d", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:央视 频道名:CCTV10科教
|
||||
"624878405": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "y", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:央视 频道名:CCTV11戏曲
|
||||
"667987558": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "z", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:央视 频道名:CCTV12社会与法
|
||||
"673168185": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "d", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:央视 频道名:CCTV13新闻
|
||||
"608807423": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "y", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:央视 频道名:CCTV14少儿
|
||||
"624878440": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "y", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:央视 频道名:CCTV15音乐
|
||||
"673168223": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "a", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:央视 频道名:CCTV17农业农村
|
||||
"673168256": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "a", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:央视 频道名:CCTV4欧洲
|
||||
"608807419": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "y", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:央视 频道名:CCTV4美洲
|
||||
"608807416": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "y", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:央视 频道名:CGTN外语记录
|
||||
"609006487": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "y", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:央视 频道名:CGTN阿拉伯语
|
||||
"609154345": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "b", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:央视 频道名:CGTN西班牙语
|
||||
"609006450": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "y", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:央视 频道名:CGTN法语
|
||||
"609006476": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "y", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:央视 频道名:CGTN俄语
|
||||
"609006446": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "y", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:央视 频道名:老故事
|
||||
"884121956": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "l", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:央视 频道名:发现之旅
|
||||
"624878970": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "l", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:央视 频道名:中学生
|
||||
"708869532": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "z", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:央视 频道名:CGTN
|
||||
"609017205": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "a", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:卫视 频道名:东方卫视
|
||||
"651632648": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "w", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:卫视 频道名:江苏卫视
|
||||
"623899368": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "b", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:卫视 频道名:广东卫视
|
||||
"608831231": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "a", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:卫视 频道名:江西卫视
|
||||
"783847495": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "y", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:卫视 频道名:河南卫视
|
||||
"790187291": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "a", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:卫视 频道名:陕西卫视
|
||||
"738910838": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "k", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:卫视 频道名:大湾区卫视
|
||||
"608917627": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "w", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:卫视 频道名:湖北卫视
|
||||
"947472496": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "y", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:卫视 频道名:吉林卫视
|
||||
"947472500": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "z", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:卫视 频道名:青海卫视
|
||||
"947472506": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "z", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:卫视 频道名:东南卫视
|
||||
"849116810": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "k", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:卫视 频道名:海南卫视
|
||||
"947472502": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "z", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:卫视 频道名:海峡卫视
|
||||
"849119120": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "d", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:地方 频道名:上海新闻综合
|
||||
"651632657": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "w", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:地方 频道名:上视东方影视
|
||||
"617290047": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "c", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:地方 频道名:上海第一财经
|
||||
"608780988": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "l", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:地方 频道名:南京新闻综合频道
|
||||
"838109047": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "c", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:地方 频道名:南京教科频道
|
||||
"838153729": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "x", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:地方 频道名:南京十八频道
|
||||
"838151753": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "x", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:地方 频道名:体育休闲频道
|
||||
"626064707": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "x", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:地方 频道名:江苏城市频道
|
||||
"626064714": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "x", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:地方 频道名:江苏国际
|
||||
"626064674": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "w", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:地方 频道名:江苏教育
|
||||
"628008321": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "b", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:地方 频道名:江苏影视频道
|
||||
"626064697": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "w", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:地方 频道名:江苏综艺频道
|
||||
"626065193": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "d", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:地方 频道名:公共新闻频道
|
||||
"626064693": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "w", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:地方 频道名:淮安新闻综合
|
||||
"639731826": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "k", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:地方 频道名:泰州新闻综合
|
||||
"639731818": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "k", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:地方 频道名:连云港新闻综合
|
||||
"639731715": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "x", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:地方 频道名:宿迁新闻综合
|
||||
"639731832": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "k", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:地方 频道名:徐州新闻综合
|
||||
"639731747": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "x", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:地方 频道名:优漫卡通频道
|
||||
"626064703": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "x", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:影视 频道名:中国航天“逆袭”之路
|
||||
"617432318": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "b", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:影视 频道名:新片放映厅
|
||||
"619495952": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "l", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:影视 频道名:CHC影迷电影
|
||||
"952383261": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "a", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:影视 频道名:CHC动作电影
|
||||
"644368714": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "x", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:影视 频道名:CHC家庭影院
|
||||
"644368373": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "b", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:影视 频道名:和美乡途轮播台
|
||||
"713591450": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "y", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:影视 频道名:高清大片
|
||||
"629943678": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "w", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:影视 频道名:南方影视
|
||||
"614961829": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "k", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:影视 频道名:红色轮播台
|
||||
"713600957": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "l", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:影视 频道名:华语乐坛最强音
|
||||
"707671890": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "k", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:影视 频道名:周杰伦现场
|
||||
"625133682": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "w", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:影视 频道名:最强综艺趴
|
||||
"629942228": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "a", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:影视 频道名:嘉佳卡通
|
||||
"614952364": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "b", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:影视 频道名:经典动画大集合
|
||||
"629942219": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "a", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:影视 频道名:深度对话
|
||||
"625703337": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "b", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:影视 频道名:CETV1
|
||||
"923287154": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "d", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:影视 频道名:CETV2
|
||||
"923287211": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "a", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:影视 频道名:CETV4
|
||||
"923287339": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "b", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:影视 频道名:新动解码在一线
|
||||
"713589837": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "k", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:体育 频道名:赛事最经典
|
||||
"646596895": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "k", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:体育 频道名:掼蛋精英赛
|
||||
"631354620": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "w", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:体育 频道名:体坛名栏汇
|
||||
"629943305": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "b", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:体育 频道名:咪咕24小时体育台
|
||||
"654102378": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "b", "a"]
|
||||
},
|
||||
},
|
||||
// 分类:熊猫 频道名:熊猫频道1
|
||||
"608933610": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "w", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:熊猫 频道名:熊猫频道2
|
||||
"608933640": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "w", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:熊猫 频道名:熊猫频道3
|
||||
"608934619": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "w", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:熊猫 频道名:熊猫频道4
|
||||
"608934721": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "x", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:熊猫 频道名:熊猫频道5
|
||||
"608935104": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "d", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:熊猫 频道名:熊猫频道6
|
||||
"608935797": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "x", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:熊猫 频道名:熊猫频道7
|
||||
"609169286": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "a", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:熊猫 频道名:熊猫频道8
|
||||
"609169287": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "a", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:熊猫 频道名:熊猫频道9
|
||||
"609169226": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "a", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
// 分类:熊猫 频道名:熊猫频道10
|
||||
"609169285": {
|
||||
"all": {
|
||||
index: [5, 8, 11, 14],
|
||||
data: ["x", "a", "a", "a"]
|
||||
},
|
||||
noChangeStandard: true,
|
||||
},
|
||||
}
|
||||
|
||||
export { changedDdCalcu, channelName, cntvNames }
|
||||
export { cntvNames }
|
||||
|
||||
@@ -98,14 +98,6 @@ function getEncryptURL(exports, videoURL) {
|
||||
/**
|
||||
* h5端现已失效
|
||||
* 获取ddCalcu
|
||||
* 大致思路:把puData最后一个字符和第一个字符拼接,然后拼接倒数第二个跟第二个,一直循环,
|
||||
* 当第1 2 3 4次(从0开始)循环时需要插入特殊标识字符
|
||||
* 特殊字符:
|
||||
* 都是根据一些数字字符串的某一位的值对应某数组的值确定的,形如数组[数字字符串[第几位]],具体根据第几位每个版本都不一样
|
||||
* 第1次是根据userid确定的,未登录时为固定字母
|
||||
* 第2位是根据时间戳确定(需要yyyyMMddhhmmss格式)
|
||||
* 第3根据节目id
|
||||
* 第4是根据平台确定的
|
||||
* @param {string} puData - 服务器返回的那个东东
|
||||
* @param {string} programId - 节目ID
|
||||
* @param {string} clientType - 平台类型 h5 android
|
||||
@@ -130,7 +122,6 @@ function getddCalcu(puData, programId, clientType, rateType) {
|
||||
return ""
|
||||
}
|
||||
|
||||
// words第1位是根据userId的第7位(从0开始)数字对应keys里的字母生成的
|
||||
// 不登录标清是默认v
|
||||
const id = userId ? userId : process.env.USERID
|
||||
if (id) {
|
||||
@@ -219,8 +210,7 @@ function getddCalcu720p(puData, programId) {
|
||||
if (programId == null || programId == undefined) {
|
||||
return ""
|
||||
}
|
||||
|
||||
const keys = "0123456789"
|
||||
const keys = "cdabyzwxkl"
|
||||
|
||||
let ddCalcu = []
|
||||
for (let i = 0; i < puData.length / 2; i++) {
|
||||
@@ -230,16 +220,16 @@ function getddCalcu720p(puData, programId) {
|
||||
switch (i) {
|
||||
case 1:
|
||||
// ddCalcu.push(token=="" ?"e":keys[] )
|
||||
ddCalcu.push("e")
|
||||
ddCalcu.push("v")
|
||||
break;
|
||||
case 2:
|
||||
ddCalcu.push(keys[parseInt(getDateString(new Date())[6])])
|
||||
ddCalcu.push(keys[parseInt(getDateString(new Date())[2])])
|
||||
break;
|
||||
case 3:
|
||||
ddCalcu.push(keys[programId[2]])
|
||||
ddCalcu.push(keys[programId[6]])
|
||||
break;
|
||||
case 4:
|
||||
ddCalcu.push("0")
|
||||
ddCalcu.push("a")
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -265,7 +255,7 @@ function getddCalcuURL720p(puDataURL, programId) {
|
||||
const puData = puDataURL.split("&puData=")[1]
|
||||
const ddCalcu = getddCalcu720p(puData, programId)
|
||||
|
||||
return `${puDataURL}&ddCalcu=${ddCalcu}`
|
||||
return `${puDataURL}&ddCalcu=${ddCalcu}&sv=10004&ct=android`
|
||||
}
|
||||
|
||||
export { initWasm, getEncryptURL, getddCalcuURL, getddCalcuURL720p }
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import axios from "axios"
|
||||
|
||||
// 睡眠
|
||||
function delay(ms) {
|
||||
@@ -9,10 +8,10 @@ function delay(ms) {
|
||||
|
||||
// 获取分类集合
|
||||
async function cateList() {
|
||||
const resp = await axios.get("https://program-sc.miguvideo.com/live/v2/tv-data/1ff892f2b5ab4a79be6e25b69d2f5d05")
|
||||
let liveList = resp.data.body.liveList
|
||||
const resp = await fetch("https://program-sc.miguvideo.com/live/v2/tv-data/1ff892f2b5ab4a79be6e25b69d2f5d05").then(r => r.json())
|
||||
let liveList = resp.body.liveList
|
||||
// 热门内容重复
|
||||
liveList = liveList.filter((item) => {
|
||||
liveList = liveList.filter(item => {
|
||||
return item.name != "热门"
|
||||
})
|
||||
|
||||
@@ -32,8 +31,8 @@ async function dataList() {
|
||||
|
||||
for (let cate in cates) {
|
||||
try {
|
||||
const resp = await axios.get("https://program-sc.miguvideo.com/live/v2/tv-data/" + cates[cate].vomsID)
|
||||
cates[cate].dataList = resp.data.body.dataList
|
||||
const resp = await fetch("https://program-sc.miguvideo.com/live/v2/tv-data/" + cates[cate].vomsID).then(r => r.json())
|
||||
cates[cate].dataList = resp.body.dataList
|
||||
} catch (error) {
|
||||
cates[cate].dataList = [];
|
||||
}
|
||||
|
||||
@@ -40,5 +40,12 @@ function renameFileSync(oldFilePath, newFilePath) {
|
||||
}
|
||||
})
|
||||
}
|
||||
function copyFileSync(filePath, newFilePath, mode) {
|
||||
fs.copyFileSync(filePath, newFilePath, mode, err => {
|
||||
if (err) {
|
||||
throw new Error(`文件复制失败${filePath} -> ${newFilePath}`)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export { createFile, writeFile, appendFile, appendFileSync, readFileSync, renameFileSync }
|
||||
export { createFile, writeFile, appendFile, appendFileSync, readFileSync, renameFileSync, copyFileSync }
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import axios from "axios"
|
||||
import { getDateString, getDateTimeString } from "./time.js"
|
||||
import { appendFileSync } from "./fileUtil.js"
|
||||
import { cntvNames } from "./datas.js"
|
||||
@@ -7,7 +6,7 @@ import { cntvNames } from "./datas.js"
|
||||
async function getPlaybackData(programId) {
|
||||
const date = new Date()
|
||||
const today = getDateString(date)
|
||||
const resp = await axios.get(`https://program-sc.miguvideo.com/live/v2/tv-programs-data/${programId}/${today}`).then(r => r.data)
|
||||
const resp = await fetch(`https://program-sc.miguvideo.com/live/v2/tv-programs-data/${programId}/${today}`).then(r => r.json())
|
||||
return resp.body?.program[0]?.content
|
||||
}
|
||||
|
||||
@@ -43,7 +42,7 @@ async function updatePlaybackDataByCntv(program, filePath) {
|
||||
const date = new Date()
|
||||
const today = getDateString(date)
|
||||
const cntvName = cntvNames[program.name]
|
||||
const resp = await axios.get(`https://api.cntv.cn/epg/epginfo3?serviceId=shiyi&d=${today}&c=${cntvName}`).then(r => r.data)
|
||||
const resp = await fetch(`https://api.cntv.cn/epg/epginfo3?serviceId=shiyi&d=${today}&c=${cntvName}`).then(r => r.json())
|
||||
|
||||
const playbackData = resp[cntvName]?.program
|
||||
if (!playbackData) {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import axios from "axios"
|
||||
import { AESencrypt, getStringMD5, KEY_AES, RSAencrypt } from "./EncryUtils.js"
|
||||
import { AESencrypt, getStringMD5, RSAencrypt } from "./EncryUtils.js"
|
||||
|
||||
// 类似URLEncoder.encode()的效果
|
||||
/**
|
||||
* @param {string} str -
|
||||
* @returns {string} -
|
||||
*/
|
||||
function encodeURLEncoder(str) {
|
||||
return encodeURIComponent(str)
|
||||
.replace(/[!'()*]/g, (c) =>
|
||||
@@ -10,7 +12,12 @@ function encodeURLEncoder(str) {
|
||||
.replace(/%20/g, '+');
|
||||
}
|
||||
|
||||
// 刷新token
|
||||
/**
|
||||
* 刷新token
|
||||
* @param {string} userId - 用户ID
|
||||
* @param {string} token - 用户token
|
||||
* @returns {boolean} - 是否成功
|
||||
*/
|
||||
async function refreshToken(userId, token) {
|
||||
|
||||
if (userId == null || userId == undefined || token == null || token == undefined) {
|
||||
@@ -22,8 +29,8 @@ async function refreshToken(userId, token) {
|
||||
const baseData = `{"userToken":"${token}","autoDelay":true,"deviceId":"","userId":"${userId}","timestamp":"${time}"}`
|
||||
|
||||
// 请求体加密
|
||||
const encryData = AESencrypt(baseData, KEY_AES)
|
||||
const data = '{"data":"' + encryData.substring(0, encryData.length - 2) + '\\u003d\\u003d"}'
|
||||
const encryData = AESencrypt(baseData)
|
||||
const data = '{"data":"' + encryData + '"}'
|
||||
|
||||
// 签名
|
||||
const str = getStringMD5(data)
|
||||
@@ -39,9 +46,11 @@ async function refreshToken(userId, token) {
|
||||
const params = `?clientId=27fb3129-5a54-45bc-8af1-7dc8f1155501&sign=${sign}&signType=RSA`
|
||||
|
||||
// 发送请求
|
||||
const respResult = await axios.post(baseURL + params, data, {
|
||||
headers: headers
|
||||
}).then(r => r.data)
|
||||
const respResult = await fetch(baseURL + params, {
|
||||
headers: headers,
|
||||
method: "post",
|
||||
body: data
|
||||
}).then(r => r.json())
|
||||
|
||||
// 处理响应结果
|
||||
if (respResult.resultCode == "REFRESH_TOKEN_SUCCESS") {
|
||||
|
||||
Reference in New Issue
Block a user