李勇

1.增加自动登录判断

2.录制回放模块对数据分模块保存
... ... @@ -7,6 +7,7 @@ import Emiter from './Emiter';
import Sass from 'Sass';
import ServerCheck from 'ServerCheck';
import RecordPlayBackParse from 'RecordPlayBackParse';
import MD5 from "md5";
import Mcu from 'mcu';
import MessageTypes from 'MessageTypes';
import Loger from 'Loger';
... ... @@ -329,14 +330,24 @@ export default class MessageEntrance extends Emiter {
if (GlobalConfig.userName == null || GlobalConfig.userName == "") {
GlobalConfig.userName = _param.userName;
}
GlobalConfig.autoLogin=_param.autoLogin||"";
GlobalConfig.password = _param.password || "";
GlobalConfig.hasCamera = (typeof _param.hasCamera == "boolean") ? _param.hasCamera : false;
GlobalConfig.hasMicrophone = (typeof _param.hasMicrophone == "boolean") ? _param.hasMicrophone : false;
//debugger;
//开始校验
if (_sass) {
_sass.passwordAndMd5Checking(GlobalConfig.getClassInfo());
loger.log("autoLoginMd5",GlobalConfig.classId,GlobalConfig.userId,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){
// MD5(classId+userId+userRole)==m
//自动登录,跳过验证流程
loger.log("自动登录");
this._sassJoinSuccessHandler();
}else {
//不能自动登录,开始校验
if (_sass) {
_sass.passwordAndMd5Checking(GlobalConfig.getClassInfo());
}
}
}
... ...
... ... @@ -70,6 +70,7 @@ class GlobalConfig {
classStatusInfo.classStartTime=this.classStartTime;//课堂点击开始时间
classStatusInfo.classStopTime=this.classStopTime;//最后一次停止的时间(点暂停或结束),每次发送数据都获取当前时间戳
classStatusInfo.classTimestamp=this.classTimestamp;//相对于点开始课堂的时间戳
classStatusInfo.recordPlaybackMaxTime=this.recordPlaybackMaxTime;//相对于点开始课堂的时间戳
classStatusInfo.classBeginTime=this.classBeginTime;//课堂创建的时间,这个是Sass返回的
classStatusInfo.classEndTime=this.classEndTime;//课堂结束的时间,这个是Sass返回的
... ... @@ -297,6 +298,7 @@ GlobalConfig.classBeginTime="";//课堂创建的时间,这个是Sass返回的
GlobalConfig.classEndTime="";//课堂结束的时间,这个是Sass返回的
GlobalConfig.classTimestamp=0;//从课堂开始到现在的时
GlobalConfig.recordPlaybackMaxTime=0;//录制回放的总时间
GlobalConfig.recordStatus=false;//当前录制状态
GlobalConfig.recordTimestamp=0;//相对于首次开始录制的进行时间
GlobalConfig.recordFileName="";//录制的文件名,如 果为空就创建一个
... ...
... ... @@ -17,11 +17,11 @@ import TimerCounter from "TimerCounter";
let parseBuffer;
// 日志对象
const loger = Loger.getLoger('RecordPlayBackParse');
const Default=0;//未开始
const PLAY=1;//播放中
const PAUSE=2;//暂停
const SEEK=3;//seek
const STOP=4;//停止
const Default = 0;//未开始
const PLAY = 1;//播放中
const PAUSE = 2;//暂停
const SEEK = 3;//seek
const STOP = 4;//停止
class RecordPlayBackParse extends Emiter {
constructor() {
... ... @@ -32,9 +32,17 @@ class RecordPlayBackParse extends Emiter {
console.log(parseBuffer);
this._recordPlaybackTimestamp = 0;//回放的时间
this._recordPlaybackMaxTime = 0;//录制回放的总时间
this._isReady=false;//录制回放是否已经准备完成
this._isReady = false;//录制回放是否已经准备完成
this._apes = {};
this._messages = {};
this._conferApeMssages = {};//会议数据
this._chatApeMssages = {};//聊天数据
this._videoApeMssages = {};//视频数据
this._audioApeMssages = {};//音频数据
this._docApeMssages = {};//文档数据
this._whiteApeMssages = {};//白板数据
this._timerCounter = new TimerCounter();//计时器
this._timerCounter.addTimerCallBack(this._timerCounterUptate.bind(this), 1);
}
... ... @@ -45,8 +53,10 @@ class RecordPlayBackParse extends Emiter {
this._apes[ape._session_id] = ape;
}
// 录制回放EverSocket底层消息处理
_everSocketMsgReceivedHandler(data) {
// 录制回放EverSocket底层消息处理 data-数据;timestamp-数据对应的时间戳
// 1.如果第二个参数timestamp不为空,数据就不往外发送,只做解析和储存
// 2.如果第二个参数timestamp为空,数据就发送给各个ape处理;
_everSocketMsgReceivedHandler(data, timestamp) {
let pduMsg = pdu.decode_pdu(data);
let pduType = pduMsg.get("type");
let pduData = pduMsg.get("data");
... ... @@ -82,13 +92,41 @@ class RecordPlayBackParse extends Emiter {
//先判断当前消息属于哪个APE 根据 sessionId来判断
let ape = this._apes[pduMsg.sessionId];
let sessionLabel = ApeConsts(pduMsg.sessionId);
if (ape) {
let subTypeLabel = pdu.id2type(pduMsg.subType);
//loger.log('MCU-SecondLayer封装消息', 'sessionId', sessionLabel, pduMsg.sessionId, 'subtype', subTypeLabel, pduMsg.subType);
//ape广播事件,只要ape中监听就能收到
ape._emit(pduMsg.subType, pduMsg.data);
if (timestamp) {
//只做解析存储,不对外发送
loger.log('解析数据-timestamp->', timestamp, 'sessionId->', pduMsg.sessionId, 'sessionLabel->', sessionLabel);
switch (pduMsg.sessionId) {
case ApeConsts.CONFERENCE_SESSION_ID:
this.saveParseData(data, timestamp, this._conferApeMssages);
break;
case ApeConsts.CHAT_SESSION_ID:
this.saveParseData(data, timestamp, this._chatApeMssages);
break;
case ApeConsts.DOCSHARING_SESSION_ID:
this.saveParseData(data, timestamp, this._docApeMssages);
break;
case ApeConsts.WHITEBOARD_SESSION_ID:
this.saveParseData(data, timestamp, this._whiteApeMssages);
break;
case ApeConsts.VIDEO_SESSION_ID:
this.saveParseData(data, timestamp, this._videoApeMssages);
break;
case ApeConsts.AUDIO_SESSION_ID:
this.saveParseData(data, timestamp, this._audioApeMssages);
break;
default:
break;
}
} else {
loger.warn(sessionLabel + '尚未注册');
//对方发送消息
if (ape) {
let subTypeLabel = pdu.id2type(pduMsg.subType);
//loger.log('MCU-SecondLayer封装消息', 'sessionId', sessionLabel, pduMsg.sessionId, 'subtype', subTypeLabel, pduMsg.subType);
//ape广播事件,只要ape中监听就能收到
ape._emit(pduMsg.subType, pduMsg.data);
} else {
loger.warn(sessionLabel + '尚未注册');
}
}
break;
default:
... ... @@ -96,6 +134,17 @@ class RecordPlayBackParse extends Emiter {
}
}
//保存数据
saveParseData(data, timestamp, apeMessages) {
let messageItem = apeMessages[timestamp];
if (!messageItem) {
apeMessages[timestamp] = [];//数组存数据,因为有1秒内收到多个消息的情况,timestamp是按秒记录的
messageItem = apeMessages[timestamp];
}
messageItem.push({"timestamp": timestamp, "byteData": data});
}
//开启计时器
_startTimerCounter() {
this._timerCounter.startTimer();
... ... @@ -108,23 +157,28 @@ class RecordPlayBackParse extends Emiter {
_timerCounterUptate() {
this._recordPlaybackTimestamp = this._recordPlaybackTimestamp + 1;//计时
if(this._recordPlaybackTimestamp>=this._recordPlaybackMaxTime){
if (this._recordPlaybackTimestamp >= this._recordPlaybackMaxTime) {
this._stopTimerCounter();
loger.log("录制回放结束...当前时间->", this._recordPlaybackTimestamp," 总时间->",this._recordPlaybackMaxTime);
this._emit(MessageTypes.RECORD_PLAYBACK_UPDATE,{"status":STOP});
loger.log("录制回放结束...当前时间->", this._recordPlaybackTimestamp, " 总时间->", this._recordPlaybackMaxTime);
this._emit(MessageTypes.RECORD_PLAYBACK_UPDATE, {"status": STOP});
return;
}
loger.log("录制回放中...", this._recordPlaybackTimestamp);
this._emit(MessageTypes.CLASS_UPDATE_TIMER, {"classTimestamp": this._recordPlaybackTimestamp});
//根据时间查找消息数据
this._searchMessageFromTime(this._recordPlaybackTimestamp);
//各个APE模块根据时间查找消息数据
this._searchMessageFromTime(this._recordPlaybackTimestamp, this._conferApeMssages);
this._searchMessageFromTime(this._recordPlaybackTimestamp, this._chatApeMssages);
this._searchMessageFromTime(this._recordPlaybackTimestamp, this._docApeMssages);
this._searchMessageFromTime(this._recordPlaybackTimestamp, this._whiteApeMssages);
this._searchMessageFromTime(this._recordPlaybackTimestamp, this._videoApeMssages);
this._searchMessageFromTime(this._recordPlaybackTimestamp, this._audioApeMssages);
}
//加载录制文件
readyRecordPlay() {
this._isReady=false;
this._isReady = false;
this._stopTimerCounter();
loger.log("读取回放数据");
//let url = `http://123.56.73.119:80/h5dev/20170306/1357644520_20170306.rec`;
... ... @@ -182,103 +236,153 @@ class RecordPlayBackParse extends Emiter {
position += byteLen;
console.log(timestamp, byteLen, byteData);
let messageItem=this._messages[timestamp];
if(!messageItem){
this._messages[timestamp]=[];//数组存数据,因为有1秒内收到多个消息的情况,timestamp是按秒记录的
messageItem=this._messages[timestamp];
let messageItem = this._messages[timestamp];
if (!messageItem) {
this._messages[timestamp] = [];//数组存数据,因为有1秒内收到多个消息的情况,timestamp是按秒记录的
messageItem = this._messages[timestamp];
}
messageItem.push({"timestamp": timestamp, "byteData": byteData});
this._everSocketMsgReceivedHandler(byteData, timestamp);
//记录最后一个数据的时间戳作为整个录制回放的总时间戳
this._recordPlaybackMaxTime=timestamp;
this._recordPlaybackMaxTime = timestamp;
}
this._recordPlaybackTimestamp=0;
this._isReady=true;
this._recordPlaybackTimestamp = 0;
this._isReady = true;
this._stopTimerCounter();
GlobalConfig.recordPlaybackMaxTime=this._recordPlaybackMaxTime;
loger.log("录制回放数据解析完成,录制回放的总时间长为->",this._recordPlaybackMaxTime);
console.log(this._messages);
this._emit(RecordPlayBackParse.CLASS_JOIN_RECORD_PLAYBACK_SUCCESS,{"recordPlaybackMaxTime":this._recordPlaybackMaxTime});
GlobalConfig.recordPlaybackMaxTime = this._recordPlaybackMaxTime;
loger.log("录制回放数据解析完成,录制回放的总时间长为->", this._recordPlaybackMaxTime);
console.log("_messages", this._messages);
console.log("_conferApeMssages", this._conferApeMssages);
console.log("_chatApeMssages", this._chatApeMssages);
console.log("_docApeMssages", this._docApeMssages);
console.log("_whiteApeMssages", this._whiteApeMssages);
console.log("_videoApeMssages", this._videoApeMssages);
console.log("_audioApeMssages", this._audioApeMssages);
this._emit(RecordPlayBackParse.CLASS_JOIN_RECORD_PLAYBACK_SUCCESS, {"recordPlaybackMaxTime": this._recordPlaybackMaxTime});
}
//根据时间查找数据
_searchMessageFromTime(_timestamp){
let msgDataArr=this._messages[_timestamp];
if(!msgDataArr){
_searchMessageFromTime(_timestamp, _apeMessages) {
let msgDataArr = _apeMessages[_timestamp];
if (!msgDataArr) {
//没有数据,需要查找当前时间点属于哪一个时间戳关键帧
}else {
} else {
//把时间点对应的数据发送,同一秒内有存在多个数据的情况
for(let i=0;i<msgDataArr.length;i++){
for (let i = 0; i < msgDataArr.length; i++) {
this._everSocketMsgReceivedHandler(msgDataArr[i].byteData);
}
}
}
/*_searchMessageFromTime(_timestamp,_apeMessages){
let msgDataArr=this._messages[_timestamp];
if(!msgDataArr){
//没有数据,需要查找当前时间点属于哪一个时间戳关键帧
}else {
//把时间点对应的数据发送,同一秒内有存在多个数据的情况
for(let i=0;i<msgDataArr.length;i++){
this._everSocketMsgReceivedHandler(msgDataArr[i].byteData);
}
}
}*/
//method------------外部接口-------------------------------------
//开始播放
startRecordPlayback(_param) {
if(!this._isReady){
return {"code": ApeConsts.RETURN_FAILED,"data": "录制回放还未准备完成"};
if (!this._isReady) {
return {"code": ApeConsts.RETURN_FAILED, "data": "录制回放还未准备完成"};
}
this._startTimerCounter();
this._emit(MessageTypes.RECORD_PLAYBACK_UPDATE,{"status":PLAY});
this._emit(MessageTypes.RECORD_PLAYBACK_UPDATE, {"status": PLAY});
}
//停止播放
stopRecordPlayback(_param) {
this._recordPlaybackTimestamp = 0;
this._stopTimerCounter();
this._emit(MessageTypes.RECORD_PLAYBACK_UPDATE,{"status":STOP});
this._emit(MessageTypes.RECORD_PLAYBACK_UPDATE, {"status": STOP});
}
//暂停播放
pauseRecordPlayback(_param) {
this._stopTimerCounter();
this._emit(MessageTypes.RECORD_PLAYBACK_UPDATE,{"status":PAUSE});
this._emit(MessageTypes.RECORD_PLAYBACK_UPDATE, {"status": PAUSE});
}
//跳转到指定时间点播放
seekRecordPlayback(_param) {
if(!this._isReady){
return {"code": ApeConsts.RETURN_FAILED,"data": "录制回放还未准备完成"};
if (!this._isReady) {
return {"code": ApeConsts.RETURN_FAILED, "data": "录制回放还未准备完成"};
}
if(!_param||!_param.time){
return {"code": ApeConsts.RETURN_FAILED,"data": "参数不正确"};
if (!_param || !_param.time) {
return {"code": ApeConsts.RETURN_FAILED, "data": "参数不正确"};
}
//先暂停,更改进行的时间
this._stopTimerCounter()
this._recordPlaybackTimestamp = _param.time || 0;
//查找关键帧
this._searchKeyFram();
//各个ape模块查找关键帧数据
this._searchKeyfram();
}
_searchKeyFram(){
_searchKeyfram() {
//查找关键帧,找到关键帧后再继续播放
this._searchApeMessageKeyfram(this._conferApeMssages,ApeConsts.CONFERENCE_SESSION_ID);
this._searchApeMessageKeyfram(this._docApeMssages,ApeConsts.DOCSHARING_SESSION_ID);
this._searchApeMessageKeyfram(this._whiteApeMssages,ApeConsts.WHITEBOARD_SESSION_ID);
this._searchApeMessageKeyfram(this._videoApeMssages,ApeConsts.VIDEO_SESSION_ID);
this._searchApeMessageKeyfram(this._audioApeMssages,ApeConsts.AUDIO_SESSION_ID);
//聊天模块的比较特殊,消息是累计的
this._searchChatApeMessageKeyfram(this._chatApeMssages,ApeConsts.CHAT_SESSION_ID);
//各个ape模块无论有没有找到关键帧数据,都继续播放
this._startTimerCounter();
}
//查找ape关键帧数据
_searchApeMessageKeyfram(_apeMessages,_apeId) {
let messageItem;
let keyFrameSeek=0;
for(let i=this._recordPlaybackTimestamp;i>0;i--){
messageItem=this._messages[i];
if(messageItem){
break;
let keyFrameSeek = 0;
for (let i = this._recordPlaybackTimestamp; i > 0; i--) {
messageItem = _apeMessages[i];
if (messageItem) {
keyFrameSeek = (this._recordPlaybackTimestamp - i)
loger.log("SEEK->APE",_apeId, this._recordPlaybackTimestamp, "查找到相连的数据, messageItem.timestamp->",i, this._recordPlaybackTimestamp,keyFrameSeek, "秒");
//把时间点对应的数据发送,同一秒内有存在多个数据的情况
for (let k = 0; k < messageItem.length; k++) {
this._everSocketMsgReceivedHandler(messageItem[k].byteData);
}
if(_apeId==ApeConsts.AUDIO_SESSION_ID||_apeId==ApeConsts.VIDEO_SESSION_ID){
this._emit(MessageTypes.RECORD_PLAYBACK_UPDATE, {"status": SEEK, "keyFrameSeek": keyFrameSeek});
}
return;
}
}
if(messageItem){
keyFrameSeek=(this._recordPlaybackTimestamp-messageItem.timestamp)
loger.log("SEEK->",this._recordPlaybackTimestamp,"查找到相连的数据,seek和关键帧的位置偏移",keyFrameSeek,"秒");
//把时间点对应的数据发送,同一秒内有存在多个数据的情况
for(let i=0;i<messageItem.length;i++){
this._everSocketMsgReceivedHandler(messageItem[i].byteData);
loger.log("SEEK->APE",_apeId, this._recordPlaybackTimestamp, "没有查找到相连的数据");
//this._emit(MessageTypes.RECORD_PLAYBACK_UPDATE,{"status":SEEK,"keyFrameSeek":keyFrameSeek});
}
//查找聊天模块ape关键帧数据,聊天模块比较特殊,消息是累积的,当前时间戳之前的都需要显示
_searchChatApeMessageKeyfram(_apeMessages) {
let messageItem;
let keyFrameSeek = 0;
for (let i = this._recordPlaybackTimestamp; i > 0; i--) {
messageItem = _apeMessages[i];
if (messageItem) {
//把时间点对应的数据发送,同一秒内有存在多个数据的情况
for (let i = 0; i < messageItem.length; i++) {
this._everSocketMsgReceivedHandler(messageItem[i].byteData);
}
}
}else {
loger.log("SEEK->",this._recordPlaybackTimestamp,"没有查找到相连的数据");
}
this._emit(MessageTypes.RECORD_PLAYBACK_UPDATE,{"status":SEEK,"keyFrameSeek":keyFrameSeek});
//无论有没有找到关键帧数据,都继续播放
this._startTimerCounter();
}
}
RecordPlayBackParse.prototype.CLASS_JOIN_RECORD_PLAYBACK_SUCCESS = RecordPlayBackParse.CLASS_JOIN_RECORD_PLAYBACK_SUCCESS = 'class_join_recordPlayback_success';//加入录制回放成功
... ...