diff --git a/src/EngineEntrance.js b/src/EngineEntrance.js index 462dacb..d2bbde3 100644 --- a/src/EngineEntrance.js +++ b/src/EngineEntrance.js @@ -63,7 +63,7 @@ export default class MessageEntrance extends Emiter { super(); this.lastClassActiveTime=0;//最后一次课堂激活的时间戳 //sdk 信息 - GlobalConfig.sdkVersion = "v2.28.1.20171110"; + GlobalConfig.sdkVersion = "v2.28.2.20171111"; loger.warn("sdkVersion:" + GlobalConfig.sdkVersion); console.log("sdkVersion:" + GlobalConfig.sdkVersion); //设置 @@ -594,6 +594,7 @@ export default class MessageEntrance extends Emiter { GlobalConfig.portal = GlobalConfig.replacePort(GlobalConfig.portal, ":80", ""); } + GlobalConfig.paramUserId= _param.userId || "0"; GlobalConfig.userId = "" + _param.userId || "0"; //H5处理 GlobalConfig.isH5 = _param.isH5 || false;//外部传入的参数,是否是H5 @@ -672,7 +673,8 @@ export default class MessageEntrance extends Emiter { GlobalConfig.hasMicrophone = (typeof _param.hasMicrophone == "boolean") ? _param.hasMicrophone : false; //loger.log("autoLoginMd5", GlobalConfig.classId, GlobalConfig.userId, GlobalConfig.userRole); - let autoLoginMd5 = MD5("" + GlobalConfig.classId + GlobalConfig.userId + GlobalConfig.userRole); + let autoLoginMd5 = MD5("" + GlobalConfig.classId + GlobalConfig.paramUserId + GlobalConfig.userRole); + //let autoLoginMd5 = MD5("" + GlobalConfig.classId + GlobalConfig.userId + GlobalConfig.userRole); //loger.log("joinClass-GlobalConfig.autoLogin", GlobalConfig.autoLogin, "autoLoginMd5-", autoLoginMd5); if (GlobalConfig.autoLogin && autoLoginMd5 == GlobalConfig.autoLogin || GlobalConfig.isInvisible) { // MD5(classId+userId+userRole)==m diff --git a/src/GlobalConfig.js b/src/GlobalConfig.js index 3535554..69fc1b9 100644 --- a/src/GlobalConfig.js +++ b/src/GlobalConfig.js @@ -545,6 +545,7 @@ GlobalConfig.returnCitySN = null;//获取的ip数据 {"cip":"60.253.214.122","c GlobalConfig.deviceType = 0; //设备类型 0:电脑 1:ios 2:安卓 GlobalConfig.userIp = ""; //用户当前IP GlobalConfig.userId = 0; +GlobalConfig.paramUserId=0; GlobalConfig.userName = ""; GlobalConfig.handUpTime = 0; GlobalConfig.level = 0; diff --git a/src/RecordInfoMatch.js b/src/RecordInfoMatch.js new file mode 100644 index 0000000..23a366a --- /dev/null +++ b/src/RecordInfoMatch.js @@ -0,0 +1,368 @@ +import Emiter from 'Emiter'; +import MessageTypes from 'MessageTypes'; +import Loger from 'Loger'; + +import MediaModule from "apes/MediaModule"; + +import Base64 from 'base64-js'; +import GlobalConfig from 'GlobalConfig'; +import EngineUtils from 'EngineUtils'; + + +// 日志对象 +const loger = Loger.getLoger('RecordInfoParse'); +class RecordInfoMatch extends Emiter { + constructor() { + super(); + this.recordMessages = {}; + this.jsonPathList = {}; + this.m3u8jsonDataList = {}; + this.streamInfoLen = 0; + this.filePath = ""; + this.matchStreams = {};//记录匹配完成的数据 + this.unMatchStreams = {};//记录匹配完成的数据 + this.unMatchUid = {};//没有匹配到的uid + } + + start() { + let serverIp = GlobalConfig.recordFileSever || "123.56.73.119:8080"; + this.filePath = `${GlobalConfig.locationProtocol + serverIp}`; + this.getRecordInfo(()=> { + let requestLen = Object.keys(this.jsonPathList).length; + let currentLen = 0; + let fileNameArr; + for (let i in this.jsonPathList) { + this.getRecordFileJSON(this.jsonPathList [i], (data)=> { + currentLen++; + console.log(i, "getRecordFileJSON请求返回", currentLen); + if (data) { + for (let k in data) { + let arr = data[k]; + let indexStr = ".m3u8"; + //"694537045_20171103073546522.m3u8" //522.m3u8是需要截取掉的内容 + for (let j of arr) { + if (j && j.indexOf(indexStr) >= 0) { + //console.log("视频地址:"+i+"/"+k+"/"+j); + fileNameArr = j.split("_"); + if (fileNameArr && fileNameArr.length > 0) { + let stream = fileNameArr[1]; + //20171106102811807 -->20171106102811 + stream = stream.substr(0, 14); + if (!this.m3u8jsonDataList[fileNameArr[0]]) { + this.m3u8jsonDataList[fileNameArr[0]] = {} + } + //筛除一些重复流地址,会出现多录制的情况,保留一个即可 + this.m3u8jsonDataList[fileNameArr[0]][stream] = { + video_url: this.filePath + "/" + i + "/" + k + "/" + j, + creatDate: i, + folder: k, + stream: j, + createTimeUTC: stream + }; + } + + } + } + } + } + if (currentLen >= requestLen) { + console.log("视频数据获取完成", this.m3u8jsonDataList); + this.matchRecordFile(this.recordMessages, this.m3u8jsonDataList); + } + }); + } + }); + } + + getRecordInfo(_callback) { + //获取课堂录制信息 get localhost:3000/recordInfo/getRecordInfo/7d72365eb9834353397e3e3f9d460bdda + //localhost:3000/recordInfo/getRecordInfo/ 后面直接添加课堂号 channel + if (!GlobalConfig.getRecordInfoInterfaces) { + loger.log("AG-获取媒体录制信息->失败->接口地址无效"); + if (_callback) { + _callback(); + } + return; + } + let url = `${GlobalConfig.locationProtocol + GlobalConfig.getRecordInfoInterfaces}/${GlobalConfig.channelId}`; + loger.log('AG-获取媒体录制信息.', url); + fetch(url, { + timeout: 15000 + }) + .then(ret => { + if (ret.ok) { + return ret.json(); + } else { + loger.error(`AG-获取媒体录制信息-网络异常.状态码:${ret}`); + if (_callback) { + _callback(); + } + throw ''; + } + }) + .then(ret => { + loger.log('AG-获取媒体录制信息-完成'); + for (let i = 0; i < ret.returnData.data.length; i++) { + let item = ret.returnData.data[i]; + if (item.status == 1) { + this.streamInfoLen++; + //console.log(JSON.stringify(item)); + delete item.appId; + delete item.id; + let time = parseInt(item.createTime); + let timeInfo = this.timestampToUTCTime(time); + //return {yymmddhhmmss:yymmddhhmmss,yymmdd:yymmdd} + item.seek = 0; + item.createTimeUTC = timeInfo.yymmddhhmmss; + item.creatDate = timeInfo.yymmdd; + this.jsonPathList [timeInfo.yymmdd] = this.filePath + "/" + timeInfo.yymmdd + "/json/" + item.channel + ".json"; + item.stream_id = item.channel + "_" + item.userId + "_" + item.timestamp; + + if (!this.recordMessages[item.uid]) { + this.recordMessages[item.uid] = {}; + } + this.recordMessages[item.uid][item.timestamp] = item; + } + } + if (_callback) { + _callback(); + } + }) + .catch(err => { + loger.error(`AG-获取媒体录制信息-异常.状态码:${err}`); + if (_callback) { + _callback(); + } + }); + } + + getRecordFileJSON(path, _callback) { + let url = path + "?t=" + new Date().getTime(); + /* $.ajax( + { + type: "GET", + url: location, + dataType: 'json', + success: function (data) { + console.log("getRecordFileJSON success", data); + if (_callback) { + _callback(data); + } + }, + error: function (data) { + //alert(data.code); + console.log("getRecordFileJSON error", data); + if (_callback) { + _callback(null); + } + } + } + );*/ + fetch(url, { + timeout: 5000, + method: 'GET', + }) + .then(ret => { + if (ret.ok) { + return ret.json(); + } else { + loger.error(`AG-getRecordFileJSON-网络异常.状态码:${ret}`); + if (_callback) { + _callback(); + } + throw ''; + } + }) + .then(ret => { + loger.log('AG-getRecordFileJSON-完成'); + if (_callback) { + _callback(ret); + } + }) + .catch(err => { + loger.error(`AG-getRecordFileJSON-异常.状态码:${err}`); + if (_callback) { + _callback(); + } + }); + } + + matchRecordFile(_messages, _m3u8List) { + let _recordMessages = _messages; + let _m3u8jsonDataList = _m3u8List; + console.log("匹配之前的消息集合", _recordMessages); + console.log("匹配之前的视频地址集合", _m3u8jsonDataList); + let matchStreams = {}; + let uidRecordInfo; + let uidRecordFile; + + for (let k in _recordMessages) { + this.matchForUid(k, _recordMessages[k], _m3u8jsonDataList[k]); + } + + console.log("unMatchUid", this.matchStreams); + console.log("_recordMessages", _recordMessages); + console.log("_m3u8jsonDataList", _m3u8jsonDataList); + console.log("最终匹配完成的数量为->" + Object.keys(this.matchStreams).length, "未匹配成功的数量为->" + (this.streamInfoLen - parseInt(Object.keys(this.matchStreams).length))); + console.log("没有录制文件的用户", this.unMatchUid); + this._emit(RecordInfoMatch.RECORD_INFO_MATCH_COMPLETE, this.matchStreams); + } + + matchForUid(k, _recordMessages, _m3u8jsonDataList) { + let uidRecordInfo = _recordMessages; + let uidRecordFile = _m3u8jsonDataList; + if (!uidRecordFile) { + console.log(k, "没有录制文件"); + this.unMatchUid[k] = uidRecordInfo; + } else { + + let uidRecordInfoArr = Object.values(uidRecordInfo); + let uidRecordFileArr = Object.values(uidRecordFile); + uidRecordInfoArr = uidRecordInfoArr.sort(function (a, b) { + return parseInt(a.createTimeUTC) - parseInt(b.createTimeUTC); + }); + uidRecordFileArr = uidRecordFileArr.sort(function (a, b) { + return parseInt(a.createTimeUTC) - parseInt(b.createTimeUTC); + }); + + if (uidRecordInfoArr.length == uidRecordFileArr.length && uidRecordFileArr.length > 0) { + //1.如果文件数量和消息数量相等,直接关联即可 + console.log(k + "->数量相同->直接匹配", uidRecordInfoArr.length); + for (let h = 0; h < uidRecordInfoArr.length; h++) { + let item = uidRecordInfoArr[h]; + item.video_url = uidRecordFileArr[h].video_url; + this.matchStreams[item.stream_id] = item; + } + + } else { + //2.通过时间戳匹配 + for (let f in uidRecordInfo) { + let time = parseInt(uidRecordInfo[f].createTimeUTC); + let video_url = ""; + let video_urlObj = uidRecordFile[k + "_" + time]; + if (video_urlObj && video_urlObj.video_url) { + video_url = video_urlObj.video_url; + } + //模糊 + if (!video_url) { + video_urlObj = uidRecordFile[k + "_" + (time + 1)]; + if (video_urlObj && video_urlObj.video_url) { + video_url = video_urlObj.video_url; + } + } + if (!video_url) { + video_urlObj = uidRecordFile[k + "_" + (time - 1)]; + if (video_urlObj && video_urlObj.video_url) { + video_url = video_urlObj.video_url; + } + } + + //通过时间戳匹配 结束 + if (video_url) { + let item = uidRecordInfo[f]; + item.video_url = video_url; + this.matchStreams[item.stream_id] = item; + } else { + console.log(k + "_" + time, "按时间戳没有查找到->"); + } + } + + //3.最后一次通过间隔查找 + if (uidRecordInfoArr.length != uidRecordFileArr.length && uidRecordFileArr.length > 0 && uidRecordInfoArr.length > 0) { + console.log(k + "->数量不同 消息数量:" + uidRecordInfoArr.length, "视频数量:" + uidRecordFileArr.length); + //按消息的数量大于视频数量处理 + let lastFileItem;//记录最后一个 + for (let h = 0; h < uidRecordInfoArr.length; h++) { + let infoItem = uidRecordInfoArr[h]; + let fileItem = uidRecordFileArr[h]; + if (fileItem) { + infoItem.video_url = fileItem.video_url; + + //如果之前没有匹配到才设置 + if (!this.matchStreams[infoItem.stream_id]) { + this.matchStreams[infoItem.stream_id] = infoItem; + } + lastFileItem = infoItem;//记录最后一个文件的数据 + } else { + if (lastFileItem) { + infoItem.video_url = lastFileItem.video_url; + infoItem.seek = parseInt(infoItem.createTimeUTC) - parseInt(lastFileItem.createTimeUTC); + if (!this.matchStreams[infoItem.stream_id]) { + this.matchStreams[infoItem.stream_id] = infoItem; + } + } + } + + } + } + + /* + //没有查找到之后,如果两次推流的消息时间过短,只会有一个视频,需要再次匹配 + console.log("uidRecordInfoUnsearch", uidRecordInfoUnsearch, uidRecordInfo); + if (Object.keys(uidRecordInfoUnsearch).length > 0) { + let item; + let item2; + let minInterval = 10000; + let nearItem = null; + for (let s in uidRecordInfoUnsearch) { + item = uidRecordInfoUnsearch[s]; + for (let h in uidRecordInfo) { + item2 = uidRecordInfo[h]; + if (item2 && item2.video_url) { + let interval = parseInt((item.createTime) * 0.001 - parseInt(item2.createTime) * 0.001); + if (minInterval > interval) { + nearItem = item2; + minInterval = interval; + } + minInterval = Math.min(minInterval, interval); + //console.log("两次推流消息的间隔",interval); + } + } + } + if (item && nearItem) { + console.log("查找到最接近的消息", nearItem, "seek", minInterval); + item.video_url = nearItem.video_url; + item.seek = minInterval; + matchStreams[item.stream_id] = item; + } + + }*/ + } + } + + } + + + timestampToUTCTime(_timestamp) { + let date = new Date(_timestamp - 8 * 60 * 60 * 1000);//GMT 转UTC 减8 + let y = "" + date.getFullYear(); + let month = "" + (date.getMonth() + 1); + let d = "" + date.getDate(); + let h = "" + (date.getHours()); + let minutes = "" + date.getMinutes(); + let s = "" + date.getSeconds(); + if (month.length < 2) { + month = "0" + month; + } + if (d.length < 2) { + d = "0" + d; + } + if (h.length < 2) { + h = "0" + h; + } + if (minutes.length < 2) { + minutes = "0" + minutes; + } + if (s.length < 2) { + s = "0" + s; + } + let yymmddhhmmss = "" + y + month + d + h + minutes + s; + let yymmdd = "" + y + month + d; + console.log(_timestamp, yymmdd, yymmddhhmmss, date); + return {yymmddhhmmss: yymmddhhmmss, yymmdd: yymmdd} + } +} + +RecordInfoMatch.prototype.RECORD_INFO_MATCH_COMPLETE = RecordInfoMatch.RECORD_INFO_MATCH_COMPLETE = 'recordInfoMatchComplete';//录制数据匹配完成 +export default new RecordInfoMatch; +