importwin.ui;/*DSG{{*/varwinform = win.form(text="aardio form";right=935;bottom=599)
winform.add(
btnFullScreen={cls="button";text="全屏";left=600;top=552;right=704;bottom=584;db=1;dl=1;z=5};
btnView={cls="button";text="查看";left=456;top=552;right=560;bottom=584;db=1;dl=1;z=1};
custom={cls="custom";text="custom";left=16;top=16;right=921;bottom=525;ah=1;aw=1;z=3};
edUrl={cls="edit";left=104;top=552;right=448;bottom=584;db=1;dl=1;edge=1;multiline=1;z=2};
static={cls="static";text="直播间地址";left=24;top=560;right=104;bottom=584;db=1;dl=1;transparent=1;z=4}
)/*}}*/importthread.commandimporthpsocket.ssl.httpClient;importstring.xml;importstring.html;importweb.json;importweb.kit;importmpvPlayer;importinet.httpvarhttp = inet.http()varenvJs = http.get("https://www.kingkong.com.tw/static/lib/jsrsasign-jwths-min.js")if( !envJs ){
winform.msgboxErr("连接king kong直播平台失败,请重试")return;
}varaddJs =/****
/*
Version: v3.6.1
The MIT License: Copyright (c) 2010-2017 LiosK.
*/
var UUID;
UUID=function(f){function a(){}a.generate=function(){var b=a._getRandomInt,c=a._hexAligner;return c(b(32),8)+"-"+c(b(16),4)+"-"+c(16384|b(12),4)+"-"+c(32768|b(14),4)+"-"+c(b(48),12)};a._getRandomInt=function(b){if(0>b||53>>30-b};a._hexAligner=function(b,c){for(var a=b.toString(16),d=c-a.length,e="0";0>>=1,e+=e)d&1&&(a=e+a);return a};a.overwrittenUUID=f;"undefined"!==typeof module&&module&&module.exports&&(module.exports=a);return a}(UUID);
var _getPFID = function() {
var e = UUID.generate().toString().replace(/\-/g, "");
return e = e.substring(0, e.length)
}
var _getName = function(e) {
var t;
return e && (t = "訪客" + e.toString().substring(e.length - 5, e.length)),t
}
var getToken = function( param ) {
var e = {}
e.live_id = param.liveId
e.pfid = param.pfid || _getPFID()
e.name = param.name || _getName(e.pfid)
e.lv = param.lv || 1
e.from = param.from || 1
e.from_seq = param.fromSeq || 1
e.channel_id = param.channelId || 1
e.client_type = "web"
return KJUR.jws.JWS.sign(null, JSON.stringify({
alg: "HS256",
typ: "JWT"
}), JSON.stringify(e), param.liveKey)
}
****/varwke = web.kit.view()
wke.doScript( envJs )
wke.doScript( addJs )varhttpClient = hpsocket.ssl.httpClient()varmpv = mpvPlayer( winform.custom )varmpvOption = {
["osd-font-size"] = 35;// 字体大小["osd-spacing"] = 2;// 字体间距["osd-align-x"] ="center";// 显示位置["osd-align-y"] ="bottom";
["osd-back-color"] ="#171111";// 背景颜色}for(k,vinmpvOption){
mpv.setOption(k,v)
}varthCmd = thread.command()
thCmd.onChat =function(name, msg){
mpv.setOption("osd-msg1", name ++":"++ msg );
}vartmId;varkeepLive =function(){if( tmId ){
winform.killtimer(tmId)
}
tmId = winform.addtimer(
30000,function(hwnd,msg,id,tick){
httpClient.sendWsMessage("2")
}
)
}
thCmd.keepLive =function(){
keepLive()
}
httpClient.onUpgrade =function(hpHttpClient,connId,upgradeType){if(upgradeType!=1)return-1;if( ! hpHttpClient.checkWsUpgradeResponse() )return-1;
}
httpClient.onWsMessageHeader =function(hpHttpClient,connId,final,reserved,opCode,mask,bodyLen){
hpHttpClient.reallocString(bodyLen);
}
httpClient.onWsMessageBody =function(hpHttpClient,connId,pData,len){
hpHttpClient.appendString(pData,len);
}
httpClient.onWsMessageComplete =function(hpHttpClient){importthread.command;importweb.json;vardata = hpHttpClient.getString();if( data ){varmsgType, msg = string.match( data,"(.+?)\,(.+?)$")if( msgType ==="42/chat_nsp"){varret = web.json.parse(msg)if( ret[1] =="msg"){
thread.command.post("onChat", ret[2].name, ret[2].msg)
}
}elseif( string.indexOf(data,"pingInterval") ){
thread.command.post("keepLive")
}
}
}
httpClient.onHandShake =function(hpHttpClient,connId){// 必须先从内存取出绑定的认证数据,因为 sendWsUpgradeRequest 会刷新内存varauthData = hpHttpClient.getString()// 发送升级包hpHttpClient.sendWsUpgradeRequest("/chat_nsp/?EIO=3&transport=websocket");
hpHttpClient.sendWsMessage("40/chat_nsp,")// 发送认证hpHttpClient.sendWsMessage(authData)
}
httpClient.onClose =function(hpHttpClient,connId,enOperation,errCode){
hpHttpClient.reallocString(0);
}vargetRooomInfo =function(url){importinet.httpimportstring.xml;importstring.html;importweb.json;varhttp = inet.http()varurl = string.match(url,"(\d+)")if( !url ){returnnull,"不是金刚直播的url";
}varhtml = http.get( url )if!htmlreturnnull,"网络出错请重试";varxml = string.xml(html)varele = xml.queryEle( ["class"]="view view-live")if!elereturnnull,"找不到ele";varroomInfo = ele["data-roomInfo"]if!roomInforeturnnull,"找不到roomInfo";varjson = string.html.toText(roomInfo)varret = web.json.parse(json)returnret, json;
}vargetToken =function(json){returnwke.eval(`getToken( JSON.parse( '`++ json ++`') )`)
}varview =function( url ){if( !#url ){returnnull,"直播间地址不能为空";
}varret, json = win.invoke(getRooomInfo,url)if( !ret ){returnnull, json;
}vartoken = getToken(json)if( !token ){returnnull,"数据解析出错,网站可能已经更新";
}
httpClient.stop()
httpClient.sslCleanup()if( !httpClient.sslSetupContext(0) ){returnnull,"初始化SSL环境失败";
}if( !httpClient.start("cht.ws.kingkong.com.tw",443,false) ){returnnull,"连接弹幕服务器失败";
}// 绑定认证数据vardata ="42/chat_nsp,"++ web.json.stringify({"authentication";{
anchor_pfid = ret.pfid;
client_type ="web";
live_id = ret.liveId;
token = token;}})
httpClient.reallocString(1)
httpClient.appendString( data )
winform.text = ret.name ++":"++ ret.roomTitle
mpv.command("loadfile", ret.videos[1].url )returntrue;
}
winform.btnView.oncommand =function(id,event){owner.disabled =truevarurl = winform.edUrl.text;varok, err = view(url)if( !ok ){
winform.msgboxErr(err )
}owner.disabled =false}
winform.btnFullScreen.oncommand =function(id,event){
winform.custom.fullscreen(true)
}importwin.ui.accelerator
win.ui.accelerator({
{ vkey =0x1B/*_VK_ESC*/;oncommand =function(id,event) winform.custom.fullscreen(false) }
{ vkey =0x7A/*_VK_F11*/; oncommand =function(id,event) winform.custom.fullscreen() }
},winform);
winform.show()
win.loopMessage();