mirror of
https://github.com/develop202/migu_video.git
synced 2025-12-16 23:09:37 +08:00
添加体育
This commit is contained in:
@@ -10,7 +10,5 @@ RUN apk add --no-cache tzdata \
|
||||
&& ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \
|
||||
&& echo $TZ > /etc/timezone
|
||||
|
||||
RUN npm install
|
||||
|
||||
CMD [ "node", "app.js" ]
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
账号🐔了。~~只有标清..~~ 高清为主😅 gitee仓库被改私有了..
|
||||
|
||||
gitee经常请求超时,仓库链接已经很不稳定,有条件还是搞本地吧。。。
|
||||
gitee ip被ban,仓库链接已失效
|
||||
|
||||
访问地址(可回看当天内容)
|
||||
|
||||
@@ -28,15 +28,15 @@ https://gh-proxy.com/https://raw.githubusercontent.com/develop202/migu_video/ref
|
||||
|
||||
## 配置
|
||||
|
||||
配置信息如下,默认本机和局域网可用,未登录720p已失效
|
||||
配置信息如下,默认本机和局域网可用
|
||||
|
||||
| 变量名 | 默认值 | 类型 | 介绍 |
|
||||
| --------- | ------ | ------ | ------------------------------------------------ |
|
||||
| --------- | ------ | ------ | -------------------------------------------- |
|
||||
| muserId | | string | 用户id,可在网页端登录获取 |
|
||||
| mtoken | | string | 用户token,可在网页端登录获取 |
|
||||
| mport | 1234 | number | 本地运行端口号 |
|
||||
| mhost | | string | 公网/自定义访问地址 格式<http://你的ip:1234> |
|
||||
| mrateType | 3 | number | 画质 2:标清 3:高清(需登录) 4:蓝光(需登录且有VIP) |
|
||||
| mrateType | 3 | number | 画质 2:标清 3:高清 4:蓝光(需登录且有VIP) |
|
||||
|
||||
## node
|
||||
|
||||
@@ -49,7 +49,6 @@ https://gh-proxy.com/https://raw.githubusercontent.com/develop202/migu_video/ref
|
||||
```shell
|
||||
git clone git@github.com:develop202/migu_video.git
|
||||
cd migu_video
|
||||
npm i
|
||||
```
|
||||
|
||||
### 运行
|
||||
|
||||
39
app.js
39
app.js
@@ -68,6 +68,7 @@ const server = http.createServer(async (req, res) => {
|
||||
loading = false
|
||||
return
|
||||
} catch (error) {
|
||||
printRed(error)
|
||||
|
||||
res.writeHead(200, { "Content-Type": "application/json;charset=UTF-8" })
|
||||
res.end("访问异常")
|
||||
@@ -92,6 +93,7 @@ const server = http.createServer(async (req, res) => {
|
||||
loading = false
|
||||
return
|
||||
} catch (error) {
|
||||
printRed(error)
|
||||
|
||||
res.writeHead(200, { "Content-Type": "application/json;charset=UTF-8" })
|
||||
res.end("访问异常")
|
||||
@@ -138,10 +140,14 @@ const server = http.createServer(async (req, res) => {
|
||||
let playURL = urlCache[pid].url
|
||||
// 节目调整
|
||||
if (playURL == "") {
|
||||
printRed(`${pid} 节目调整,暂不提供服务`)
|
||||
let msg = "节目调整,暂不提供服务"
|
||||
if (urlCache[pid].content != null) {
|
||||
msg = urlCache[pid].content.message
|
||||
}
|
||||
printRed(`${pid} ${msg}`)
|
||||
|
||||
res.writeHead(200, { "Content-Type": "application/json;charset=UTF-8" })
|
||||
res.end("节目调整,暂不提供服务")
|
||||
res.end(msg)
|
||||
loading = false
|
||||
return
|
||||
}
|
||||
@@ -173,6 +179,7 @@ const server = http.createServer(async (req, res) => {
|
||||
resObj = await getAndroidURL(userId, token, pid, rateType)
|
||||
}
|
||||
} catch (error) {
|
||||
printRed(error)
|
||||
|
||||
res.writeHead(200, { "Content-Type": "application/json;charset=UTF-8" })
|
||||
res.end("链接请求出错,请稍后重试")
|
||||
@@ -200,7 +207,7 @@ const server = http.createServer(async (req, res) => {
|
||||
if (location == "" || location == undefined || location == null) {
|
||||
continue
|
||||
}
|
||||
if (location.startsWith("http://hlsz")) {
|
||||
if (location.startsWith("http://hlsz") || location.startsWith("http://mgsp") || location.startsWith("http://trial")) {
|
||||
resObj.url = location
|
||||
break
|
||||
}
|
||||
@@ -214,6 +221,7 @@ const server = http.createServer(async (req, res) => {
|
||||
}
|
||||
}
|
||||
|
||||
// printRed(resObj.url)
|
||||
printGreen(`添加节目缓存 ${pid}`)
|
||||
// 缓存有效时长
|
||||
let addTime = 3 * 60 * 60 * 1000
|
||||
@@ -229,15 +237,20 @@ const server = http.createServer(async (req, res) => {
|
||||
urlCache[pid] = {
|
||||
// 有效期3小时 节目调整时改为1分钟
|
||||
valTime: Date.now() + addTime,
|
||||
url: resObj.url
|
||||
url: resObj.url,
|
||||
content: resObj.content,
|
||||
}
|
||||
// console.log(resObj.url)
|
||||
|
||||
if (resObj.url == "") {
|
||||
printRed(`${pid} 节目调整,暂不提供服务`)
|
||||
let msg = "节目调整,暂不提供服务"
|
||||
if (resObj.content != null) {
|
||||
msg = resObj.content.message
|
||||
}
|
||||
printRed(`${pid} ${msg}`)
|
||||
|
||||
res.writeHead(200, { "Content-Type": "application/json;charset=UTF-8" })
|
||||
res.end("节目调整,暂不提供服务")
|
||||
res.end(msg)
|
||||
loading = false
|
||||
return
|
||||
}
|
||||
@@ -267,29 +280,31 @@ const server = http.createServer(async (req, res) => {
|
||||
|
||||
server.listen(port, async () => {
|
||||
|
||||
// 设置定时器,6小时更新一次
|
||||
// 设置定时器,3小时更新一次
|
||||
setInterval(async () => {
|
||||
printBlue(`\n准备更新文件 ${getDateTimeStr(new Date())}\n`)
|
||||
hours += 6
|
||||
printBlue(`准备更新文件 ${getDateTimeStr(new Date())}`)
|
||||
hours += 3
|
||||
try {
|
||||
await update(hours)
|
||||
} catch (error) {
|
||||
printRed(error)
|
||||
printRed("更新失败")
|
||||
console.log(error)
|
||||
}
|
||||
|
||||
printBlue(`\n当前已运行${hours}小时`)
|
||||
}, 6 * 60 * 60 * 1000);
|
||||
printBlue(`当前已运行${hours}小时`)
|
||||
}, 3 * 60 * 60 * 1000);
|
||||
|
||||
try {
|
||||
// 初始化数据
|
||||
await update(hours)
|
||||
} catch (error) {
|
||||
printRed(error)
|
||||
printRed("更新失败")
|
||||
console.log(error)
|
||||
}
|
||||
|
||||
printYellow("每6小时更新一次")
|
||||
printGreen("每3小时更新一次")
|
||||
|
||||
printGreen(`本地地址: http://localhost:${port}`)
|
||||
if (host != "") {
|
||||
|
||||
291
package-lock.json
generated
291
package-lock.json
generated
@@ -4,296 +4,7 @@
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "migu_video",
|
||||
"dependencies": {
|
||||
"axios": "^1.9.0",
|
||||
"crypto-js": "^4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.12.2",
|
||||
"resolved": "https://registry.npmmirror.com/axios/-/axios-1.12.2.tgz",
|
||||
"integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
"form-data": "^4.0.4",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bind-apply-helpers": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
||||
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/crypto-js": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.2.0.tgz",
|
||||
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dunder-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"gopd": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-define-property": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-errors": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz",
|
||||
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-object-atoms": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
|
||||
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-set-tostringtag": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
|
||||
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"get-intrinsic": "^1.2.6",
|
||||
"has-tostringtag": "^1.0.2",
|
||||
"hasown": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.9",
|
||||
"resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz",
|
||||
"integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"debug": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.4.tgz",
|
||||
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"es-set-tostringtag": "^2.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-intrinsic": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.2",
|
||||
"es-define-property": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"es-object-atoms": "^1.1.1",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-proto": "^1.0.1",
|
||||
"gopd": "^1.2.0",
|
||||
"has-symbols": "^1.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"math-intrinsics": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"dunder-proto": "^1.0.1",
|
||||
"es-object-atoms": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
|
||||
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-symbols": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-tostringtag": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
||||
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"has-symbols": "^1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz",
|
||||
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/math-intrinsics": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
|
||||
"license": "MIT"
|
||||
"name": "migu_video"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
{
|
||||
"name": "migu_video",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"axios": "^1.9.0",
|
||||
"crypto-js": "^4.2.0"
|
||||
}
|
||||
"dependencies": {}
|
||||
}
|
||||
|
||||
121
updateData.js
121
updateData.js
@@ -1,25 +1,26 @@
|
||||
import { dataList } from "./utils/fetchList.js"
|
||||
import { appendFile, appendFileSync, renameFileSync, writeFile } from "./utils/fileUtil.js"
|
||||
import { appendFile, appendFileSync, copyFileSync, renameFileSync, writeFile } from "./utils/fileUtil.js"
|
||||
import { updatePlaybackData } from "./utils/playback.js"
|
||||
import { /* refreshToken as mrefreshToken, */ host, token, userId } from "./config.js"
|
||||
import refreshToken from "./utils/refreshToken.js"
|
||||
import { printGreen, printRed, printYellow } from "./utils/colorOut.js"
|
||||
import { getDateString } from "./utils/time.js"
|
||||
|
||||
async function update(hours) {
|
||||
/**
|
||||
* @param {Number} hours -更新小时数
|
||||
*/
|
||||
async function updateTV(hours) {
|
||||
|
||||
const date = new Date()
|
||||
const start = date.getTime()
|
||||
let interfacePath = ""
|
||||
// 获取数据
|
||||
const datas = await dataList()
|
||||
printGreen("数据获取成功!")
|
||||
printGreen("TV数据获取成功!")
|
||||
|
||||
if (!(hours % 24)) {
|
||||
// 必须绝对路径
|
||||
interfacePath = process.cwd() + '/interface.txt.bak'
|
||||
interfacePath = `${process.cwd()}/interface.txt.bak`
|
||||
// 创建写入空内容
|
||||
writeFile(interfacePath, "")
|
||||
}
|
||||
|
||||
if (!(hours % 24)) {
|
||||
// 每24小时刷新token
|
||||
@@ -30,11 +31,11 @@ async function update(hours) {
|
||||
// printGreen(`跳过token刷新`)
|
||||
// }
|
||||
}
|
||||
appendFile(interfacePath, `#EXTM3U x-tvg-url="\${replace}/playback.xml" catchup="append" catchup-source="?playbackbegin=\${(b)yyyyMMddHHmmss}&playbackend=\${(e)yyyyMMddHHmmss}"\n`)
|
||||
}
|
||||
printYellow("正在更新...")
|
||||
appendFile(interfacePath, `#EXTM3U x-tvg-url="\${replace}/playback.xml" catchup="append" catchup-source="?playbackbegin=\${(b)yyyyMMddHHmmss}&playbackend=\${(e)yyyyMMddHHmmss}"\n`)
|
||||
printYellow("开始更新TV...")
|
||||
// 回放
|
||||
const playbackFile = process.cwd() + '/playback.xml.bak'
|
||||
const playbackFile = `${process.cwd()}/playback.xml.bak`
|
||||
writeFile(playbackFile,
|
||||
`<?xml version="1.0" encoding="UTF-8"?>\n` +
|
||||
`<tv generator-info-name="Tak" generator-info-url="${host}">\n`)
|
||||
@@ -48,28 +49,112 @@ async function update(hours) {
|
||||
|
||||
await updatePlaybackData(data[j], playbackFile)
|
||||
|
||||
if (!(hours % 24)) {
|
||||
// 写入节目
|
||||
appendFile(interfacePath, `#EXTINF:-1 tvg-id="${data[j].name}" tvg-name="${data[j].name}" tvg-logo="${data[j].pics.highResolutionH}" group-title="${datas[i].name}",${data[j].name}\n\${replace}/${data[j].pID}\n`)
|
||||
// printGreen(` 节目链接更新成功`)
|
||||
}
|
||||
}
|
||||
if (!(hours % 24)) {
|
||||
printGreen(`分类###:${datas[i].name} 更新完成!`)
|
||||
}
|
||||
}
|
||||
|
||||
appendFileSync(playbackFile, `</tv>\n`)
|
||||
|
||||
// 重命名
|
||||
renameFileSync(playbackFile, playbackFile.replace(".bak", ""))
|
||||
if (!(hours % 24)) {
|
||||
renameFileSync(interfacePath, interfacePath.replace(".bak", ""))
|
||||
}
|
||||
printYellow("更新完成!")
|
||||
printGreen("TV更新完成!")
|
||||
const end = Date.now()
|
||||
printYellow(`本次耗时: ${(end - start) / 1000}秒`)
|
||||
printYellow(`TV更新耗时: ${(end - start) / 1000}秒`)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Number} hours -更新小时数
|
||||
*/
|
||||
async function updatePE(hours) {
|
||||
|
||||
const date = new Date()
|
||||
const start = date.getTime()
|
||||
// 获取PE数据
|
||||
const datas = await fetch("http://v0-sc.miguvideo.com/vms-match/v6/staticcache/basic/match-list/normal-match-list/0/all/default/1/miguvideo").then(r => r.json())
|
||||
printGreen("PE数据获取成功!")
|
||||
// console.dir(datas, { depth: null })
|
||||
|
||||
copyFileSync(`${process.cwd()}/interface.txt`, `${process.cwd()}/interface.txt.bak`, 0)
|
||||
const interfacePath = `${process.cwd()}/interface.txt.bak`
|
||||
|
||||
printYellow("开始更新PE...")
|
||||
|
||||
for (let i = 1; i < 4; i++) {
|
||||
// 日期
|
||||
const date = datas.body?.days[i]
|
||||
for (const data of datas.body?.matchList[date]) {
|
||||
let relativeDate = "昨天"
|
||||
const dateString = getDateString(new Date())
|
||||
if (date == dateString) {
|
||||
relativeDate = "今天"
|
||||
} else if (parseInt(date.substring(6)) > parseInt(dateString.substring(6))) {
|
||||
relativeDate = "明天"
|
||||
}
|
||||
|
||||
let pkInfoTitle = data.pkInfoTitle
|
||||
if (data.confrontTeams) {
|
||||
pkInfoTitle = `${data.confrontTeams[0].name}VS${data.confrontTeams[1].name}`
|
||||
}
|
||||
// const peResult = await fetch(`http://app-sc.miguvideo.com/vms-match/v5/staticcache/basic/all-view-list/${data.mgdbId}/2/miguvideo`).then(r => r.json())
|
||||
const peResult = await fetch(`https://vms-sc.miguvideo.com/vms-match/v6/staticcache/basic/basic-data/${data.mgdbId}/miguvideo`).then(r => r.json())
|
||||
try {
|
||||
// 比赛已结束
|
||||
if (peResult.body.endTime < Date.now()) {
|
||||
const replayResult = await fetch(`http://app-sc.miguvideo.com/vms-match/v5/staticcache/basic/all-view-list/${data.mgdbId}/2/miguvideo`).then(r => r.json())
|
||||
let replayList = replayResult.body?.replayList
|
||||
if (replayList == null || replayList == undefined) {
|
||||
replayList = peResult.body.multiPlayList.replayList
|
||||
}
|
||||
if (replayList == null || replayList == undefined) {
|
||||
printYellow(`${data.mgdbId} ${pkInfoTitle} 无回放`)
|
||||
continue
|
||||
}
|
||||
for (const replay of replayList) {
|
||||
if (replay.name.match(/.*集锦|训练.*/) != null) {
|
||||
continue
|
||||
}
|
||||
if (replay.name.match(/.*回放|赛.*/) != null) {
|
||||
// 写入赛事
|
||||
appendFileSync(interfacePath, `#EXTINF:-1 tvg-id="${pkInfoTitle}" tvg-name="${pkInfoTitle}" tvg-logo="${data.competitionLogo}" group-title="体育-${relativeDate}",${data.competitionName} ${pkInfoTitle} ${replay.name} ${peResult.body.multiPlayList.preList[peResult.body.multiPlayList.preList.length - 1].startTimeStr.substring(11, 16)}\n\${replace}/${replay.pID}\n`)
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
// 比赛未结束
|
||||
const liveList = peResult.body.multiPlayList.liveList
|
||||
for (const live of liveList) {
|
||||
if (live.name.match(/.*集锦.*/) != null || live.startTimeStr == undefined) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 写入赛事
|
||||
appendFileSync(interfacePath, `#EXTINF:-1 tvg-id="${pkInfoTitle}" tvg-name="${pkInfoTitle}" tvg-logo="${data.competitionLogo}" group-title="体育-${relativeDate}",${data.competitionName} ${pkInfoTitle} ${live.name} ${live.startTimeStr.substring(11, 16)}\n\${replace}/${live.pID}\n`)
|
||||
}
|
||||
} catch (error) {
|
||||
printRed(`${data.mgdbId} ${pkInfoTitle} 更新失败`)
|
||||
printRed(error)
|
||||
}
|
||||
}
|
||||
printGreen(`日期 ${date} 更新完成!`)
|
||||
}
|
||||
|
||||
// 重命名
|
||||
renameFileSync(interfacePath, interfacePath.replace(".bak", ""))
|
||||
printGreen("PE更新完成!")
|
||||
const end = Date.now()
|
||||
printYellow(`PE更新耗时: ${(end - start) / 1000}秒`)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Number} hours - 更新小时数
|
||||
*/
|
||||
async function update(hours) {
|
||||
await updateTV(hours)
|
||||
await updatePE(hours)
|
||||
}
|
||||
|
||||
export default update
|
||||
|
||||
@@ -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