From 7426f91c109b08bb6831947b62f9ea6a5f3cd48f Mon Sep 17 00:00:00 2001 From: ygbhbox Date: Sat, 29 Nov 2025 10:35:53 +0000 Subject: [PATCH] cctvnews.js created online with Bitbucket --- TVBoxOSC/cctvnews.js | 152 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 TVBoxOSC/cctvnews.js diff --git a/TVBoxOSC/cctvnews.js b/TVBoxOSC/cctvnews.js new file mode 100644 index 0000000..d21a08c --- /dev/null +++ b/TVBoxOSC/cctvnews.js @@ -0,0 +1,152 @@ +const CryptoJS = require("crypto"); + +function main(item) { + // 重试机制 + for (let attempt = 0; attempt < 3; attempt++) { + try { + const id = item.id || 'cctv1'; + const n = { + 'cctv1': '11200132825562653886', + 'cctv2': '12030532124776958103', + 'cctv4': '10620168294224708952', + 'cctv7': '8516529981177953694', + 'cctv9': '7252237247689203957', + 'cctv10': '14589146016461298119', + 'cctv12': '13180385922471124325', + 'cctv13': '16265686808730585228', + 'cctv17': '4496917190172866934', + 'cctv4k': '2127841942201075403', + }; + + const articleId = n[id]; + if (!articleId) { + return { + url: null, + error: `不支持的频道ID: ${id}`, + success: false + }; + } + + const t = Math.floor(Date.now() / 1000); + const sail = ku9.md5(`articleId=${articleId}&scene_type=6`); + const w = `&&&20000009&${sail}&${t}&emas.feed.article.live.detail&1.0.0&&&&&`; + const k = "emasgatewayh5"; + const sign = CryptoJS.HmacSHA256(w, k).toString(); + const url = `https://emas-api.cctvnews.cctv.com/h5/emas.feed.article.live.detail/1.0.0?articleId=${articleId}&scene_type=6`; + const client_id = ku9.md5(t.toString()); + const headers = { + 'cookieuid': client_id, + 'from-client': 'h5', + 'referer': 'https://m-live.cctvnews.cctv.com/', + 'x-emas-gw-appkey': '20000009', + 'x-emas-gw-pv': '6.1', + 'x-emas-gw-sign': sign, + 'x-emas-gw-t': t, + 'x-req-ts': t * 1000 + }; + + const res = ku9.get(url, headers); + if (!res) { + if (attempt < 2) continue; // 重试 + return { + url: null, + error: '网络请求失败', + success: false + }; + } + + const responseData = JSON.parse(res); + if (!responseData || !responseData.response) { + if (attempt < 2) continue; // 重试 + return { + url: null, + error: 'API返回数据格式错误', + success: false + }; + } + + const decodedData = JSON.parse(ku9.decodeBase64(responseData.response)); + if (!decodedData || !decodedData.data) { + if (attempt < 2) continue; // 重试 + return { + url: null, + error: '解码后的数据格式错误', + success: false + }; + } + + const data = decodedData.data; + + // 使用安全访问函数,避免直接访问可能为null的属性 + const getSafeValue = (obj, path, defaultValue = null) => { + const keys = path.split('.'); + let result = obj; + for (const key of keys) { + if (result === null || result === undefined) return defaultValue; + // 处理数组索引 + if (key.includes('[') && key.includes(']')) { + const arrayKey = key.split('[')[0]; + const index = parseInt(key.split('[')[1].split(']')[0]); + if (!Array.isArray(result[arrayKey]) || index >= result[arrayKey].length) { + return defaultValue; + } + result = result[arrayKey][index]; + } else { + result = result[key]; + } + } + return result === null || result === undefined ? defaultValue : result; + }; + + // 安全获取认证URL + const authUrl = getSafeValue(data, 'live_room.liveCameraList[0].pullUrlList[0].authResultUrl[0].authUrl'); + if (!authUrl) { + if (attempt < 2) continue; // 重试 + return { + url: null, + error: '无法获取认证URL,可能该频道当前无直播', + success: false + }; + } + + const dk = getSafeValue(data, 'dk'); + if (!dk) { + if (attempt < 2) continue; // 重试 + return { + url: null, + error: '缺少解密密钥(dk)', + success: false + }; + } + + const key = dk.substring(0, 8) + t.toString().substring(t.toString().length - 8); + const iv = dk.substring(dk.length - 8) + t.toString().substring(0, 8); + const decrypted = ku9.opensslDecrypt(authUrl, "AES-128-CBC", key, 0, iv); + + if (!decrypted) { + if (attempt < 2) continue; // 重试 + return { + url: null, + error: 'URL解密失败', + success: false + }; + } + + return { + url: decrypted, + success: true + }; + + } catch (error) { + // 最后一次尝试仍然失败,返回错误 + if (attempt === 2) { + return { + url: null, + error: `执行错误: ${error.message}`, + success: false + }; + } + // 否则继续重试 + } + } +} \ No newline at end of file