腾讯体育直播和之前调试过的央视频一样用的 txvlive.js,主要是找 cKey 参数,而且更简洁明了。
打开一个直播间后刷新,比如https://sports.qq.com/kbsweb/game.htm?mid=100702:1200595在加载过程中找到如下请求的响应内容中有 playurl: "https://8abb84751ce8f955cc2d9807e474ff42.v.smtcdns.net:443/txycdn.video.qq.com/xxx/1333509601.m3u8?from=player&cdncode=%2f18907E7BE0798990%2f&time=1621669233&cdn=tcloud&sdtfrom=v26902212&platform=40201&butype=2&scheduleflag=0&HLSP2P=1&buname=qqlive&vkey=xxx&drmtype=0" ,而且能长时间正常播放。其中 cnlid 来自 https://matchweb.sports.qq.com/kbs/matchDetail?mid=100702:1200595&callback=fetchMatchDetailCallback0 响应中的 liveId、 livepid是programId、fntick和tm是10位时间戳,cKey 需计算得出,其他大部分参数固定。
请求地址:https://infozb6.video.qq.com/
请求参数:cmd: 2
cnlid: 1333509600
pla: 0
stream: 2
system: 0
appVer: 3.0.0.138
encryptVer: 7.6
qq: 0
device: PC
guid: f56776a1fa52e9c8c4987bfecfbf0503
defn: shd
host: qq.com
livepid: 114693
logintype: 1
vip_status: 1
livequeue: 1
fntick: 1621669031
tm: 1621669031
sdtfrom: 1107
platform: 40201
cKey: 229538382d5b98c82191af006eef53ad
queueStatus: 0
sphttps: 1
authext: {}
auth_ext: {}
auth_from: 40001
callback: txvlive_videoinfoget_1803466280
直接搜 cKey 可以在 txvlive.js 中找到相关代码如下,一眼看到几个参数来源,(new Date).getDay() 获取当天星期几,前面拼接 “7.0” 即参数 m 和 encryptVer;cKey 由函数 g = r.$xx(f, p, h, 1, v, m) 生成,传入参数中有 encryptVer,而 o.$xx 中又用 substr() 方法抽取了最后一位,即每周星期几就赋值给参数 s 对应的字符串常量。o.ha(s + e + r + "*#06#" + t) 这里拼接其他几个字符串后传入 o.ha,而 o.ha 方法明显是个 MD5 函数。
{
key: "getLiveVideoUrl",
value: function (t, e, n, o, i) {
var f = t.platform,
p = t.vid,
d = t.defn || "",
h = u(f),
v = a.getTimeStampStr({
time: this.svrtick
}),
//当天星期几
y = (new Date).getDay(),
m = "7." + (0 == y ? 7 : y),
g = "";
try {
g = r.$xx(f, p, h, 1, v, m)
} catch (w) {}
var _ = this;
!function (r, u) {
//请求参数
var y = {
cmd: 2,
cnlid: p,
pla: 0,
stream: 2,
system: l(),
appVer: TxvLive.pubConfig.version,
encryptVer: m,
qq: a.getUin() || 0,
device: "PC",
guid: encodeURIComponent(t.guid),
defn: d,
host: a.url.getHost(),
livepid: t.livepid || "",
logintype: 1,
vip_status: 1,
livequeue: 1,
fntick: v,
tm: v,
sdtfrom: h,
platform: f,
cKey: g,
queueStatus: _.prevLiveData ? _.prevLiveData.queue_status : 0
};
//生成cKey的函数
o.$xx = function (t, e, n, i, r, a) {
var s = "123456";
if (a.length < 3)
return "err";
if ("7." != a.substr(0, 2))
return "err";
var c = a.substr(2);
//参数s根据星期赋值
"1" == c && (s = "06fc1464"),
"2" == c && (s = "4244ce1b"),
"3" == c && (s = "77de31c5"),
"4" == c && (s = "e0149fa2"),
"5" == c && (s = "60394ced"),
"6" == c && (s = "2da639f0"),
"7" == c && (s = "c2f0cf9f");
var r = r || parseInt(+new Date / 1e3),
i = ("" + i).charAt(0);
return o.ha(s + e + r + "*#06#" + t)
}
//o.ha是个MD5加密
o.ha = function (t) {
function e(t, e) {
return ((t >> 1) + (e >> 1) << 1) + (1 & t) + (1 & e)
}
for (var n = [], o = 0; o < 64; )
n[o] = 0 | 4294967296 * Math.abs(Math.sin(++o));
return function (t) {
for (var o = void 0, i = void 0, r = void 0, a = void 0, s = [], c = unescape(encodeURI(t)), l = c.length, u = [o = 1732584193, i = -271733879, ~o, ~i], f = 0; f <= l; )
s[f >> 2] |= (c.charCodeAt(f) || 128) << f++ % 4 * 8;
for (s[t = 16 * (l + 8 >> 6) + 14] = 8 * l,
f = 0; f < t; f += 16) {
for (l = u,
a = 0; a < 64; )
l = [r = l[3], e(o = l[1], (r = e(e(l[0], [o & (i = l[2]) | ~o & r, r & o | ~r & i, o ^ i ^ r, i ^ (o | ~r)][l = a >> 4]), e(n[a], s[[a, 5 * a + 1, 3 * a + 5, 7 * a][l] % 16 + f]))) << (l = [7, 12, 17, 22, 5, 9, 14, 20, 4, 11, 16, 23, 6, 10, 15, 21][4 * l + a++ % 4]) | r >>> 32 - l), o, i];
for (a = 4; a; )
u[--a] = e(u[a], l[a])
}
for (t = ""; a < 32; )
t += (u[a >> 3] >> 4 * (1 ^ 7 & a++) & 15).toString(16);
return t
}
}(),
最后总结下:
1、Python 代码实现还是放在 GitHub:real-url/kbs.py
2、每个直播间的 mid 不一样,作为传参。
3、目前只调试了可免费观看的直播间,VIP 直播间可能要带 cookie。
4、请求参数中的 defn 是清晰度,其值分别为:蓝光fhd、超清shd、高清hd、标清sd,未登陆时最高获取超清,蓝光需VIP。
大佬,虎牙的一起看又升级加密了,能否麻烦抽空破解下呢