self.importScripts('common.js'); var receiveVideoUrl = '' var firstRequestWs= 1 Uint8Array.prototype.concat = function(old,addInt8Arrays){ var arrInt1 = Array.from(old) var arrInt2 = Array.from(addInt8Arrays) var last = arrInt1.concat(arrInt2) var arrUint8 = new Uint8Array(last) return arrUint8 } function Downloader() { this.logger = new Logger("Downloader"); this.isChonglian = true; this.fetchFirst = true; this.comein = true; this.downloadNum = {};//定义对象存放建立的链接 for(let num =1; num <17; num++){ this.downloadNum["malv" + num] = 0 this.downloadNum["ismalvtimeInter" + num] = true this.downloadNum["controller" + num] = '' this.downloadNum["recordVideoData" + num] = new Uint8Array(0) this.downloadNum["chushihua" + num] = true } } Downloader.prototype.getFileInfo = function (url,num) { this.logger.logInfo("Getting file size " + url + "."); var objData = { t: kGetFileInfoRsp, i: { sz: 20<<20, st: 200 }, num:num }; self.postMessage(objData); }; Downloader.prototype.sendDataws = function(read,start, end, seq,num,status,showName,rongqiId,getUrl,devCode){ if(read == ""){ }else{ this.reader = read } var that = this this.reader.read().then(function processData({done, value}) {         if (done) { console.log('liu结束') var objData = { t: kliuover, num:num, rongqiId:rongqiId, devCode:devCode }; self.postMessage(objData); }else{ if(value.byteLength){ that.downloadNum["malv" + num] += value.byteLength if(that.downloadNum["ismalvtimeInter" + num]){ that.downloadNum["ismalvtimeInter" + num] = false that.downloadNum["malv" + num] = 0 let tt = setTimeout(function(){ that.downloadNum["ismalvtimeInter" + num] = true var objData = { t: 6, num:num, rongqiId:rongqiId, malv:that.downloadNum["malv" + num], }; self.postMessage(objData); clearTimeout(tt) },2000) } var objData = { t: kFileData, s: start, e: start+value.byteLength, d:  value.buffer, q: seq, num:num, status:status, showName:showName, downloadData:that.downloadNum["recordVideoData" + num], chushihua:that.downloadNum["chushihua" + num], rongqiId:rongqiId, malv:that.downloadNum["malv" + num], ismalv:that.downloadNum["ismalvtimeInter" + num], devCode:devCode }; if(status === "1"){ var incomingData = new Uint8Array(objData.d); // create a uint8 view on the ArrayBuffer that.downloadNum["recordVideoData" + num] = that.downloadNum["recordVideoData" + num].concat(that.downloadNum["recordVideoData" + num],incomingData) } self.postMessage(objData, [objData.d]); if(status === "2"){ if(that.downloadNum["recordVideoData" + num].byteLength !== 0){ that.downloadNum["recordVideoData" + num] = new Uint8Array(0) } } that.downloadNum["chushihua" + num] = false } } }) } var totalLength = 0; Downloader.prototype.sendData = function(read,start, end, seq,num,status,showName,rongqiId,getUrl,devCode){ if(read == ""){ }else{ this.reader = read } var that = this this.reader.read().then(function processData({done, value}) {         if (done) {            console.log("Stream done."); var objData = { t: kliuover, num:num, rongqiId:rongqiId, devCode:devCode }; self.postMessage(objData);         } if(value.byteLength){ that.downloadNum["malv" + num] += value.byteLength if(that.downloadNum["ismalvtimeInter" + num]){ that.downloadNum["ismalvtimeInter" + num] = false that.downloadNum["malv" + num] = 0 let tt = setTimeout(function(){ that.downloadNum["ismalvtimeInter" + num] = true var objData = { t: 6, num:num, rongqiId:rongqiId, malv:that.downloadNum["malv" + num], }; self.postMessage(objData); clearTimeout(tt) },2000) } var objData = { t: kFileData, s: start, e: start+value.byteLength, d:  value.buffer, q: seq, num:num, status:status, showName:showName, downloadData:that.downloadNum["recordVideoData" + num], chushihua:that.downloadNum["chushihua" + num], rongqiId:rongqiId, malv:that.downloadNum["malv" + num], ismalv:that.downloadNum["ismalvtimeInter" + num], devCode:devCode }; if(status === "1"){ var incomingData = new Uint8Array(objData.d); // create a uint8 view on the ArrayBuffer that.downloadNum["recordVideoData" + num] = that.downloadNum["recordVideoData" + num].concat(that.downloadNum["recordVideoData" + num],incomingData) } self.postMessage(objData, [objData.d]); if(status === "2"){ if(that.downloadNum["recordVideoData" + num].byteLength !== 0){ that.downloadNum["recordVideoData" + num] = new Uint8Array(0) } } that.downloadNum["chushihua" + num] = false } }); } function iserror (num,rongqiId,Sguvp_errorcode,Sguvp_errordesc,devCode){ console.log("进入错误提示") var errrorJSON = { 401:"登录失败,请重新登录", 500:"服务内部错误(设备类)", 503: "超过服务处理能力(设备类)", 531: "消息格式错误(设备类)", 532: "还有其他客户端在看此路视频(设备类)", 533: "设备(含摄像机/dvr/nvr)未加载到程序中或设备不存在或设备未登陆(设备类)", 534: "设备不支持此接口(设备类)", 535: "设备登陆失败,请检查IP,端口号和登录名密码(设备类)", 536: "设备连接失败,请检查网络情况和设备配置情况(设备类)", 537: "RTP失败(设备类)", 538: "SPS失败(设备类)", 539: "RTCP超时(设备类)", 540: "SDK执行失败,请检查PTS配置(设备类)", 541: "不支持此方法(设备类)", 542: "未定义的设备错误(设备类)", 551: "SIP服务器内部错误(设备类)", 552: "SIP协商有问题(设备类)", 553: "SIP不支持的请求类型(设备类)", 554: "SIP未找到请求项(设备类)", 555: "SIP消息格式错误(设备类)", 556: "SIP忙(设备类)", 557: "SIP未知错误(设备类)", 571: "RTSP错误的请求(设备类)", 572: "RTSP不支持的请求类型(设备类)", 573: "RTSP不允许该方法(设备类)", 574: "RTSP的Session不匹配(设备类)", 575: "RTSP超时(设备类)", 576: "RTSP的报文太大(设备类)", 577: "RTSP的URI太长(设备类)", 578: "RTSP的媒体类型不支持(设备类)", 579: "RTSP不理解此参数(设备类)", 580: "RTSP没找到Session(设备类)", 581: "RTSP此方法和当前状态不匹配(设备类)", 582: "RTSP的Range字段不争取(设备类)", 583: "RTSP传输方式不支持(设备类)", 584: "RTSP当前负荷满(设备类)", 585: "RTSP不支持此版本(设备类)", 586: "RTSP响应超时(设备类)", 587: "RTSP解析失败(设备类)", 588: "RTSP发送失败(设备类)", 589: "RTSP当前内部错误(设备类)", 621: "流媒体不在线(平台类)", 622: "视频打开超时(设备类)", 626: "当前服务端资源不足,请稍后再尝试。(平台类)", 627: "管理员禁止(平台类)", 629: "设备故障,前端未注册(设备类)", 641: "前端不在线(设备类)", 642: "前端响应超时(设备类)", 715: "录像回放建立失败(设备类)", 901: "视频请求信令发送失败(设备类)", 902: "视频播放URL错误(平台类)", 903: "视频播放格式错误(平台类)", 904: "转码服务未收到视频数据(设备类)", 905: "请求HTTP视频流应答失败(平台类)", 906: "分配UDP端口失败(平台类)", 907: "绑定UDP端口失败(平台类)", 908: "视频请求返回的IP为空(平台类)", 909: "视频请求返回的端口为空(平台类)", 910: "语音对讲建立TCP链接失败(平台类)", 911: "不支持的非标码流格式,请用OCX播放", 801:"对侧平台视频调阅数(所有人)达到上限,关闭其他视频再操作" }; var errrorArray = [] for (let i in errrorJSON){ errrorArray.push(i) if(Sguvp_errorcode && Sguvp_errorcode == i){ var objData = { t: kErrorTip, num:num, errorDes:errrorJSON[i], errorCode:Sguvp_errorcode, rongqiId:rongqiId, devCode:devCode }; self.postMessage(objData); } } if(errrorArray.indexOf(Sguvp_errorcode) < 0 ){ if(Sguvp_errordesc){ }else{ Sguvp_errordesc = `设备故障,请联系设备厂商做进一步处理 (${Sguvp_errorcode})` } var objData = { t: kErrorTip, num:num, errorDes:Sguvp_errordesc, errorCode:Sguvp_errorcode, rongqiId:rongqiId, devCode:devCode }; self.postMessage(objData); } } Downloader.prototype.downloadFile = function (getUrl, start, end, seq,num,luzhistatus,showName,rongqiId,devCode) { var _this = this downloadFileFuc(getUrl, start, end, seq,num,luzhistatus,showName,rongqiId,devCode,_this) }; function downloadFileFuc (getUrl, start, end, seq,num,luzhistatus,showName,rongqiId,devCode,_this){ var that = _this; if(that.fetchFirst){ that.firstArgs = [...arguments] } var ishttp = getUrl.indexOf('ws://') < 0 if (ishttp) { if(that.fetchFirst){ that.fetchFirst = false; receiveVideoUrl = 'http://' that.downloadNum["controller" + num] = new AbortController(); var signal = that.downloadNum["controller" + num].signal; // var index = getUrl.indexOf("&num=") // getUrl = getUrl.slice(0,index) console.log("开始建立fetch连接") fetch(getUrl,{signal}).then( function respond(response) { console.log("是否返回错误码:",response.headers.has("Sguvp_errorcode")) // console.log(response.headers) // response.headers.forEach((v,k) =>{ // console.log(k,":",v) // }) if(response.headers.has("Sguvp_errorcode")){ var Sguvp_errorcode = response.headers.get("Sguvp_errorcode") var Sguvp_errordesc = response.headers.get("Sguvp_errordesc") console.log("进入错误提示") var errrorJSON = window.top.__errorList || { 401:"登录失败,请重新登录", 500:"服务内部错误(设备类)", 503: "超过服务处理能力(设备类)", 531: "消息格式错误(设备类)", 532: "还有其他客户端在看此路视频(设备类)", 533: "设备(含摄像机/dvr/nvr)未加载到程序中或设备不存在或设备未登陆(设备类)", 534: "设备不支持此接口(设备类)", 535: "设备登陆失败,请检查IP,端口号和登录名密码(设备类)", 536: "设备连接失败,请检查网络情况和设备配置情况(设备类)", 537: "RTP失败(设备类)", 538: "SPS失败(设备类)", 539: "RTCP超时(设备类)", 540: "SDK执行失败,请检查PTS配置(设备类)", 541: "不支持此方法(设备类)", 542: "未定义的设备错误(设备类)", 551: "SIP服务器内部错误(设备类)", 552: "SIP协商有问题(设备类)", 553: "SIP不支持的请求类型(设备类)", 554: "SIP未找到请求项(设备类)", 555: "SIP消息格式错误(设备类)", 556: "SIP忙(设备类)", 557: "SIP未知错误(设备类)", 571: "RTSP错误的请求(设备类)", 572: "RTSP不支持的请求类型(设备类)", 573: "RTSP不允许该方法(设备类)", 574: "RTSP的Session不匹配(设备类)", 575: "RTSP超时(设备类)", 576: "RTSP的报文太大(设备类)", 577: "RTSP的URI太长(设备类)", 578: "RTSP的媒体类型不支持(设备类)", 579: "RTSP不理解此参数(设备类)", 580: "RTSP没找到Session(设备类)", 581: "RTSP此方法和当前状态不匹配(设备类)", 582: "RTSP的Range字段不争取(设备类)", 583: "RTSP传输方式不支持(设备类)", 584: "RTSP当前负荷满(设备类)", 585: "RTSP不支持此版本(设备类)", 586: "RTSP响应超时(设备类)", 587: "RTSP解析失败(设备类)", 588: "RTSP发送失败(设备类)", 589: "RTSP当前内部错误(设备类)", 621: "流媒体不在线(平台类)", 622: "视频打开超时(设备类)", 626: "当前服务端资源不足,请稍后再尝试。(平台类)", 627: "管理员禁止(平台类)", 629: "设备故障,前端未注册(设备类)", 641: "前端不在线(设备类)", 642: "前端响应超时(设备类)", 715: "录像回放建立失败(设备类)", 901: "视频请求信令发送失败(设备类)", 902: "视频播放URL错误(平台类)", 903: "视频播放格式错误(平台类)", 904: "转码服务未收到视频数据(设备类)", 905: "请求HTTP视频流应答失败(平台类)", 906: "分配UDP端口失败(平台类)", 907: "绑定UDP端口失败(平台类)", 908: "视频请求返回的IP为空(平台类)", 909: "视频请求返回的端口为空(平台类)", 910: "语音对讲建立TCP链接失败(平台类)", 911: "不支持的非标码流格式,请用OCX播放", 801:"对侧平台视频调阅数(所有人)达到上限,关闭其他视频再操作" }; var errrorArray = [] for (let i in errrorJSON){ errrorArray.push(i) if(Sguvp_errorcode && Sguvp_errorcode == i){ var objData = { t: kErrorTip, num:num, errorDes:errrorJSON[i], errorCode:Sguvp_errorcode, rongqiId:rongqiId, devCode:devCode }; self.postMessage(objData); } } if(errrorArray.indexOf(Sguvp_errorcode) < 0 ){ if(Sguvp_errordesc){ }else{ Sguvp_errordesc = `设备故障,请联系设备厂商做进一步处理 (${Sguvp_errorcode})` } var objData = { t: kErrorTip, num:num, errorDes:Sguvp_errordesc, errorCode:Sguvp_errorcode, rongqiId:rongqiId, devCode:devCode }; self.postMessage(objData); } }else{ console.log("进入读取流") that.sendData(response.body.getReader(),start, end, seq,num,luzhistatus,showName,rongqiId,getUrl,devCode); } } ).catch( err => { console.log("",err) // var objData = { // t: kErrorTip, // num:num, // errorDes:'网络不通', // rongqiId:rongqiId // }; // self.postMessage(objData); } ); }else{ that.sendData('',start, end, seq,num,luzhistatus,showName,rongqiId,getUrl,devCode) } }else{//如果是ws receiveVideoUrl = 'ws://' if(that.fetchFirst){ that.fetchFirst = false; that.downloadNum["controller" + num] = new WebSocket(getUrl); that.downloadNum["controller" + num].onopen = function(e) { console.log("open ws") }; that.downloadNum["controller" + num].onmessage = function (evt) { if(that.comein){ that.comein = false if(typeof evt.data == 'string'){ iserror(num,rongqiId,JSON.parse(evt.data).resultCode,JSON.parse(evt.data).resultHint) }else{ that.sendDataws(evt.data.stream().getReader(),start, end, seq,num,luzhistatus,showName,rongqiId,getUrl,devCode); } } } }else{ that.downloadNum["controller" + num].onmessage= function (evt) { if(typeof evt.data == 'string'){ iserror(num,rongqiId,JSON.parse(evt.data).resultCode,JSON.parse(evt.data).resultHint) }else{ that.sendDataws(evt.data.stream().getReader(),start, end, seq,num,luzhistatus,showName,rongqiId,getUrl,devCode); } } } } } Downloader.prototype.stopStream = function(num){ if(receiveVideoUrl == "ws://"){ if(this.downloadNum["controller" + num]){ this.downloadNum["controller" + num].onclose = function(){ console.log('ws已经关闭完成'); this.downloadNum["controller" + num] = ""; } console.log('进入开始关闭websocket') this.downloadNum["controller" + num].close(); this.downloadNum["controller" + num] = ""; } }else{ if(this.downloadNum["controller" + num]){ this.downloadNum["controller" + num].abort(); this.downloadNum["controller" + num] = ""; } } self.close() } self.downloader = new Downloader(); self.onmessage = function (evt) { if (!self.downloader) { console.log("[ER] Downloader not initialized!"); return; } var objData = evt.data; switch (objData.t) { case kGetFileInfoReq: self.downloader.getFileInfo(objData.u,objData.num); break; case kDownloadFileReq: self.downloader.downloadFile(objData.u, objData.s, objData.e, objData.q, objData.num,objData.luzhistatus,objData.showName,objData.rongqiId,objData.devCode); break; case kCloseDownloaderReq: self.downloader.stopStream(objData.num) break; default: self.downloader.logger.logError("Unsupport messsage " + objData.t); } };