李勇

修复录制回放消息和视频文件对应的问题;在多个消息对应一个视频的时候,原有的规则是第一个消息直接对应视频问题,这个存在一个问题,有可能第一个消息没有视频文件生成,…

…第二个消息才是正真对应视频数据的,需要判断消息和视频文件生成时间的间隔,第一个消息和视频文件的间隔大于30秒以上就不能做直接对应
@@ -63,7 +63,7 @@ export default class MessageEntrance extends Emiter { @@ -63,7 +63,7 @@ export default class MessageEntrance extends Emiter {
63 super(); 63 super();
64 this.lastClassActiveTime=0;//最后一次课堂激活的时间戳 64 this.lastClassActiveTime=0;//最后一次课堂激活的时间戳
65 //sdk 信息 65 //sdk 信息
66 - GlobalConfig.sdkVersion = "v2.38.11.20171214"; 66 + GlobalConfig.sdkVersion = "v2.38.13.20171216";
67 loger.warn("sdkVersion:" + GlobalConfig.sdkVersion); 67 loger.warn("sdkVersion:" + GlobalConfig.sdkVersion);
68 console.log("sdkVersion:" + GlobalConfig.sdkVersion); 68 console.log("sdkVersion:" + GlobalConfig.sdkVersion);
69 //设置 69 //设置
@@ -250,7 +250,9 @@ class RecordInfoMatch extends Emiter { @@ -250,7 +250,9 @@ class RecordInfoMatch extends Emiter {
250 console.log("_recordMessages", _recordMessages); 250 console.log("_recordMessages", _recordMessages);
251 console.log("_m3u8jsonDataList", _m3u8jsonDataList); 251 console.log("_m3u8jsonDataList", _m3u8jsonDataList);
252 console.log("最终匹配完成的数量为->" + Object.keys(this.matchStreams).length); 252 console.log("最终匹配完成的数量为->" + Object.keys(this.matchStreams).length);
253 - console.error("没有录制文件的用户", this.unMatchUid); 253 + if(Object.keys(this.unMatchUid).length>0){
  254 + console.error("没有录制文件的用户", this.unMatchUid);
  255 + }
254 this._emit(RecordInfoMatch.RECORD_INFO_MATCH_COMPLETE, this.matchStreams); 256 this._emit(RecordInfoMatch.RECORD_INFO_MATCH_COMPLETE, this.matchStreams);
255 } 257 }
256 258
@@ -274,9 +276,12 @@ class RecordInfoMatch extends Emiter { @@ -274,9 +276,12 @@ class RecordInfoMatch extends Emiter {
274 276
275 if (uidRecordInfoArr.length == uidRecordFileArr.length && uidRecordFileArr.length > 0) { 277 if (uidRecordInfoArr.length == uidRecordFileArr.length && uidRecordFileArr.length > 0) {
276 //1.如果文件数量和消息数量相等,直接关联即可 278 //1.如果文件数量和消息数量相等,直接关联即可
277 - console.log(k + "->数量相同->直接匹配", uidRecordInfoArr.length); 279 + console.log(k + "->数量相同->直接匹配->数量:", uidRecordInfoArr.length);
278 for (let h = 0; h < uidRecordInfoArr.length; h++) { 280 for (let h = 0; h < uidRecordInfoArr.length; h++) {
279 let item = uidRecordInfoArr[h]; 281 let item = uidRecordInfoArr[h];
  282 + let interval=this.utcdateToTimestamp(uidRecordFileArr[h].creatTimeUTC)-this.utcdateToTimestamp(item.creatTimeUTC);
  283 + interval=parseInt(interval/1000);
  284 + console.log("数量相同->直接匹配->间隔->视频文件时间-视频消息时间=",interval);
280 item.video_url = uidRecordFileArr[h].video_url; 285 item.video_url = uidRecordFileArr[h].video_url;
281 this.matchStreams[item.stream_id] = item; 286 this.matchStreams[item.stream_id] = item;
282 } 287 }
@@ -319,11 +324,20 @@ class RecordInfoMatch extends Emiter { @@ -319,11 +324,20 @@ class RecordInfoMatch extends Emiter {
319 console.log(k + "->数量不同 消息数量:" + uidRecordInfoArr.length, "视频数量:" + uidRecordFileArr.length); 324 console.log(k + "->数量不同 消息数量:" + uidRecordInfoArr.length, "视频数量:" + uidRecordFileArr.length);
320 //按消息的数量大于视频数量处理 325 //按消息的数量大于视频数量处理
321 let lastVideoFileItem;//记录最后一个 326 let lastVideoFileItem;//记录最后一个
  327 + let messageAndFileInterval=0;//默认为录制消息和录制视频生成的时间戳差距为0,实际情况为视频生成的时间戳要晚于消息的时间戳
322 for (let s = 0; s < uidRecordInfoArr.length; s++) { 328 for (let s = 0; s < uidRecordInfoArr.length; s++) {
  329 + console.log("开始查找->",s,uidRecordInfoArr);
323 if(s==0){ 330 if(s==0){
324 let infoItem = uidRecordInfoArr[s]; 331 let infoItem = uidRecordInfoArr[s];
325 let videoFileItem = uidRecordFileArr[s]; 332 let videoFileItem = uidRecordFileArr[s];
326 infoItem.video_url = videoFileItem.video_url; 333 infoItem.video_url = videoFileItem.video_url;
  334 + let interval=this.utcdateToTimestamp(videoFileItem.creatTimeUTC)-this.utcdateToTimestamp(infoItem.creatTimeUTC);
  335 + interval=parseInt(interval/1000);
  336 + //第一个视频消息和第一个生成的视频文件时间不能超过40秒,超过30秒就是没有生成视频文件
  337 + if(Math.abs(interval)<40){
  338 + messageAndFileInterval=interval;//记录第一个视频文件和消息的间隔,后面的文件都需要减去这个间隔
  339 + }
  340 + console.log("数量不同->间隔->视频文件时间-视频消息时间=",interval);
327 //如果之前没有匹配到才设置 341 //如果之前没有匹配到才设置
328 if (!this.matchStreams[infoItem.stream_id]) { 342 if (!this.matchStreams[infoItem.stream_id]) {
329 this.matchStreams[infoItem.stream_id] = infoItem; 343 this.matchStreams[infoItem.stream_id] = infoItem;
@@ -331,11 +345,10 @@ class RecordInfoMatch extends Emiter { @@ -331,11 +345,10 @@ class RecordInfoMatch extends Emiter {
331 }else { 345 }else {
332 let infoItem = JSON.stringify(uidRecordInfoArr[s]); 346 let infoItem = JSON.stringify(uidRecordInfoArr[s]);
333 infoItem=JSON.parse(infoItem); 347 infoItem=JSON.parse(infoItem);
334 - console.log("查找->",s,uidRecordInfoArr);  
335 let videoFileItem=this.getNearestTimeData(infoItem.creatTimeUTC,uidRecordFileArr); 348 let videoFileItem=this.getNearestTimeData(infoItem.creatTimeUTC,uidRecordFileArr);
336 if(videoFileItem){ 349 if(videoFileItem){
337 infoItem.video_url = videoFileItem.video_url; 350 infoItem.video_url = videoFileItem.video_url;
338 - infoItem.seek=videoFileItem.seek; 351 + infoItem.seek=parseInt(videoFileItem.seek+messageAndFileInterval);//减去视频和录制消息生成的间隔
339 //如果之前没有匹配到才设置 352 //如果之前没有匹配到才设置
340 if (!this.matchStreams[infoItem.stream_id]) { 353 if (!this.matchStreams[infoItem.stream_id]) {
341 this.matchStreams[infoItem.stream_id] = infoItem; 354 this.matchStreams[infoItem.stream_id] = infoItem;
@@ -371,9 +384,86 @@ class RecordInfoMatch extends Emiter { @@ -371,9 +384,86 @@ class RecordInfoMatch extends Emiter {
371 * 根据时间获取间隔最短的的数据 384 * 根据时间获取间隔最短的的数据
372 * */ 385 * */
373 getNearestTimeData(time,videoArr){ 386 getNearestTimeData(time,videoArr){
374 - let _time=parseInt(time);  
375 - let _nearstTimeDistance=100000;//默认设置为一个超长的值  
376 - let nearstTimeItem=null; 387 + let _time=parseInt(time);
  388 + let _nearstTimeDistance=100000;//默认设置为一个超长的值
  389 + let nearstTimeItem=null;
  390 + for(let k=0;k<videoArr.length;k++){
  391 + //计算最近时间
  392 + let interval=this.utcdateToTimestamp(_time)-this.utcdateToTimestamp(videoArr[k].creatTimeUTC);
  393 + interval=parseInt(interval/1000);
  394 + console.log("getNearestTimeData-视频消息和视频文件时间差->",interval);
  395 + if(interval>-12&&interval<_nearstTimeDistance){
  396 + //记录时间点最接近
  397 + nearstTimeItem=videoArr[k];
  398 + //nearstTimeItem.seek=interval;
  399 + _nearstTimeDistance=Math.abs(interval);
  400 + }
  401 + }
  402 +
  403 + let itemJson="";
  404 + if(nearstTimeItem){
  405 + itemJson=JSON.stringify(nearstTimeItem);
  406 + let finelItem=JSON.parse(itemJson);
  407 + finelItem.seek=parseInt((this.utcdateToTimestamp(_time)-this.utcdateToTimestamp(finelItem.creatTimeUTC))/1000);
  408 + console.log("nearstTimeItem->",finelItem);
  409 + return finelItem;
  410 + }
  411 + console.log("nearstTimeItem->没有找到数据");
  412 + return null
  413 + }
  414 +
  415 + /*
  416 + *
  417 + * utc时间转换为时间戳
  418 + * */
  419 + utcdateToTimestamp (_d) {
  420 + _d=""+_d;//转换为字符串
  421 + if(!_d||_d.length!=14){
  422 + console.error("时间长度不正确->必须是->YYMMDDhhmmss",_d);
  423 + return 0;
  424 + }
  425 + let year = parseInt(_d.substr(0, 4));
  426 + let month = parseInt(_d.substr(4, 2));
  427 + let date = parseInt(_d.substr(6, 2));
  428 + let hour = parseInt(_d.substr(8, 2));
  429 + let minute = parseInt(_d.substr(10, 2));
  430 + let second = parseInt(_d.substr(12, 2));
  431 + //console.log(_d,"->",year,month,date,hour,minute,second);
  432 + let timestamp=new Date(year,(month-1),date,hour,minute,second).getTime();
  433 + return timestamp;
  434 + }
  435 + //getNearestTimeData(time,videoArr){
  436 + // let _time=parseInt(time);
  437 + // let _nearstTimeDistance=100000;//默认设置为一个超长的值
  438 + // let nearstTimeItem=null;
  439 + // for(let k=0;k<videoArr.length;k++){
  440 + // //计算最近时间
  441 + // let interval=parseInt(parseInt(_time)-parseInt(videoArr[k].creatTime))/1000;
  442 + // console.log("getNearestTimeData",interval,_time,k,videoArr[k].creatTime);
  443 + // if(interval>-12&&interval<_nearstTimeDistance){
  444 + // //记录时间点最接近
  445 + // nearstTimeItem=videoArr[k];
  446 + // nearstTimeItem.seek=interval;
  447 + // _nearstTimeDistance=Math.abs(interval);
  448 + // }
  449 + // }
  450 + //
  451 + // let itemJson="";
  452 + // if(nearstTimeItem){
  453 + // itemJson=JSON.stringify(nearstTimeItem);
  454 + // let finelItem=JSON.parse(itemJson);
  455 + // finelItem.seek=parseInt(parseInt(_time)-parseInt(videoArr[k].creatTime))/1000;
  456 + // console.log("nearstTimeItem->",finelItem);
  457 + // return finelItem;
  458 + // }
  459 + // console.log("nearstTimeItem->没有找到数据");
  460 + // return null
  461 + //}
  462 +
  463 + /*getNearestTimeData(time,_creatTime,videoArr){
  464 + let _time=parseInt(time);
  465 + let _nearstTimeDistance=100000;//默认设置为一个超长的值
  466 + let nearstTimeItem=null;
377 for(let k=0;k<videoArr.length;k++){ 467 for(let k=0;k<videoArr.length;k++){
378 //计算最近时间 468 //计算最近时间
379 let interval=_time-parseInt(videoArr[k].creatTimeUTC); 469 let interval=_time-parseInt(videoArr[k].creatTimeUTC);
@@ -396,7 +486,7 @@ class RecordInfoMatch extends Emiter { @@ -396,7 +486,7 @@ class RecordInfoMatch extends Emiter {
396 } 486 }
397 console.log("nearstTimeItem->没有找到数据"); 487 console.log("nearstTimeItem->没有找到数据");
398 return null 488 return null
399 - } 489 + }*/
400 490
401 timestampToUTCTime(_timestamp) { 491 timestampToUTCTime(_timestamp) {
402 let date = new Date(_timestamp - 8 * 60 * 60 * 1000);//GMT 转UTC 减8 492 let date = new Date(_timestamp - 8 * 60 * 60 * 1000);//GMT 转UTC 减8
@@ -141,6 +141,7 @@ class RecordPlayBackParse extends Emiter { @@ -141,6 +141,7 @@ class RecordPlayBackParse extends Emiter {
141 141
142 //解析和储存,录制回放EverSocket底层消息处理 data-数据;timestamp-数据对应的时间戳 142 //解析和储存,录制回放EverSocket底层消息处理 data-数据;timestamp-数据对应的时间戳
143 _parseSaveSocketMsgReceivedHandler(data, timestamp) { 143 _parseSaveSocketMsgReceivedHandler(data, timestamp) {
  144 + //console.log("脚本消息时间",timestamp);
144 let pduMsg = pdu.decode_pdu(data); 145 let pduMsg = pdu.decode_pdu(data);
145 let pduType = pduMsg.get("type"); 146 let pduType = pduMsg.get("type");
146 let pduData = pduMsg.get("data"); 147 let pduData = pduMsg.get("data");
@@ -739,10 +740,37 @@ class RecordPlayBackParse extends Emiter { @@ -739,10 +740,37 @@ class RecordPlayBackParse extends Emiter {
739 } 740 }
740 console.log("TX MediaModule.streams", MediaModule.streams); 741 console.log("TX MediaModule.streams", MediaModule.streams);
741 } 742 }
742 -  
743 //解析录制的rec数据 743 //解析录制的rec数据
744 parseArrayBuf() { 744 parseArrayBuf() {
745 - //this._messages = {}; 745 + let lowTimestamp = 0;
  746 + let isLowTime = false;
  747 +
  748 + /* let byteLength = parseBuffer.offset;
  749 + parseBuffer.byteOffset = 0;
  750 + var position = 0;
  751 + while (position < byteLength) {
  752 + let timestamp = parseBuffer.readUInt32(position);
  753 + position += 4;//4字节
  754 + let byteLen = parseBuffer.readUInt32(position);
  755 + position += 4;//4字节
  756 + let byteData = parseBuffer.buffer.slice(position, (position + byteLen));
  757 + position += byteLen;
  758 +
  759 + if (timestamp < this._recordPlaybackMaxTime) {
  760 + if (isLowTime == false) {
  761 + lowTimestamp = timestamp;
  762 + this._recordPlaybackMaxTime += 10;
  763 + }
  764 + isLowTime = true;
  765 + timestamp = this._recordPlaybackMaxTime + (timestamp - lowTimestamp)
  766 + } else {
  767 + isLowTime = false;
  768 + }
  769 + this._recordPlaybackMaxTime = Math.max(this._recordPlaybackMaxTime, timestamp);
  770 + //按时间戳解保存数据
  771 + this._parseSaveSocketMsgReceivedHandler(byteData, timestamp);
  772 + }*/
  773 +
746 let byteLength = parseBuffer.offset; 774 let byteLength = parseBuffer.offset;
747 parseBuffer.byteOffset = 0; 775 parseBuffer.byteOffset = 0;
748 var position = 0; 776 var position = 0;
@@ -755,7 +783,7 @@ class RecordPlayBackParse extends Emiter { @@ -755,7 +783,7 @@ class RecordPlayBackParse extends Emiter {
755 position += byteLen; 783 position += byteLen;
756 784
757 if(this._recordPlaybackMaxTime>timestamp){ 785 if(this._recordPlaybackMaxTime>timestamp){
758 - loger.warn("脚本录制文件中的数据时间戳重叠了!!!!",this._recordPlaybackMaxTime,timestamp,"相差:"+this._recordPlaybackMaxTime-timestamp); 786 + loger.warn("脚本录制文件中的数据时间戳重叠了!!!!",this._recordPlaybackMaxTime,timestamp);
759 if( this.lastParseTime==0){ 787 if( this.lastParseTime==0){
760 this.lastParseTime=this._recordPlaybackMaxTime; 788 this.lastParseTime=this._recordPlaybackMaxTime;
761 this.lastParseTimeDistance=(this._recordPlaybackMaxTime-timestamp)*2; 789 this.lastParseTimeDistance=(this._recordPlaybackMaxTime-timestamp)*2;
@@ -764,10 +792,10 @@ class RecordPlayBackParse extends Emiter { @@ -764,10 +792,10 @@ class RecordPlayBackParse extends Emiter {
764 } 792 }
765 //记录最后一个数据的时间戳作为整个录制回放的总时间戳 793 //记录最后一个数据的时间戳作为整个录制回放的总时间戳
766 this._recordPlaybackMaxTime = Math.max(this._recordPlaybackMaxTime,timestamp); 794 this._recordPlaybackMaxTime = Math.max(this._recordPlaybackMaxTime,timestamp);
767 -  
768 //按时间戳解保存数据 795 //按时间戳解保存数据
769 this._parseSaveSocketMsgReceivedHandler(byteData, timestamp); 796 this._parseSaveSocketMsgReceivedHandler(byteData, timestamp);
770 } 797 }
  798 +
771 this._recordPlaybackTimestamp = 0; 799 this._recordPlaybackTimestamp = 0;
772 this._isReady = true; 800 this._isReady = true;
773 this._stopTimerCounter(); 801 this._stopTimerCounter();
@@ -716,7 +716,7 @@ class VideoApe extends Ape { @@ -716,7 +716,7 @@ class VideoApe extends Ape {
716 } 716 }
717 if (replay.code == 0) { 717 if (replay.code == 0) {
718 receiveChannelInfo.replay = replay.playUrl; 718 receiveChannelInfo.replay = replay.playUrl;
719 - receiveChannelInfo.seek=receiveChannelInfo.seek+replay.seek; 719 + receiveChannelInfo.seek=parseInt(parseInt(receiveChannelInfo.seek)+parseInt(replay.seek));
720 } 720 }
721 721
722 if (unpackChannelInfo.mediaType != ApeConsts.MEDIA_TYPE_SHARE&& 722 if (unpackChannelInfo.mediaType != ApeConsts.MEDIA_TYPE_SHARE&&