找回密码
 立即注册
搜索
查看: 184|回复: 8

央视新闻JS---求大佬完善

[复制链接]

2

主题

65

回帖

93

积分

彩电迷

积分
93
发表于 2025-11-4 16:32:31 | 显示全部楼层 |阅读模式
AI转出来的,默认只能播放CCTV1,烦请有技术的大佬修改。
管理员的PHP我部署在路由上,用的PHP8,结果不能使用。其他的PHP都没问题。不知道啥原因
根据管理员的PHP转出来的,如有不合适,烦请管理员删帖
  1. function main(item) {
  2.     var id = item.id || 'cctv1';
  3.    
  4.     // 频道映射配置
  5.     var channelMap = {
  6.         'cctv1': '11200132825562653886',
  7.         'cctv2': '12030532124776958103',
  8.         'cctv4': '10620168294224708952',
  9.         'cctv7': '8516529981177953694',
  10.         'cctv9': '7252237247689203957',
  11.         'cctv10': '14589146016461298119',
  12.         'cctv12': '13180385922471124325',
  13.         'cctv13': '16265686808730585228',
  14.         'cctv17': '4496917190172866934',
  15.         'cctv4k': '2127841942201075403'
  16.     };
  17.    
  18.     // 缓存设置
  19.     let cacheKey = "ysxw_cache_" + id;
  20.     const cacheExpiry = 60 * 1000; // 60秒缓存
  21.    
  22.     // 尝试从缓存获取数据
  23.     const cachedData = ku9.getCache(cacheKey);
  24.     if (cachedData) {
  25.         return {
  26.             url: cachedData,
  27.             headers: {
  28.                 'Referer': 'https://m-live.cctvnews.cctv.com/',
  29.                 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
  30.             }
  31.         };
  32.     }
  33.    
  34.     // 获取播放地址
  35.     var room = channelMap[id] || channelMap['cctv1'];
  36.     var playUrl = getPlayUrlFromWeb(room);
  37.    
  38.     // 缓存结果
  39.     if (playUrl) {
  40.         ku9.setCache(cacheKey, playUrl, cacheExpiry);
  41.     }
  42.    
  43.     // 返回播放地址和头信息
  44.     return {
  45.         url: playUrl || "",
  46.         headers: {
  47.             'Referer': 'https://m-live.cctvnews.cctv.com/',
  48.             'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
  49.         }
  50.     };
  51. }

  52. // 从网络获取播放地址
  53. function getPlayUrlFromWeb(room) {
  54.     try {
  55.         var url = "https://gateway2.cctvnews.cctv.com/1.0.0/feed/article/live/detail?articleId=" + room + "&scene_type=6";
  56.         var t = Math.round(Date.now());
  57.         var clientId = createUuid();
  58.         var xReqTs = t - 1;
  59.         
  60.         // 生成签名
  61.         var signStr = "GET\napplication/json\n\n\n\nx-ca-key:204133710\nx-ca-stage:RELEASE\nx-ca-timestamp:" + t + "\n/1.0.0/feed/article/live/detail?articleId=" + room + "&scene_type=6";
  62.         var secret = 'etyEuNdA7GvQU7iPZHqnrBpSFfRyKQTD';
  63.         
  64.         // 使用HMAC-SHA256生成签名
  65.         var sign = generateHmacSha256(signStr, secret);
  66.         
  67.         // 构建请求头
  68.         var headers = {
  69.             'accept': 'application/json',
  70.             'cookieuid': clientId,
  71.             'from-client': 'h5',
  72.             'userid': clientId,
  73.             'x-ca-key': '204133710',
  74.             'x-ca-stage': 'RELEASE',
  75.             'x-ca-signature': sign,
  76.             'x-ca-signature-headers': 'x-ca-key,x-ca-stage,x-ca-timestamp',
  77.             'x-ca-timestamp': t.toString(),
  78.             'x-req-ts': xReqTs.toString(),
  79.             'x-request-id': clientId,
  80.             'Referer': 'https://m-live.cctvnews.cctv.com/',
  81.             'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
  82.         };
  83.         
  84.         // 发送API请求
  85.         var res = ku9.request(url, "GET", headers);
  86.         
  87.         if (!res || !res.body) {
  88.             console.error("API请求失败");
  89.             return null;
  90.         }
  91.         
  92.         // 解析响应
  93.         var jsonData = JSON.parse(res.body);
  94.         
  95.         if (!jsonData.response) {
  96.             console.error("响应中没有response字段");
  97.             return null;
  98.         }
  99.         
  100.         // 解码base64响应
  101.         var decodedResponse = ku9.decodeBase64(jsonData.response);
  102.         var responseData = JSON.parse(decodedResponse);
  103.         
  104.         if (!responseData.data || !responseData.data.live_room) {
  105.             console.error("响应中没有live_room数据");
  106.             return null;
  107.         }
  108.         
  109.         var data = responseData.data;
  110.         var liveRoom = data.live_room;
  111.         
  112.         // 安全检查数组访问
  113.         if (!liveRoom.liveCameraList || liveRoom.liveCameraList.length === 0) {
  114.             console.error("liveCameraList为空");
  115.             return null;
  116.         }
  117.         
  118.         var firstCamera = liveRoom.liveCameraList[0];
  119.         
  120.         if (!firstCamera.pullUrlList || firstCamera.pullUrlList.length === 0) {
  121.             console.error("pullUrlList为空");
  122.             return null;
  123.         }
  124.         
  125.         var firstPullUrl = firstCamera.pullUrlList[0];
  126.         
  127.         if (!firstPullUrl.authResultUrl || firstPullUrl.authResultUrl.length === 0) {
  128.             console.error("authResultUrl为空");
  129.             return null;
  130.         }
  131.         
  132.         var authUrl = firstPullUrl.authResultUrl[0].authUrl;
  133.         
  134.         if (!authUrl) {
  135.             console.error("authUrl为空");
  136.             return null;
  137.         }
  138.         
  139.         var liveUrl;
  140.         if (authUrl.toLowerCase().indexOf('http') === 0) {
  141.             liveUrl = authUrl;
  142.         } else {
  143.             var dk = data.dk;
  144.             if (!dk) {
  145.                 console.error("dk为空,无法解密");
  146.                 return null;
  147.             }
  148.             liveUrl = decryptUrl(authUrl, dk, xReqTs);
  149.         }
  150.         
  151.         // 将https替换为http
  152.         if (liveUrl) {
  153.             liveUrl = liveUrl.replace(/https:/i, 'http:');
  154.         }
  155.         
  156.         return liveUrl;
  157.         
  158.     } catch (e) {
  159.         console.error('获取播放URL过程中出错:', e);
  160.         return null;
  161.     }
  162. }

  163. // 生成HMAC-SHA256签名
  164. function generateHmacSha256(message, secret) {
  165.     try {
  166.         // 如果环境支持CryptoJS,使用CryptoJS
  167.         const CryptoJS = require("crypto");
  168.         var hash = CryptoJS.HmacSHA256(message, secret);
  169.         return CryptoJS.enc.Base64.stringify(hash);
  170.     } catch (e) {
  171.         // 如果CryptoJS不可用,使用备选方法
  172.         console.warn('CryptoJS不可用,使用MD5作为备选签名');
  173.         return ku9.md5(message + secret).substring(0, 16);
  174.     }
  175. }

  176. // 生成UUID(参考PHP的create_uuid函数)
  177. function createUuid() {
  178.     var parts = [];
  179.     for (var i = 0; i < 8; i++) {
  180.         if (i === 3) {
  181.             // 第13位固定为4
  182.             var part = '4' + Math.floor(Math.random() * 0x1000).toString(16).substring(1, 4);
  183.             parts.push(part);
  184.         } else if (i === 4) {
  185.             // 第17位固定为8/9/a/b
  186.             var part = (0x8000 | Math.floor(Math.random() * 0x4000)).toString(16).substring(1, 5);
  187.             parts.push(part);
  188.         } else {
  189.             var part = Math.floor(Math.random() * 0x10000).toString(16).substring(1, 5);
  190.             parts.push(part);
  191.         }
  192.     }
  193.     return parts.join('');
  194. }

  195. // 解密URL
  196. function decryptUrl(encryptedData, dk, xReqTs) {
  197.     try {
  198.         // 如果已经是URL,直接返回
  199.         if (encryptedData.indexOf('http') === 0) {
  200.             return encryptedData;
  201.         }
  202.         
  203.         // 生成密钥和IV
  204.         var key = generateKey(dk, xReqTs);
  205.         var iv = generateIv(dk, xReqTs);
  206.         
  207.         // 尝试使用AES解密
  208.         var decrypted = ku9.opensslDecrypt(encryptedData, 'AES-128-CBC', key, 0, iv);
  209.         
  210.         if (decrypted && decrypted.indexOf('http') === 0) {
  211.             return decrypted;
  212.         }
  213.         
  214.         // 如果AES解密失败,尝试Base64解码
  215.         try {
  216.             var base64Decoded = ku9.decodeBase64(encryptedData);
  217.             if (base64Decoded && base64Decoded.indexOf('http') === 0) {
  218.                 return base64Decoded;
  219.             }
  220.         } catch (e) {
  221.             console.log("Base64解码失败:", e);
  222.         }
  223.         
  224.         // 如果所有解密方法都失败,返回原始数据
  225.         return encryptedData;
  226.         
  227.     } catch (e) {
  228.         console.error('解密过程中出错:', e);
  229.         return encryptedData;
  230.     }
  231. }

  232. // 生成密钥
  233. function generateKey(dk, xReqTs) {
  234.     var tsStr = Math.floor(xReqTs / 1000).toString();
  235.     return dk.substring(0, 8) + tsStr.substring(tsStr.length - 8);
  236. }

  237. // 生成IV
  238. function generateIv(dk, xReqTs) {
  239.     var tsStr = Math.floor(xReqTs / 1000).toString();
  240.     return dk.substring(dk.length - 8) + tsStr.substring(0, 8);
  241. }
复制代码

点评

这个js转出来估计是断流的。  发表于 2025-11-4 16:54
php没问题,估计是你保存时的php文件格式不对,可能带了BOM头。  发表于 2025-11-4 16:54

0

主题

48

回帖

92

积分

彩电迷

积分
92
发表于 2025-11-4 17:11:52 来自手机 | 显示全部楼层
用CCTV9测试了你这个js五分钟没有断流,你酷9版本太低了,下载最新版

1

主题

72

回帖

89

积分

彩电迷

积分
89
发表于 2025-11-4 17:17:41 | 显示全部楼层
有大佬能研究一下他这个直播流的校验问题吗
直接用他网页看好像没问题,但是通过代理出来的,好像会随机403,无法看,尤其是同一个地址被多个人使用的情况下,失效更快
他那个尾部里的时间看着也没过期,就是看不了,不知道是有啥限制

2

主题

65

回帖

93

积分

彩电迷

积分
93
 楼主| 发表于 2025-11-4 18:46:29 | 显示全部楼层
wk574244808 发表于 2025-11-4 17:11
用CCTV9测试了你这个js五分钟没有断流,你酷9版本太低了,下载最新版

你播放的是CCTV9吗?我也测试不断流,但是只能放出来CCTV1

4

主题

201

回帖

403

积分

等离子电视迷

积分
403
发表于 2025-11-4 19:30:25 来自手机 | 显示全部楼层
function main(item) {
    var id = item.id || 'cctv1';
   
    // 频道映射配置
    var channelMap = {
        'cctv1': '11200132825562653886',
        'cctv2': '12030532124776958103',
        'cctv4': '10620168294224708952',
        'cctv7': '8516529981177953694',
        'cctv9': '7252237247689203957',
        'cctv10': '14589146016461298119',
        'cctv12': '13180385922471124325',
        'cctv13': '16265686808730585228',
        'cctv17': '4496917190172866934',
        'cctv4k': '2127841942201075403'
    };
   
    var room = channelMap[id] || channelMap['cctv1'];
    console.log("请求频道: " + id + ", room: " + room);
   
    var playUrl = getPlayUrlFromWeb(room);
    console.log("获取到的播放地址: " + playUrl);
   
    if (playUrl && playUrl.indexOf('http') === 0) {
        return {
            url: playUrl,
            headers: {
                'Referer': 'https://m-live.cctvnews.cctv.com/',
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
            }
        };
    }
    return { url: '' };
}

// 从网络获取播放地址
function getPlayUrlFromWeb(room) {
    try {
        var url = "https://gateway2.cctvnews.cctv.com/1.0.0/feed/article/live/detail?articleId=" + room + "&scene_type=6";
        console.log("API请求URL: " + url);
        
        var t = Math.round(Date.now());
        var clientId = createUuid();
        var xReqTs = t - 1;
        
        // 生成签名 - 使用简化的签名方式
        var signStr = "GET\napplication/json\n\n\n\nx-ca-key:204133710\nx-ca-stage:RELEASE\nx-ca-timestamp:" + t + "\n/1.0.0/feed/article/live/detail?articleId=" + room + "&scene_type=6";
        var secret = 'etyEuNdA7GvQU7iPZHqnrBpSFfRyKQTD';
        
        // 使用CryptoJS生成HMAC-SHA256签名
        var sign = generateHmacSha256(signStr, secret);
        console.log("生成的签名: " + sign);
        
        // 构建请求头
        var headers = {
            'Accept': 'application/json',
            'cookieuid': clientId,
            'from-client': 'h5',
            'userid': clientId,
            'x-ca-key': '204133710',
            'x-ca-stage': 'RELEASE',
            'x-ca-signature': sign,
            'x-ca-signature-headers': 'x-ca-key,x-ca-stage,x-ca-timestamp',
            'x-ca-timestamp': t.toString(),
            'x-req-ts': xReqTs.toString(),
            'x-request-id': clientId,
            'Referer': 'https://m-live.cctvnews.cctv.com/',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        };
        
        console.log("发送API请求...");
        // 发送API请求
        var res = ku9.request(url, "GET", headers);
        console.log("API响应状态: " + res.code);
        
        if (!res || !res.body) {
            console.error("API请求失败");
            return null;
        }
        
        console.log("响应内容: " + res.body.substring(0, 500));
        
        // 解析响应
        var jsonData = JSON.parse(res.body);
        
        if (!jsonData.response) {
            console.error("响应中没有response字段");
            return null;
        }
        
        // 解码base64响应
        var decodedResponse = ku9.decodeBase64(jsonData.response);
        console.log("解码后响应: " + decodedResponse.substring(0, 500));
        
        var responseData = JSON.parse(decodedResponse);
        
        if (!responseData.data || !responseData.data.live_room) {
            console.error("响应中没有live_room数据");
            return null;
        }
        
        var data = responseData.data;
        var liveRoom = data.live_room;
        
        // 安全检查数组访问
        if (!liveRoom.liveCameraList || liveRoom.liveCameraList.length === 0) {
            console.error("liveCameraList为空");
            return null;
        }
        
        var firstCamera = liveRoom.liveCameraList[0];
        
        if (!firstCamera.pullUrlList || firstCamera.pullUrlList.length === 0) {
            console.error("pullUrlList为空");
            return null;
        }
        
        var firstPullUrl = firstCamera.pullUrlList[0];
        
        if (!firstPullUrl.authResultUrl || firstPullUrl.authResultUrl.length === 0) {
            console.error("authResultUrl为空");
            return null;
        }
        
        var authUrl = firstPullUrl.authResultUrl[0].authUrl;
        
        if (!authUrl) {
            console.error("authUrl为空");
            return null;
        }
        
        console.log("原始authUrl: " + authUrl);
        
        var liveUrl = authUrl;
        
        // 如果需要解密
        if (authUrl.toLowerCase().indexOf('http') !== 0) {
            var dk = data.dk;
            if (dk) {
                console.log("进行URL解密, dk: " + dk);
                liveUrl = decryptUrl(authUrl, dk, xReqTs);
            }
        }
        
        console.log("最终播放地址: " + liveUrl);
        return liveUrl;
        
    } catch (e) {
        console.error('获取播放URL过程中出错: ' + e.message);
        return null;
    }
}

// 生成HMAC-SHA256签名
function generateHmacSha256(message, secret) {
    try {
        const CryptoJS = require("crypto");
        var hash = CryptoJS.HmacSHA256(message, secret);
        return CryptoJS.enc.Base64.stringify(hash);
    } catch (e) {
        console.warn('CryptoJS HMAC-SHA256失败,使用备选方案: ' + e.message);
        // 备选方案:使用简单的MD5
        return ku9.md5(message + secret).substring(0, 32);
    }
}

// 生成UUID
function createUuid() {
    var parts = [];
    for (var i = 0; i < 8; i++) {
        if (i === 3) {
            var part = '4' + Math.floor(Math.random() * 0x1000).toString(16).substring(1, 4);
            parts.push(part);
        } else if (i === 4) {
            var part = (0x8000 | Math.floor(Math.random() * 0x4000)).toString(16).substring(1, 5);
            parts.push(part);
        } else {
            var part = Math.floor(Math.random() * 0x10000).toString(16).substring(1, 5);
            parts.push(part);
        }
    }
    return parts.join('');
}

// 解密URL
function decryptUrl(encryptedData, dk, xReqTs) {
    try {
        // 如果已经是URL,直接返回
        if (encryptedData.indexOf('http') === 0) {
            return encryptedData;
        }
        
        // 生成密钥和IV
        var key = generateKey(dk, xReqTs);
        var iv = generateIv(dk, xReqTs);
        
        console.log("解密参数 - key: " + key + ", iv: " + iv);
        
        // 尝试使用AES解密
        var decrypted = ku9.opensslDecrypt(encryptedData, 'AES-128-CBC', key, 0, iv);
        
        if (decrypted && decrypted.indexOf('http') === 0) {
            return decrypted;
        }
        
        // 如果AES解密失败,尝试Base64解码
        try {
            var base64Decoded = ku9.decodeBase64(encryptedData);
            if (base64Decoded && base64Decoded.indexOf('http') === 0) {
                return base64Decoded;
            }
        } catch (e) {
            console.log("Base64解码失败: " + e.message);
        }
        
        // 如果所有解密方法都失败,返回原始数据
        return encryptedData;
        
    } catch (e) {
        console.error('解密过程中出错: ' + e.message);
        return encryptedData;
    }
}

// 生成密钥
function generateKey(dk, xReqTs) {
    var tsStr = Math.floor(xReqTs / 1000).toString();
    return dk.substring(0, 8) + tsStr.substring(tsStr.length - 8);
}

// 生成IV
function generateIv(dk, xReqTs) {
    var tsStr = Math.floor(xReqTs / 1000).toString();
    return dk.substring(dk.length - 8) + tsStr.substring(0, 8);
}   试下我用ai转的看断流吗

2

主题

65

回帖

93

积分

彩电迷

积分
93
 楼主| 发表于 2025-11-5 14:06:44 | 显示全部楼层
lxxcp 发表于 2025-11-4 19:30
function main(item) {
    var id = item.id || 'cctv1';
   

你这个断流,我转化的那个不断流 但是只有CCTV1

点评

我手机使用是正常,电视没试过  发表于 2025-11-5 14:33
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋

创办于 2025 年 5 月 5 日

快速回复 返回顶部 返回列表