李勇
0a4aa530 1 parent d53faee0 webRtc-dev ... 20170922-1 20171019-1 20171120-1w dev ly20170824-1 ly20170829-1 ly20170925-1 ly20170926-1 ly20170927-1 ly20170929-1 ly20171011-1 ly20171013-1 ly20171013-2 ly20171016-1 ly20171021-1 ly20171023-1 ly20171024-1w ly20171025-1w ly20171026-1w ly20171027-1w ly20171030-1 ly20171030-2w ly20171107-1 ly20171110-1w ly20171113-1w ly20171204-1w ly20171208-1w ly20171211-1w ly20171211-2w ly20171214-1w v2.38.13.20171216 v2.38.11.20171214 v2.38.3.201712011 v2.38.1.201712011 v2.36.11.20171204 v2.36.8.20171206 v2.36.4.20171201 v2.35.11.20171130 v2.34.16.20171128 v2.34.5.20171127 v2.33.6.20171123 v2.32.1.20171123 v2.31.12.20171122 v2.31.10.20171122 v2.30.5.20171117 v2.30.2.20171117 v2.29.5.20171114 v2.28.1.20171110 v2.27.11.20171109 v2.26.9.20171107 v2.26.6.20171103 v2.26.2.20171102 v2.25.7.20171031 v2.25.6.20171031 v2.25.0.20171030 v2.24.2.20171030 v2.23.0.20171030 v2.22.7.20171026 v2.20.5.20171023 v2.20.0.20171021 v2.19.8.20171020 v2.18.14.20171020 v2.18.10.20171019 v2.17.11.20171014 v2.16.8.20171012 v2.16.5.20171012 v2.15.5.20171001 v2.15.3.20170929 v2.14.5.20170927 v2.13.5.20170927 v2.12.14.20170927 v2.12.8.20170926 v2.12.6.20170925 v2.11.13.20170925 v2.10.7.20170921 v2.10.6.20170921 v2.10.5.20170920 v2.10.4.20170920 v2.9.3.20170919 v2.8.17.20170918 v2.8.8.20170917 v2.8.2.20170916 v2.6.2.20170915 v2.5.12.20170915 v2.5.6.20170914 v2.5.5.20170914 v2.4.4.20170908 v2.4.2.20170908 v2.4.0.20170907 v2.3.6.20170907 v2.2.16.20170905 v2.1.22.20170904 v1.84.0.20170912 v1.83.2.20170831 v1.82.11.20170829 v1.81.19.20170828

修改开启录制和停止录制的逻辑,课堂开启录制之后只有课堂内主动调用停止或课堂内10分钟没有人的时候才会停止

... ... @@ -58,7 +58,7 @@ export default class MessageEntrance extends Emiter {
constructor() {
super();
//sdk 信息
GlobalConfig.sdkVersion = "v1.80.1.20170823";
GlobalConfig.sdkVersion = "v1.81.1.20170824";
loger.warn("sdkVersion:" + GlobalConfig.sdkVersion);
//设置
... ... @@ -127,8 +127,10 @@ export default class MessageEntrance extends Emiter {
_confer_ape.on(MessageTypes.CLASS_STATUS_INFO_CHANGE, this._onClassStatusInfoChange.bind(this)); //当前课堂状态信息发生改变
_confer_ape.on(MessageTypes.CLASS_DELETE_ROSTER, this._onClassDeleteRoster.bind(this)); //当前课堂人员离开
_confer_ape.on(MessageTypes.CLASS_NONENTITY_ROSTER, this._onClassNonentityRoster.bind(this)); //当前课堂中视频或音频占用channel的nodeId ,在人员列表中不存在
_confer_ape.on(MessageTypes.CLASS_RECORD_START, this._onClassRecordStart.bind(this)); //课堂开始录制
_confer_ape.on(MessageTypes.CLASS_RECORD_SUCCESS, this._onClassRecordSuccess.bind(this)); //课堂开启录制成功
_confer_ape.on(MessageTypes.SWITCH_MS_IP, this._switchMsIpHandler.bind(this)); //MS动态选点
//_confer_ape.on(MessageTypes.SWITCH_RTMP_PULL_IP, this._switchRtmpPullIpHandler.bind(this)); //MS 拉流地址动态选点
//_confer_ape.on(MessageTypes.SWITCH_HLS_IP, this._switchHlsIpHandler.bind(this)); //MS HLS动态选点
... ... @@ -406,7 +408,7 @@ export default class MessageEntrance extends Emiter {
//如果是第一次点击开始上课,需要创建录制时的文件名
_onClassRecordStart(_param) {
if (GlobalConfig.getCurrentStatus().code != GlobalConfig.statusCode_2.code) {
if (!_mcu||!_mcu.connected) {
loger.warn("不能保存课堂状态", GlobalConfig.getCurrentStatus());
return;
}
... ... @@ -1355,6 +1357,9 @@ export default class MessageEntrance extends Emiter {
}
if (_confer_ape) {
//开始录制
_confer_ape.startRecord();
//开始上课
_confer_ape.startClass(_param);
}
}
... ... @@ -1476,7 +1481,7 @@ export default class MessageEntrance extends Emiter {
//停止上课
_sendCloseClass(_param) {
if (!_mcu.connected) {
if (!_mcu||!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": ""};
}
... ... @@ -1502,7 +1507,7 @@ export default class MessageEntrance extends Emiter {
}
//离开课堂
if (_confer_ape) {
_confer_ape.stopRecord();
//_confer_ape.stopRecord();//不主动调用停止录制
_confer_ape.leaveClass();
}
... ... @@ -1618,11 +1623,13 @@ export default class MessageEntrance extends Emiter {
//存储Sass数据到本地
if (_data.currentInfo) {
//根据从Sass获取的数据信息,同步最后一次保存的课堂状态信息
loger.log("从Saas返回的课堂状态信息数据",_data.currentInfo);
try {
GlobalConfig.setClassStatusInfo(JSON.parse(_data.currentInfo));
let dataObj=JSON.parse(_data.currentInfo);
dataObj.recordStatus=false;
GlobalConfig.setClassStatusInfo(dataObj);
} catch (err) {
loger.warn("从Sass获取的课堂数据JSON转换失败->");
console.log("currentInfo", _data.currentInfo);
GlobalConfig.setClassStatusInfo(_data.currentInfo);
}
loger.log(GlobalConfig.classStatusInfo);
... ...
require('es6-promise').polyfill();
require('whatwg-fetch');
require('jquery-touchswipe');
require('string.fromcodepoint');
//require('messenger');
import Emiter from './Emiter';
import Sass from 'Sass';
import IpManager from 'IpManager';
import RecordPlayBackParse from 'RecordPlayBackParse';
import MD5 from "md5";
import Mcu from 'mcu';
import MessageTypes from 'MessageTypes';
import Loger from 'Loger';
import ConferApe from 'apes/ConferApe';
import ChatApe from 'apes/ChatApe';
import VideoApe from 'apes/VideoApe';
import AudioApe from 'apes/AudioApe';
import DocApe from 'apes/DocApe';
import WhiteBoardApe from 'apes/WhiteBoardApe';
import CursorApe from 'apes/CursorApe';
import EngineUtils from "EngineUtils";
import GlobalConfig from 'GlobalConfig';
import SystemConfig from 'SystemConfig';
import ApeConsts from 'apes/ApeConsts';
import Base64 from 'base64-js';
import ArrayBufferUtil from 'libs/ArrayBufferUtil';
import Server from "config/Server";
import MediaModule from 'apes/MediaModule';
import MediaSharedApe from 'apes/MediaSharedApe';
import MusicSharedApe from 'apes/MusicSharedApe';
import QuestionApe from 'apes/QuestionApe';
import UTF8 from 'utf-8';
let loger = Loger.getLoger('McuClient');
let _sdkInfo = {"version": "v1.55.1.20170727", "author": "www.3mang.com"};
//APE
let _sass;
let _ipManager;
let _mcu;
let _confer_ape;
let _chat_ape;
let _video_ape;
let _audio_ape;
let _doc_ape;
let _whiteboard_ape;
let _cursor_ape;
let _recordPlayback;
let _mediaShareApe;
let _musicShareApe;
let _questionApe;
//MCUClient 外部实例化主类
export default class EngineEntranceOld extends Emiter {
constructor() {
super();
//sdk 信息
this.sdkInfo = _sdkInfo;
loger.warn(this.sdkInfo);
//获取设备和系统信息
SystemConfig.getSystemInfo();
this.classRecordStatusUpdateTimer = 0; //课堂录制状态发生改变后同步当前所有模块数据的计时器
//初始化状态
this.isGetUserIpCallback = false; //是否获取IP信息返回
this.isGetFastestMcuCallback = false; //是否MCU测速结束
this.isGetFastestMsCallback = false; //是否MS测速结束
this.isGetFastestRtmpPullCallback = false; //是否RTMP拉流地址测试结束
this.isGetFastestHlsPullCallback = false; //是否HLS拉流地址测试结束
this.isGetFastestRsCallback = false; //是否录制回放HLS拉流地址测试结束
//全局的Error处理
this.on(MessageTypes.MCU_ERROR, this._mcuErrorHandler.bind(this));
// Sass平台层
_sass = Sass;
_sass.on('*', (type, data) => this._emit(type, data));
_sass.on(_sass.SUCCESS, this._sassJoinSuccessHandler.bind(this)); //通过SASS平台验证(密码和MD5)
_sass.on(_sass.CLASS_INIT_SUCCESS, this._sassInitSuccessHandler.bind(this)); //获取课堂初始化信息
//_sass.on(_sass.CLASS_GET_CLASS_DETAIL, this._sassGetClassDetailSuccessHandler.bind(this));//获取课堂的基本信息
_sass.on(_sass.CLASS_GET_CLASS_PARAM, this._sassGetClassParamSuccessHandler.bind(this)); //获取课堂的最全信息和历史保存的数据
_sass.on(_sass.CLASS_SAVE_STATUS_INFO_SUCCESS, this._sassSaveClassStatusInfoSuccessHandler.bind(this)); //保存课堂状态信息
_sass.on(_sass.CLASS_SAVE_RECORD_INFO_SUCCESS, this._sassSaveClassRecordInfoSuccessHandler.bind(this)); //保存课堂录制信息
_sass.on(_sass.DELETE_DOCUMENT_SUCCESS, this._sassDeleteDocumentSuccess.bind(this)); //sass删除文档成功
_sass.on(_sass.DELETE_MEDIASHARE_SUCCESS, this._sassDeleteMediaShareSuccess.bind(this)); //sass删除媒体文件成功
_sass.on(_sass.DELETE_MUSICSHARE_SUCCESS, this._sassDeleteMusicShareSuccess.bind(this)); //sass删除MUSIC文件成功
//选点模块
_ipManager = new IpManager();
// 底层MCU消息层
_mcu = Mcu;
_mcu.on('*', (type, data) => this._emit(type, data));
_mcu.on(MessageTypes.CLASS_JOIN_MCU_SUCCESS, this._mcuJoinMCUClassSuccessHandler.bind(this)); //加入MCU课堂完成
_mcu.on(MessageTypes.SWITCH_MCU_IP, this._switchMcuIpHandler.bind(this)); //切换MCU,重新选点
//录制回放
_recordPlayback = RecordPlayBackParse;
_recordPlayback.on('*', (type, data) => this._emit(type, data));
_recordPlayback.on(RecordPlayBackParse.CLASS_JOIN_RECORD_PLAYBACK_SUCCESS, this._joinRecordPlaybackSuccessHandler.bind(this)); //加入录制回放完成
_recordPlayback.on(RecordPlayBackParse.RECORD_PLAYBACK_CLEAR_DATA, this._recordPlaybackClearDataHandler.bind(this)); //录制回放状态更新
// 注册所有应用Ape
_confer_ape = new ConferApe();
_confer_ape.on('*', (type, data) => this._emit(type, data));
_confer_ape.on(MessageTypes.CLASS_RUN_EXIT, this._runClassExit.bind(this)); //监听自己的关闭事件
_confer_ape.on(MessageTypes.CLASS_STATUS_INFO_CHANGE, this._onClassStatusInfoChange.bind(this)); //当前课堂状态信息发生改变
_confer_ape.on(MessageTypes.CLASS_DELETE_ROSTER, this._onClassDeleteRoster.bind(this)); //当前课堂人员离开
_confer_ape.on(MessageTypes.CLASS_NONENTITY_ROSTER, this._onClassNonentityRoster.bind(this)); //当前课堂中视频或音频占用channel的nodeId ,在人员列表中不存在
_confer_ape.on(MessageTypes.CLASS_RECORD_START, this._onClassRecordStart.bind(this)); //课堂开始录制
_confer_ape.on(MessageTypes.CLASS_RECORD_SUCCESS, this._onClassRecordSuccess.bind(this)); //课堂开启录制成功
_confer_ape.on(MessageTypes.SWITCH_MS_IP, this._switchMsIpHandler.bind(this)); //MS动态选点
//_confer_ape.on(MessageTypes.SWITCH_RTMP_PULL_IP, this._switchRtmpPullIpHandler.bind(this)); //MS 拉流地址动态选点
//_confer_ape.on(MessageTypes.SWITCH_HLS_IP, this._switchHlsIpHandler.bind(this)); //MS HLS动态选点
_confer_ape.on(MessageTypes.STOP_ALL_MEDIA_PUBLISH, this._stopAllMediaPublishHandler.bind(this)); //课堂状态发生改变,需要停止当前的所有推流
_chat_ape = new ChatApe();
_chat_ape.on('*', (type, data) => this._emit(type, data));
_video_ape = new VideoApe();
_video_ape.on('*', (type, data) => this._emit(type, data));
_video_ape.on(MessageTypes.VIDEO_UPDATE, this.videoUpdate.bind(this)); //这个监听事件不能删除,需要通知课堂模块,检查channel占用
_video_ape.on(MessageTypes.USER_DEVICE_STATUS_CHAANGE, this.userDeviecStatusChange.bind(this)); //监听摄像头和麦克风的开启状态
_audio_ape = new AudioApe();
_audio_ape.on('*', (type, data) => this._emit(type, data));
_audio_ape.on(MessageTypes.AUDIO_UPDATE, this.audioUpdate.bind(this)); //这个监听事件不能删除,需要通知课堂模块,检查channel占用
_audio_ape.on(MessageTypes.USER_DEVICE_STATUS_CHAANGE, this.userDeviecStatusChange.bind(this)); //监听摄像头和麦克风的开启状态
_mediaShareApe = new MediaSharedApe();
_mediaShareApe.on('*', (type, data) => this._emit(type, data));
_mediaShareApe.on(MediaSharedApe.MEDIASHARED_JOIN_CHANNEL_SUCCESS, this.mediaShareApeJoinChannelSuccess.bind(this));
_musicShareApe = new MusicSharedApe();
_musicShareApe.on('*', (type, data) => this._emit(type, data));
_musicShareApe.on(MusicSharedApe.MUSICSHARED_JOIN_CHANNEL_SUCCESS, this.musicShareApeJoinChannelSuccess.bind(this));
_whiteboard_ape = new WhiteBoardApe();
_whiteboard_ape.on('*', (type, data) => this._emit(type, data));
_cursor_ape = new CursorApe();
_cursor_ape.on('*', (type, data) => this._emit(type, data));
_doc_ape = new DocApe();
_doc_ape.on('*', (type, data) => this._emit(type, data));
_doc_ape.on(MessageTypes.DOC_UPDATE, this.docUpdateHandler.bind(this));
_doc_ape.on(MessageTypes.DOC_DELETE, this.docDeleteHandler.bind(this));
_doc_ape.on(DocApe.DOC_JOIN_CHANNEL_SUCCESS, this.docJoinChannelSuccess.bind(this));
_questionApe = new QuestionApe();
_questionApe.on('*', (type, data) => this._emit(type, data));
//公开外部调用的方法
//class
this.init = this._init.bind(this);
this.joinClass = this._joinClass.bind(this);
this.leaveClass = this._leaveClass.bind(this);
this.getMcuClientStatus = this._getMcuClientStatus.bind(this);
this.getClassStatusInfo = this._getClassStatusInfo.bind(this);
this.sendStartClass = this._sendStartClass.bind(this);
this.silenceClass = this._silenceClass.bind(this);
this.sendPauseClass = this._sendPauseClass.bind(this);
this.sendCloseClass = this._sendCloseClass.bind(this);
this.changeHandUpStatus = this._changeHandUpStatus.bind(this); //自己切换举手状态
this.controlHandUpStatus = this._controlHandUpStatus.bind(this); //控制别人的举手状态
this.controlSilenceStatus = this._controlSilenceStatus.bind(this); //改变禁言状态
this.sceneTableChange = this._sceneTableChange.bind(this); //切换模块显示
this.kickOutRosterFormNodeId = this._kickOutRosterFormNodeId.bind(this); //把指定nodeId的人踢出课堂
this.sendThridChannelMessage = this._sendThridChannelMessage.bind(this);//通道第三方消息通道发送消息
//录制回放
this.initRecordPlayback = this._initRecordPlayback.bind(this);
this.startRecordPlayback = this._startRecordPlayback.bind(this);
this.stopRecordPlayback = this._stopRecordPlayback.bind(this);
this.pauseRecordPlayback = this._pauseRecordPlayback.bind(this);
this.seekRecordPlayback = this._seekRecordPlayback.bind(this);
//chatApe
this.sendChatMsg = this._sendChatMsg.bind(this);
//屏幕共享
this.publishScreenShare = this._publishScreenShare.bind(this);
this.stopPublishScreenShare = this._stopPublishScreenShare.bind(this);
//videoApe
//this.getVideoPlayPath = this._getVideoPlayPath.bind(this);
this.getVideoPublishPath = this._getVideoPublishPath.bind(this);
this.getVideoAllChannelInfo = this._getVideoAllChannelInfo.bind(this);
this.publishVideo = this._publishVideo.bind(this);
this.stopPublishVideo = this.unPublishVideo = this._stopPublishVideo.bind(this);
this.sendVideoBroadcastMsg = this._sendVideoBroadcastMsg.bind(this);
//audioApe
//this.getAudioPlayPath = this._getPlayAudioPath.bind(this);
this.getAudioPublishPath = this._getPublishAudioPath.bind(this);
this.getAudioAllChannelInfo = this._getAudioAllChannelInfo.bind(this);
this.publishAudio = this._publishAudio.bind(this);
this.stopPublishAudio = this.unPublishAudio = this._stopPublishAudio.bind(this);
this.sendAudioBroadcastMsg = this.sendAudioCommandMsg.bind(this);
//whiteBoradApe
this.sendInsertAnnotaion = this._sendInsertAnnotaion.bind(this); //添加标注
this.sendDeleteAllAnnotation = this._sendDeleteAllAnnotation.bind(this); //删除所有标注
this.sendDeleteCurPageAnnotation = this._sendDeleteCurPageAnnotation.bind(this); //删除当前页的所有标注
this.sendGotoPrev = this._sendGotoPrev.bind(this); //当前页撤销上一步
// CursorApe
this.sendInsertCursor = this._sendInsertCursor.bind(this); //添加鼠标同步
//DocApe
this.sendDocumentUpload = this._sendDocumentUpload.bind(this); //上传文档
this.sendDocumentSwitchDoc = this._sendDocumentSwitchDoc.bind(this); //切换文档
this.sendDocumentSwitchPage = this._sendDocumentSwitchPage.bind(this); //翻页
this.sendDocumentSwitchAnimation = this._sendDocumentSwitchAnimation.bind(this); //切换当前页码的动画步骤
this.sendDocumentDelete = this._sassDeleteDocument.bind(this);
this.sendDocBroadcastMsg = this._sendDocBroadcastMsg.bind(this);
//删除文档,先通过Sass删除,sass删除成功之后再同步mcu
//this.sendDocumentDeleteAll= this._documentDeleteAll;//删除所有文档
this.sendDocumentCommand = this._sendDocumentCommand.bind(this);
//操作文档(翻页、缩放、滚动...)
this.getDocImageFullPath = this._getDocImageFullPath.bind(this);
//获取文档图片的完整路径
this.getDocPDFFullPath = this._getDocPDFFullPath.bind(this); //获取文档的完整路径
this.getDocFullAddress = this._getDocFullAddress.bind(this); //获取文档资源地址
//媒体共享模块
this.mediaSharedUpload = this._sendMediaSharedUpload.bind(this); //上传
this.mediaSharedDelete = this._sassDeletMediaShare.bind(this); //删除,先通过Sass删除,删除成功之后才删除MCU的
this.mediaSharedPlay = this._sendMediaSharedPlay.bind(this); //播放
this.mediaSharedStop = this._sendMediaSharedStop.bind(this); //停止
this.mediaSharedUpdate = this._sendMediaSharedUpdate.bind(this); //更新媒体的状态
//音频共享模块
this.musicSharedUpload = this._sendMusicSharedUpload.bind(this); //上传
this.musicSharedDelete = this._sassDeletMusicShare.bind(this); //删除,先通过Sass删除,删除成功之后才删除MCU的
this.musicSharedPlay = this._sendMusicSharedPlay.bind(this); //Music播放
this.musicSharedStop = this._sendMusicSharedStop.bind(this); //Music停止
this.musicSharedUpdate = this._sendMusicSharedUpdate.bind(this); //Music更新媒体的状态
//答题卡
this.creatQuestion = this._creatQuestion.bind(this);
this.getQuestion = this._getQuestion.bind(this);
this.getQuestionResult = this._getQuestionResult.bind(this);
this.sendAnswer = this._sendAnswer.bind(this);
this.stopQuestion = this._stopQuestion.bind(this);
this.setDeviceInfo = this._setDeviceInfo.bind(this); //设置设备信息(麦克风,摄像头等等.....)
this.setMessageDelay = this._setMessageDelay.bind(this); //设置是否延迟消息
this.switchServer = this._switchMcuIpHandler.bind(this); //切换mcu服务器
this.switchMediaServer = this._switchMediaServer.bind(this); //手动切换ms服务器
this.setDebugInfo = this._setDebugInfo.bind(this); //设置debug信息
}
_setDebugInfo(_data) {
loger.log("设置debug信息-->", _data);
if (_data) {
Loger.setLogDebug(_data.isDebug);
}
}
//设置设备信息
_setDeviceInfo(_data) {
loger.log("设置设备信息-->", _data);
if (_data) {
GlobalConfig.cameras = _data.cameras || [];
GlobalConfig.microphones = _data.microphones || [];
GlobalConfig.videoQuality = parseInt(_data.videoQuality);
GlobalConfig.curVideoQuality = parseInt(_data.curVideoQuality);
GlobalConfig.micGain = _data.micGain || 50;
GlobalConfig.speakerVolume = _data.speakerVolume || 50;
GlobalConfig.micCode = _data.micCode || 0;
GlobalConfig.curCamera = _data.curCamera || '';
GlobalConfig.curMicrophone = _data.curMicrophone || '';
if (!GlobalConfig.curCamera && GlobalConfig.cameras.length > 0) {
GlobalConfig.curCamera = GlobalConfig.cameras[0];
}
if (!GlobalConfig.curMicrophone && GlobalConfig.microphones.length > 0) {
GlobalConfig.curMicrophone = GlobalConfig.microphones[0];
}
this._updateDeviceInfo();
}
}
//设置消息延迟
_setMessageDelay(_data) {
loger.warn("延迟消息-->", _data);
if (_data) {
GlobalConfig.messageDelay = _data.messageDelay || false;
}
}
//mcu异常监听
_mcuErrorHandler(_data, _option) {
let option = _option || "";
let errorMessage = {"code": _data, "reson": MessageTypes.ErrorReson[_data] + " " + option};
this._emit(MessageTypes.ERROR_EVENT, errorMessage);
loger.error("MCU_ERROR", errorMessage);
}
//获取当前的状态
_getMcuClientStatus() {
return GlobalConfig.getCurrentStatus();
}
//获取课堂信息
_getClassDetail() {
return GlobalConfig.getClassDetail();
}
//获取当前课堂的状态信息
_getClassStatusInfo() {
return GlobalConfig.classStatusInfo;
}
//执行离开课堂断开连接的流程
_runClassExit(_type) {
this._leaveClass(_type);
}
//当前的课堂状态信息发生改变,需要保存课堂状态到Sass
_onClassStatusInfoChange(_param) {
//如果MCU连接已经断开,不发送
if (GlobalConfig.getCurrentStatus().code != GlobalConfig.statusCode_2.code) {
loger.warn("不能保存课堂状态", GlobalConfig.getCurrentStatus());
return;
}
this._sassSaveClassStatusInfo(_param);
}
//如果是第一次点击开始上课,需要创建录制时的文件名
_onClassRecordStart(_param) {
if (GlobalConfig.getCurrentStatus().code != GlobalConfig.statusCode_2.code) {
loger.warn("不能保存课堂状态", GlobalConfig.getCurrentStatus());
return;
}
if (_sass) {
_sass.saveClassRecordContrlInfo(_param);
}
}
//开启录制成功
_onClassRecordSuccess(_param) {
clearTimeout(this.classRecordStatusUpdateTimer);
let _this = this;
this.classRecordStatusUpdateTimer = setTimeout(function () {
clearTimeout(this.classRecordStatusUpdateTimer);
_this.updaterRecordAllApeStatus(_param);
}, 2000);
}
//录制状态发送改变,更新所有模块的当前数据发送到MCU
updaterRecordAllApeStatus(_param) {
//老师身份和非录制回放的时候执行,录制状态发送改变,需要更新当前的数据,否则已有的消息会录制不上
if (GlobalConfig.isHost && !GlobalConfig.isRecordPlayBack) {
loger.warn('录制状态发送改变->更新所有模块的当前数据发送到MCU');
//目前录制的模块[文档模块、白板模块、视频模块(包含屏幕共享)、音频模块、媒体共享,聊天模块]
if (_doc_ape) {
_doc_ape.updaterRecordApeStatus();
}
if (_whiteboard_ape) {
_whiteboard_ape.updaterRecordApeStatus();
}
if (_video_ape) {
_video_ape.updaterRecordApeStatus();
}
if (_audio_ape) {
_audio_ape.updaterRecordApeStatus();
}
if (_mediaShareApe) {
_mediaShareApe.updaterRecordApeStatus();
}
//聊天模块不需要更新
}
}
//有人员离开
_onClassDeleteRoster(_data) {
}
//当前课堂中视频或音频占用channel的nodeId ,在人员列表中不存在,这种情况是占用channel的人员掉线或离开的时候没有释放channel
//的占用状态导致,对于这种情况,需要释放掉
_onClassNonentityRoster(_param) {
if (GlobalConfig.isRecordPlayBack) {
loger.warn("录制回放中,不处理")
return;
}
if (_param == null || _param.nodeId == null) {
loger.warn("onClassNonentityRoster.参数错误")
return;
}
let data = {"nodeId": _param.nodeId};
if (_video_ape) {
_video_ape.stopPublishVideo(data);
//停止屏幕共享
if (GlobalConfig.nodeId == data.nodeId) {
_video_ape.stopPublishScreenShare(data);
}
}
if (_audio_ape) {
_audio_ape.stopPublishAudio(data);
}
}
//Sass
//初始化
_init(_param) {
//{"classId":"1653304953","portal":"112.126.80.182:80","userRole":"normal","userId":0,isH5:false}
//判断传入的参数是否存在
if (_param == null || EngineUtils.isEmptyObject(_param)) {
loger.error('初始化课堂失败->参数错误', _param);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_PARAM);
return;
}
//判断必要的参数字段值
if (_param.classId == null || isNaN(_param.classId) || _param.portal == null || _param.portal == "") {
loger.error('初始化课堂失败->参数错误', _param);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_PARAM);
return;
}
loger.log('初始化课堂->', _param);
//保存参数
GlobalConfig.isRecordPlayBack = false; //设置为非录制回放状态
GlobalConfig.classId = parseInt(_param.classId);
GlobalConfig.portal = _param.portal;
//H5处理
GlobalConfig.isH5 = _param.isH5 || false;//外部传入的参数,是否是H5
if (GlobalConfig.isH5 == true) {
GlobalConfig.platform = "H5";
GlobalConfig.deviceType = 3//3是H5
loger.warn("设备类型是H5");
}
//IOS 安卓处理,需要外部传入摄像头和麦克风信息
if (GlobalConfig.isMobile) {
GlobalConfig.cameras = _param.cameras || [];
GlobalConfig.microphones = _param.microphones || [];
}
//如果没有名字,随机起一个名字
GlobalConfig.userName = _param.userName || "user_" + (new Date().getTime() % 1000000);
//如果没有userId或者为"0",随机生成
if (!GlobalConfig.userId || GlobalConfig.userId == "0") {
GlobalConfig.userId = "user_" + (new Date().getTime() % 1000000);
}
//设置角色身份
GlobalConfig.userRole = _param.userRole || ApeConsts.normal;
if (GlobalConfig.userRole != ApeConsts.host &&
GlobalConfig.userRole != ApeConsts.presenter &&
GlobalConfig.userRole != ApeConsts.assistant &&
GlobalConfig.userRole != ApeConsts.record &&
GlobalConfig.userRole != ApeConsts.invisible) {
GlobalConfig.userRole = ApeConsts.normal;
}
//客户端决定是否延迟接收消息
GlobalConfig.messageDelay = _param.messageDelay || false;
//最长允许录制的时间
if (_param.allowRecordMaxTime) {
GlobalConfig.allowRecordMaxTime = parseInt(_param.allowRecordMaxTime);
}
//获取课堂校验信息
if (_sass) {
_sass.getJoinParams(GlobalConfig.getClassInfo());
}
}
//外部请求加入课堂
_joinClass(_param) {
if (_param == null || EngineUtils.isEmptyObject(_param)) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_JOIN_PARAM);
loger.log('加入课堂失败->参数错误.', _param);
return;
}
//判断userName
if (_param.userName == null || _param.userName == "") {
loger.log('加入课堂失败->参数错误->名字不能为空');
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_JOIN_PARAM);
return;
}
//{"userName":"名字","password":"","autoLogin":""}
GlobalConfig.userName = _param.userName || GlobalConfig.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;
//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());
}
}
}
// 用classId向SASS平台获取入会验证信息成功
_sassInitSuccessHandler(_data) {
//{"siteId":"h5test","passwordRequired":true,"md5":"de399d5540b3da2fbc1eb0a770d4fd66","code":0,"msType":1}
//储存数据
GlobalConfig.md5 = _data.md5 || ""; //这个暂时用假数据,后台接口写完就有数据了
GlobalConfig.msType = _data.msType || 1;
GlobalConfig.siteId = _data.siteId || "";
GlobalConfig.classType = _data.meetingType || ApeConsts.CLASS_TYPE_1;
//host默认需要密码,Sass服务器只判断学生是否需要密码,没有判断老师的
GlobalConfig.passwordRequired = _data.passwordRequired || false; //md5验证的时候需要Sass返回的值,不能更改
loger.log('初始化课堂验证完成.');
//设置当前的课堂状态
GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_1);
//返回给客户端初始化成功的数据
let initSuccessCallBackData = {};
initSuccessCallBackData.siteId = GlobalConfig.siteId;
initSuccessCallBackData.classId = GlobalConfig.classId;
initSuccessCallBackData.userRole = GlobalConfig.userRole;
initSuccessCallBackData.userId = GlobalConfig.userId;
initSuccessCallBackData.userName = GlobalConfig.userName;
initSuccessCallBackData.classType = GlobalConfig.classType;
//host默认需要密码,Sass服务器只判断学生是否需要密码,没有判断老师的
if (GlobalConfig.userRole == ApeConsts.host) {
initSuccessCallBackData.passwordRequired = true;
} else {
initSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired;
}
this._emit(MessageTypes.CLASS_INIT_SUCCESS, initSuccessCallBackData);
}
// 通过SASS平台验证(密码和MD5)
_sassJoinSuccessHandler(_data) {
//获取课堂最完整的数据
if (_sass) {
_sass.getClassParam();
}
}
//加载本地Server.json文件,UserIp获取ip信息,选点
loadServerJsonAndgetUserIpInfo() {
let _this = this;
if (_ipManager) {
//先加载本地Server.json文件,然后获取userIp新
_ipManager.loadServerJosn(function (_data) {
_ipManager.getUserIpInfo("", GlobalConfig.userIp, _this._getUserIpCallbackHandler.bind(_this), 2000);
})
}
}
//本地JOSN加载完成-获取IP信息完成
_getUserIpCallbackHandler(_data) {
//获取IP信息,返回一次就不再处理
if (this.isGetUserIpCallback) {
return;
}
this.isGetUserIpCallback = true;
if (_data && _data.ret == "ok") {
GlobalConfig.country = _data.country; //国家
GlobalConfig.city = _data.city; //城市
GlobalConfig.province = _data.province; //服务商
GlobalConfig.isp = _data.isp; //服务商
}
//根据用户的userIp信息从sever.json和Sass中选择最终mcu和推流拉流数据列表
this._choiceMcuAndMsListFromServerAndSass();
//获取MCU和MS 推流拉流、录制回放的默认地址
this.getMcuAndMsDefaultServerIp();
loger.warn("加入课堂之前->开始测速->选择默认服务");
//加入课堂之前开始第一次选点
let _this = this;
//推流地址测速
this._getFastestIpFromServer(GlobalConfig.msListFinal,
function (_data) {
loger.log("推流地址测速->", _data);
if (_data && _data.ip) {
GlobalConfig.MS_PUBLISH_IP = _data.ip || "";
GlobalConfig.MS_PUBLISH_PORT = _data.port || "";
}
_this.isGetFastestMsCallback = true;
_this._startConnectMCU();
});
//录制回放HLS拉流地址测速
this._getFastestIpFromServer(GlobalConfig.rsPullListFinal, function (_data) {
loger.log("录制回放HLS拉流地址测速->", _data);
if (_data && _data.ip) {
GlobalConfig.RS_RECORD_PLAY_IP = _data.ip || "";
GlobalConfig.RS_RECORD_PLAY_PORT = _data.port || "";
}
_this.isGetFastestRsCallback = true;
_this._startConnectMCU();
});
//HLS和RTMP不参与测速
/*
//RTMP拉流地址测速
this._getFastestIpFromServer(GlobalConfig.rtmpPullListFinal, function (_data) {
loger.log("RTMP拉流地址测速->", _data);
if (_data && _data.ip) {
GlobalConfig.MS_PLAY_RTMP_IP = _data.ip || "";
GlobalConfig.MS_PLAY_RTMP_PORT = _data.port || "";
}
_this.isGetFastestRtmpPullCallback = true;
_this._startConnectMCU();
});
//HLS拉流地址测速
this._getFastestIpFromServer(GlobalConfig.hlsListFinal, function (_data) {
loger.log("HLS拉流地址测速->", _data);
if (_data && _data.ip) {
GlobalConfig.MS_PLAY_HLS_IP = _data.ip || "";
GlobalConfig.MS_PLAY_HLS_PORT = _data.port || "";
}
_this.isGetFastestHlsPullCallback = true;
_this._startConnectMCU();
});
*/
//MCU测速
this._getFastestMcuServer(function (_data) {
loger.log("MCU测速->", _data);
if (_data && _data.ip) {
GlobalConfig.MCUServerIP = _data.ip || "";
GlobalConfig.MCUServerPort = _data.port || "";
}
_this.isGetFastestMcuCallback = true;
_this._startConnectMCU();
});
}
/* //本地JOSN加载完成-获取IP信息完成
_getUserIpCallbackHandler(_data) {
//获取IP信息,返回一次就不再处理
if (this.isGetUserIpCallback) {
return;
}
this.isGetUserIpCallback = true;
if (_data && _data.ret == "ok") {
GlobalConfig.country = _data.country; //国家
GlobalConfig.city = _data.city; //城市
GlobalConfig.province = _data.province; //服务商
GlobalConfig.isp = _data.isp; //服务商
}
//合并MCU 、MS的列表
this._choiceMcuAndMsList();
//开始选点
let _this = this;
//有一些站点不需要进行MS选点,需要先检查一下
if (GlobalConfig.siteId_letv == GlobalConfig.siteId) {
//MS不需要选点
loger.log("MS不需要选点->siteId->", GlobalConfig.siteId);
_this.isGetFastestMcuCallback = true;
_this._startConnectMCU();
} else {
this._getFastestMsServer(function (_data) {
loger.log("MS选点结束->", _data);
if (_data && _data.ip) {
GlobalConfig.MS_PUBLISH_IP = _data.ip || "";
GlobalConfig.MS_PUBLISH_PORT = _data.port || "";
}
loger.log("当前使用的MS->", GlobalConfig.MS_PUBLISH_IP, GlobalConfig.MS_PUBLISH_PORT);
_this.isGetFastestMcuCallback = true;
_this._startConnectMCU();
});
}
this._getFastestMcuServer(function (_data) {
loger.log("MCU选点结束->", _data);
if (_data && _data.ip) {
GlobalConfig.MCUServerIP = _data.ip || "";
GlobalConfig.MCUServerPort = _data.port || "";
}
loger.log("当前使用的MCU->", GlobalConfig.MCUServerIP, GlobalConfig.MCUServerPort);
_this.isGetFastestMsCallback = true;
_this._startConnectMCU();
});
}*/
//开始连接MCU(所有服务地址测试完成之后开始连接)
_startConnectMCU() {
if (this.isGetFastestMcuCallback &&
this.isGetFastestMsCallback &&
this.isGetFastestRtmpPullCallback &&
this.isGetFastestHlsPullCallback &&
this.isGetFastestRsCallback) {
//mcu完成
//ms推流测速完成
//rtmp拉流测速完成
//hls拉流测速完成
//hls录制回放拉流测速完成
this._joinMCU();
}
}
//从Sever和Sass中选择的mcu、ms列表,如果server.json中存在就不使用Sass
_choiceMcuAndMsListFromServerAndSass() {
//1.根据user信息获取服务器列表
if (_ipManager) {
GlobalConfig.mcuListFromServer = _ipManager.getServerListForUserInfo(
"MCU",
GlobalConfig.country,
GlobalConfig.province,
GlobalConfig.city,
GlobalConfig.isp,
Server.serverList);
GlobalConfig.msListFromServer = _ipManager.getServerListForUserInfo(
"MS",
GlobalConfig.country,
GlobalConfig.province,
GlobalConfig.city,
GlobalConfig.isp,
Server.serverList);
GlobalConfig.rtmpPullListFromServer = _ipManager.getServerListForUserInfo(
"RTMP_PULL",
GlobalConfig.country,
GlobalConfig.province,
GlobalConfig.city,
GlobalConfig.isp,
Server.serverList);
GlobalConfig.rsPullListFromServer = _ipManager.getServerListForUserInfo(
"RS_PULL",
GlobalConfig.country,
GlobalConfig.province,
GlobalConfig.city,
GlobalConfig.isp,
Server.serverList);
GlobalConfig.hlsPullListFromServer = _ipManager.getServerListForUserInfo(
"HLS_PULL",
GlobalConfig.country,
GlobalConfig.province,
GlobalConfig.city,
GlobalConfig.isp,
Server.serverList);
}
loger.warn("Server中获取的服务器信息;")
loger.warn(" GlobalConfig.mcuListFromServer", GlobalConfig.mcuListFromServer);
loger.warn(" GlobalConfig.msListFromServer", GlobalConfig.msListFromServer);
loger.warn(" GlobalConfig.rtmpPullListFromServer", GlobalConfig.rtmpPullListFromServer);
loger.warn(" GlobalConfig.hlsPullListFromServer", GlobalConfig.hlsPullListFromServer);
loger.warn(" GlobalConfig.rsPullListFromServer", GlobalConfig.rsPullListFromServer);
//********选择最终使用的MCU、MS 和拉流列表********
//****优先使用server.json中的数据,如果没有再使用Sass中的数据****
//MCU
GlobalConfig.mcuListFinal = [];
if (GlobalConfig.mcuListFromServer.length > 0) {
//使用server中的MCU数据
GlobalConfig.mcuListFinal = GlobalConfig.mcuListFromServer;
} else {
//使用Sass中的数据
GlobalConfig.mcuListFinal = GlobalConfig.mcuList;
}
//MS推流
GlobalConfig.msListFinal = []
if (GlobalConfig.msListFromServer.length > 0) {
GlobalConfig.msListFinal = GlobalConfig.msListFromServer;
} else {
GlobalConfig.msListFinal = GlobalConfig.msList;
}
//RS录制回放HLS拉流
GlobalConfig.rsPullListFinal = []
if (GlobalConfig.msListFromServer.length > 0) {
GlobalConfig.rsPullListFinal = GlobalConfig.rsPullListFromServer;
} else {
GlobalConfig.rsPullListFinal = GlobalConfig.rsList;
}
//RTMP拉流
GlobalConfig.rtmpPullListFinal = [];
if (GlobalConfig.rtmpPullListFromServer.length > 0) {
GlobalConfig.rtmpPullListFinal = GlobalConfig.rtmpPullListFromServer;
} else {
GlobalConfig.rtmpPullListFinal = GlobalConfig.rtmpPullList;
}
//HLS拉流流
GlobalConfig.hlsPullListFinal = [];
if (GlobalConfig.hlsPullListFromServer.length > 0) {
GlobalConfig.hlsPullListFinal = GlobalConfig.hlsPullListFromServer;
} else {
GlobalConfig.hlsPullListFinal = GlobalConfig.hlsPullList;
}
//拉流地址列表的特殊处理,
// 1.如果RTMP拉流地址没有配置,就默认使用MS推流地址列表
if (!GlobalConfig.rtmpPullListFinal || GlobalConfig.rtmpPullListFinal.length < 1) {
GlobalConfig.rtmpPullListFinal = GlobalConfig.msListFinal;
}
// 2.如果HLS拉流地址没有配置,就默认使用录制回放RS拉流地址列表中的数据
if (!GlobalConfig.hlsPullListFinal || GlobalConfig.hlsPullListFinal.length < 1) {
GlobalConfig.hlsPullListFinal = GlobalConfig.rsPullListFinal;
;
}
loger.warn("课堂最终使用的服务列表->");
loger.warn(" GlobalConfig.mcuListFinal", GlobalConfig.mcuListFinal);
loger.warn(" GlobalConfig.msListFinal", GlobalConfig.msListFinal);
loger.warn(" GlobalConfig.rtmpPullListFinal", GlobalConfig.rtmpPullListFinal);
loger.warn(" GlobalConfig.hlsListFinal", GlobalConfig.hlsPullListFinal);
loger.warn(" GlobalConfig.rsListFinal", GlobalConfig.rsPullListFinal);
}
//开始测速
_getFastestIpFromServer(_dataArr, _callback) {
if (_ipManager) {
_ipManager.testFastestIpFromServer(_dataArr, _callback);
} else {
if (_callback) {
_callback({'ip': ""});
}
}
}
//开始MCU选点操作
_getFastestMcuServer(_callback) {
if (_ipManager) {
_ipManager.getFastestMcuServer(GlobalConfig.mcuListFinal, _callback);
} else {
if (_callback) {
_callback({'ip': ""});
}
}
}
//开始MS选点操作
_getFastestMsServer(_callback) {
if (_ipManager) {
_ipManager.getFastestMsServer(GlobalConfig.msListFinal, _callback);
} else {
if (_callback) {
_callback({ip: ""});
}
}
}
//开始MS-PULL选点操作
_getFastestRtmpPullServer(_callback) {
if (_ipManager) {
_ipManager.getFastestMsServer(GlobalConfig.rtmpPullListFinal, _callback);
} else {
if (_callback) {
_callback({ip: ""});
}
}
}
//开始MS-HLS选点操作
_getFastestHlsServer(_callback) {
if (_ipManager) {
_ipManager.getFastestMsServer(GlobalConfig.rtmpPullListFinal, _callback);
} else {
if (_callback) {
_callback({ip: ""});
}
}
}
//保存课堂状态信息
_sassSaveClassStatusInfo(_param) {
//{isForce:true} isForce->是否强制提交(true为是)
//这个是特殊权限
let isForce = false;
if (_param && _param.isForce == true) {
isForce = true;
}
if (GlobalConfig.isHost || isForce) {
//只有加入课堂之后才能保存数据
if (GlobalConfig.getCurrentStatus().code == GlobalConfig.statusCode_2.code) {
//POST 保存数据
_sass.saveClassStatusInfo({"classStatusInfo": GlobalConfig.classStatusInfo}); //保存课堂状态信息
} else {
loger.error("不能保存课堂数据", GlobalConfig.getCurrentStatus());
}
} else {
loger.log("没有保存课堂状态信息的权限->身份", GlobalConfig.userRole);
}
}
//保存会态信息成功
_sassSaveClassStatusInfoSuccessHandler(_data) {
loger.log('保存课堂状态信息成功.');
loger.log(_data);
}
_sassSaveClassRecordInfoSuccessHandler(_data) {
loger.log('保存课堂录制信息成功.');
loger.log(_data);
}
//Sass校验流程结束之后,开始加入MCU
_joinMCU() {
loger.log('加入课堂->.');
loger.warn("最终使用课堂服务信息->");
loger.warn('MCU服务器地址->mcu->', GlobalConfig.MCUServerIP, GlobalConfig.MCUServerPort);
loger.warn('推流地址->MS->', GlobalConfig.MS_PUBLISH_IP, GlobalConfig.MS_PUBLISH_PORT);
loger.warn('RTMP拉流地址->RTMP->', GlobalConfig.MS_PLAY_RTMP_IP, GlobalConfig.MS_PLAY_RTMP_PORT);
loger.warn('HLS拉流地址->HLS->', GlobalConfig.MS_PLAY_HLS_IP, GlobalConfig.MS_PLAY_HLS_PORT);
loger.warn('HLS录制回放拉流地址->HLS->', GlobalConfig.RS_RECORD_PLAY_IP, GlobalConfig.RS_RECORD_PLAY_PORT);
if (_mcu) {
_mcu.joinMCU(GlobalConfig.getClassInfo());
}
}
_switchMcuIp() {
loger.log('切换MCU IP->.');
if (_mcu) {
_mcu.switchMCUIp(GlobalConfig.getClassInfo());
}
}
// MCU 课堂成功
_mcuJoinMCUClassSuccessHandler(_data) {
//loger.log('MCU 课堂成功.');
GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_2);
GlobalConfig.classJoinSuccess = true;
GlobalConfig.screenWidth = window.screen.width;
GlobalConfig.screenHeight = window.screen.height;
//返回给客户端初始化成功的数据
let joinClassSuccessCallBackData = {};
joinClassSuccessCallBackData.isRecordPlayBack = GlobalConfig.isRecordPlayBack;
joinClassSuccessCallBackData.DOCServerIP = GlobalConfig.DOCServerIP;
joinClassSuccessCallBackData.DOCServerPort = GlobalConfig.DOCServerPort;
joinClassSuccessCallBackData.classStatus = GlobalConfig.classStatus;
joinClassSuccessCallBackData.classId = GlobalConfig.classId;
joinClassSuccessCallBackData.className = GlobalConfig.className;
joinClassSuccessCallBackData.h5Module = GlobalConfig.h5Module;
joinClassSuccessCallBackData.isHost = GlobalConfig.isHost;
joinClassSuccessCallBackData.maxAudioChannels = GlobalConfig.maxAudioChannels;
joinClassSuccessCallBackData.maxVideoChannels = GlobalConfig.maxVideoChannels;
joinClassSuccessCallBackData.maxMediaChannels = GlobalConfig.maxMediaChannels;
joinClassSuccessCallBackData.mcuDelay = GlobalConfig.mcuDelay;
joinClassSuccessCallBackData.msType = GlobalConfig.msType;
joinClassSuccessCallBackData.nodeId = GlobalConfig.nodeId;
joinClassSuccessCallBackData.password = GlobalConfig.password;
joinClassSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired; // 老师的默认是true
//GlobalConfig.passwordRequired 老师的默认是true
//GlobalConfig.portal=_data.portal;
joinClassSuccessCallBackData.role = GlobalConfig.role;
joinClassSuccessCallBackData.siteId = GlobalConfig.siteId;
joinClassSuccessCallBackData.topNodeID = GlobalConfig.topNodeID;
joinClassSuccessCallBackData.userId = GlobalConfig.userId;
joinClassSuccessCallBackData.userName = GlobalConfig.userName;
joinClassSuccessCallBackData.userRole = GlobalConfig.userRole;
joinClassSuccessCallBackData.userType = GlobalConfig.userType;
joinClassSuccessCallBackData.siteId = GlobalConfig.siteId;
joinClassSuccessCallBackData.classId = GlobalConfig.classId;
joinClassSuccessCallBackData.userRole = GlobalConfig.userRole;
joinClassSuccessCallBackData.userId = GlobalConfig.userId;
joinClassSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired;
joinClassSuccessCallBackData.classType = GlobalConfig.classType || ApeConsts.CLASS_TYPE_1;
joinClassSuccessCallBackData.country = GlobalConfig.country; //国家
joinClassSuccessCallBackData.city = GlobalConfig.city; //城市
joinClassSuccessCallBackData.province = GlobalConfig.province; //服务商
joinClassSuccessCallBackData.isp = GlobalConfig.isp; //服务商
joinClassSuccessCallBackData.classTimestamp = GlobalConfig.classTimestamp; //课堂进行的累积时间
joinClassSuccessCallBackData.recordTimestamp = GlobalConfig.recordTimestamp; //课堂录制的累积时间
joinClassSuccessCallBackData.recordPlaybackMaxTime = GlobalConfig.recordPlaybackMaxTime; //录制回放的总时间
joinClassSuccessCallBackData.fps = GlobalConfig.fps;
joinClassSuccessCallBackData.gop = GlobalConfig.gop;
joinClassSuccessCallBackData.videoQuality = GlobalConfig.videoQuality;
joinClassSuccessCallBackData.ssTunnelAppURL = GlobalConfig.ssTunnelAppURL;
joinClassSuccessCallBackData.currentSceneTableId = GlobalConfig.currentSceneTableId; //文档区域的模块显示
joinClassSuccessCallBackData.serverAndLoacTimeDistanc = GlobalConfig.serverAndLoacTimeDistanc;
joinClassSuccessCallBackData.deviceType = GlobalConfig.deviceType;
joinClassSuccessCallBackData.language = GlobalConfig.language;
joinClassSuccessCallBackData.explorer = GlobalConfig.explorer;
joinClassSuccessCallBackData.explorerVersion = GlobalConfig.explorerVersion;
joinClassSuccessCallBackData.os = GlobalConfig.os;
loger.log('加入课堂成功->');
loger.log(joinClassSuccessCallBackData);
//加入课堂成功,广播消息
this._emit(MessageTypes.CLASS_JOIN_SUCCESS, joinClassSuccessCallBackData);
}
//切换MCU ->_param->{reConnect:false} //reConnect(是否立即替换当前的ip并且重新连接)
_switchMcuIpHandler(_param) {
if (GlobalConfig.isRecordPlayBack) {
loger.log('录制回放->不进行MCU动态选点');
return;
}
loger.log('MCU->动态选点');
let _this = this;
this._getFastestMcuServer(function (_data) {
loger.log("MCU选点结束->", _data);
//记录当前的IP地址,选点结束后需要判断一下是否是新的IP;
let oldIp = GlobalConfig.MCUServerIP;
if (_data && _data.ip) {
GlobalConfig.MCUServerIP = _data.ip || "";
GlobalConfig.MCUServerPort = _data.port || "";
} else {
//随机选择一个
if (GlobalConfig.mcuList && GlobalConfig.mcuList.length > 0) {
let index = parseInt(Math.random() * GlobalConfig.mcuList.length);
GlobalConfig.MCUServerIP = GlobalConfig.mcuList[index].ip || "";
GlobalConfig.MCUServerPort = GlobalConfig.mcuList[index].port || "";
}
}
if (oldIp && oldIp != GlobalConfig.MCUServerIP) {
loger.log('MCU->最新地址->', GlobalConfig.MCUServerIP, GlobalConfig.MCUServerPort);
//判断是否需要主动断开当前的连接然后重连新的服务器
if (_param && _param.reConnect == true) {
loger.log('MCU->切换到最新的IP->', GlobalConfig.MCUServerIP, GlobalConfig.MCUServerPort);
_this._startConnectMCU();
} else {
//不需要断开当前的连接,更改ip即可
_this._switchMcuIp();
}
} else {
//如果选点结束后获得的ip和当前的IP相同,不需要切换
loger.log('MCU不需要切换->之前的IP->', oldIp, "新的IP->", GlobalConfig.MCUServerIP);
}
});
}
//课堂状态发生改变,需要停止当前的所有推流
_stopAllMediaPublishHandler(_data) {
loger.log('课堂状态发生改变,需要停止当前的所有推流');
this._emit(MessageTypes.MEDIA_STOP_PUBLISH);
}
//手动切换MS -> {ip;"xxx.xx.xx","port":"xxxx"}
_switchMediaServer(_param) {
if (GlobalConfig.isRecordPlayBack) {
//录制回放不做操作
loger.warn('录制回放->不能手动切换MS');
return;
}
if (_param && _param.ip) {
GlobalConfig.MS_PUBLISH_IP = _param.ip || "";
GlobalConfig.MS_PUBLISH_PORT = _param.port || "";
}
loger.warn('手动切换MS->', GlobalConfig.MS_PUBLISH_IP + ":" + GlobalConfig.MS_PUBLISH_PORT);
//更换完用户当前的MS地址,需要更新用户数据
if (_confer_ape) {
_confer_ape.updateUserInfo();
}
}
//切换MS ->_param->{reConnect:false} //reConnect(是否立即替换当前的ip并且重新连接)
_switchMsIpHandler(_param) {
if (GlobalConfig.isRecordPlayBack) {
//录制回放不做操作
loger.warn('录制回放->不进行MS动态选点');
return;
}
let _this = this;
this._getFastestMsServer(function (_data) {
loger.log("MS选点结束->", _data);
//记录当前的IP地址,选点结束后需要判断一下是否是新的IP;
let oldIp = GlobalConfig.MS_PUBLISH_IP;
if (_data && _data.ip) {
GlobalConfig.MS_PUBLISH_IP = _data.ip || "";
GlobalConfig.MS_PUBLISH_PORT = _data.port || "";
} else {
//随机选择一个
if (GlobalConfig.msListFinal && GlobalConfig.msListFinal.length > 0) {
let index = parseInt(Math.random() * GlobalConfig.msListFinal.length);
GlobalConfig.MS_PUBLISH_IP = GlobalConfig.msListFinal[index].ip || "";
GlobalConfig.MS_PUBLISH_PORT = GlobalConfig.msListFinal[index].port || "";
}
}
if (oldIp && oldIp != GlobalConfig.MS_PUBLISH_IP) {
//选点完成需要更新用户数据
if (_confer_ape) {
_confer_ape.updateUserInfo();
}
loger.log('MS->最新地址->', GlobalConfig.MS_PUBLISH_IP, GlobalConfig.MS_PUBLISH_PORT);
} else {
//如果选点结束后获得的ip和当前的IP相同,不需要切换
loger.log('MS不需要切换->IP', GlobalConfig.MS_PUBLISH_IP);
}
});
}
//切换MS -PULL地址
_switchRtmpPullIpHandler(_param) {
if (GlobalConfig.isRecordPlayBack) {
//录制回放不做操作
loger.warn('录制回放->不进行MS-PULL动态选点');
return;
}
if(!GlobalConfig.rtmpPullListFinal||GlobalConfig.rtmpPullListFinal.length<1){
return;
}
let _this = this;
this._getFastestRtmpPullServer(function (_data) {
loger.log("MS->PULL->选点结束->", _data);
if (_data && _data.ip) {
GlobalConfig.MS_PLAY_RTMP_IP = _data.ip || "";
GlobalConfig.MS_PLAY_RTMP_PORT = _data.port || "";
} else {
//随机选择一个
if (GlobalConfig.rtmpPullListFinal && GlobalConfig.rtmpPullListFinal.length > 0) {
let index = parseInt(Math.random() * GlobalConfig.rtmpPullListFinal.length);
GlobalConfig.MS_PLAY_RTMP_IP = GlobalConfig.rtmpPullListFinal[index].ip || "";
GlobalConfig.MS_PLAY_RTMP_PORT = GlobalConfig.rtmpPullListFinal[index].port || "";
}
}
//如果RTMP没有配置地址,那么还是使用推流的地址
if(!GlobalConfig.MS_PLAY_RTMP_IP){
GlobalConfig.MS_PLAY_RTMP_IP = GlobalConfig.MS_PUBLISH_IP;
GlobalConfig.MS_PLAY_RTMP_PORT = GlobalConfig.MS_PUBLISH_PORT;
}
});
}
//切换MS HLS地址
_switchHlsIpHandler(_param) {
if (GlobalConfig.isRecordPlayBack) {
//录制回放不做操作
loger.warn('录制回放->不进行MS-HLS动态选点');
return;
}
if(!GlobalConfig.hlsPullListFinal||GlobalConfig.hlsPullListFinal.length<1){
return;
}
let _this = this;
this._getFastestHlsServer(function (_data) {
loger.log("HLS选点结束->", _data);
if (_data && _data.ip) {
GlobalConfig.MS_PLAY_HLS_IP = _data.ip || "";
GlobalConfig.MS_PLAY_HLS_PORT = _data.port || "";
} else {
//随机选择一个
if (GlobalConfig.hlsPullListFinal && GlobalConfig.hlsPullListFinal.length > 0) {
let index = parseInt(Math.random() * GlobalConfig.hlsPullListFinal.length);
GlobalConfig.MS_PLAY_HLS_IP = GlobalConfig.hlsPullListFinal[index].ip || "";
GlobalConfig.MS_PLAY_HLS_PORT = GlobalConfig.hlsPullListFinal[index].port || "";
}
}
//如果HLS没有配置地址,那么还是使用推流的地址
if(!GlobalConfig.MS_PLAY_HLS_IP){
GlobalConfig.MS_PLAY_HLS_IP = GlobalConfig.RS_RECORD_PLAY_IP;
GlobalConfig.MS_PLAY_HLS_PORT = GlobalConfig.RS_RECORD_PLAY_PORT;
}
});
}
//先通过Sass删除文档数据,删除成功之后才能删除MCU的
_sassDeleteDocument(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
//判断传入的参数是否存在
if (_param == null || EngineUtils.isEmptyObject(_param)) {
loger.error('删除文档失败->参数错误', _param);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_DOC_DELETE_FAILED_PARAM);
return;
}
//判断必要的参数字段值
if (_param.itemIdx == null || isNaN(_param.itemIdx) || _param.docId == null || _param.docId == "") {
loger.error('删除文档失败->', _param);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_DOC_DELETE_FAILED_PARAM);
return;
}
loger.log('删除文档->', _param);
if (_sass) {
_sass.sassDeleteDocument(_param);
}
}
_sendDocBroadcastMsg(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_doc_ape) {
_doc_ape.sendDocBroadcastMsg(_param);
}
}
//Sass删除文档成功之后,同步删除MCU数据
_sassDeleteDocumentSuccess(_param) {
loger.log('删除文档成功->', _param);
this._sendDocumentDelete(_param);
}
_sassDeleteMediaShareSuccess(_param) {
loger.log('删除媒体文件成功->', _param);
this._sendMediaSharedDelete(_param);
}
_sassDeleteMusicShareSuccess(_param) {
loger.log('删除Music文件成功->', _param);
this._sendMusicSharedDelete(_param);
}
//ConferApe
//开始上课
_sendStartClass(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_confer_ape) {
_confer_ape.startClass(_param);
}
}
//ConferApe
//全局禁言
_silenceClass(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_confer_ape) {
_confer_ape.silenceClass(_param);
}
}
//暂停上课
_sendPauseClass(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_confer_ape) {
_confer_ape.pauseClass(_param);
}
}
//更新设备信息
_updateDeviceInfo(_param) {
if (!_mcu.connected) {
loger.warn('更新设备信息->失败', GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": ""};
}
if (!GlobalConfig.classJoinSuccess) {
loger.warn('更新设备信息->失败->还没有加入课堂成功', GlobalConfig.getCurrentStatus());
}
if (_confer_ape) {
_confer_ape.updateDeviceInfo(_param);
}
}
//文档-媒体共享-屏幕共享模块切换
_sceneTableChange(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": ""};
}
if (_confer_ape) {
_confer_ape.sceneTableChange(_param);
}
}
//通过第三方消息通道发送消息
_sendThridChannelMessage(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": ""};
}
if (_confer_ape) {
_confer_ape.onThirdReciveParentMessage(_param);
}
}
//将指定nodeId的人踢出课堂
_kickOutRosterFormNodeId(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": ""};
}
if (_confer_ape) {
_confer_ape.kickOutRosterFormNodeId(_param);
}
}
// 禁言控制
_controlSilenceStatus(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": ""};
}
if (_confer_ape) {
_confer_ape.controlSilenceStatus(_param);
}
}
//举手状态控制
_controlHandUpStatus(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": ""};
}
if (_confer_ape) {
_confer_ape.controlHandUpStatus(_param);
}
}
//举手状态切换
_changeHandUpStatus(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": ""};
}
if (_confer_ape) {
_confer_ape.changeHandUpStatus(_param);
}
}
//停止上课
_sendCloseClass(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": ""};
}
if (_confer_ape) {
_confer_ape.closeClass(_param);
}
}
// 离开课堂 {type:1} type=1被踢出课堂;type=0自己主动离开
_leaveClass(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": ""};
}
//停止推流
if (_video_ape) {
_video_ape.stopPublishVideo();
_video_ape.stopPublishScreenShare();
}
if (_audio_ape) {
_audio_ape.stopPublishAudio();
}
//离开课堂
if (_confer_ape) {
_confer_ape.stopRecord();
_confer_ape.leaveClass();
}
let callBack = {};
if (_param && _param.type) {
callBack = _param;
} else {
callBack.type = 0;
}
loger.warn('离开课堂->', MessageTypes.CLASS_EXIT, callBack);
this._emit(MessageTypes.CLASS_EXIT, callBack);
//断开MCU连接
if (_mcu) {
_mcu.leaveMCU();
GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_3);
}
}
//获取课堂所有参数(20170727新规则) api/meeting/detail.do? flash中的接口文件是 getClassParam.do
_sassGetClassParamSuccessHandler(_data) {
loger.log('获取课堂课堂信息完成.');
//包含整个课堂最全的信息,储存数据
if (_data) {
GlobalConfig.mcuDelay = _data.h5Delay || 0; //mcu消息延迟的时间间隔,单位(秒),结合客户端传的messageDelay的值使用
GlobalConfig.className = _data.meetingName || "";
GlobalConfig.classBeginTime = _data.beginTime || "";
GlobalConfig.classEndTime = _data.endTime || "";
GlobalConfig.userIp = _data.userIp || "";
GlobalConfig.maxVideoChannels = _data.maxVideoChannels;
GlobalConfig.maxAudioChannels = _data.maxAudioChannels;
GlobalConfig.maxMediaChannels = Math.max(GlobalConfig.maxVideoChannels, GlobalConfig.maxAudioChannels);
GlobalConfig.ssTunnelAppURL = _data.ssTunnelAppURL || ''; //屏幕共享插件的地址
//视频质量相关设置,每次加入课堂都按最新的获取设置
GlobalConfig.fps = _data.fps || 15;
GlobalConfig.gop = _data.gop || 3;
GlobalConfig.videoQuality = parseInt(_data.videoQuality);
GlobalConfig.curVideoQuality = GlobalConfig.videoQuality;
//是否自动开始(身份是host的时候才用到的)
GlobalConfig.isAutoStartClass = _data.autoRecord || 0;
GlobalConfig.serverTime = _data.serverTime || new Date().getTime(); //获取服务器时间戳
GlobalConfig.serverAndLoacTimeDistanc = (new Date().getTime() - GlobalConfig.serverTime) / 1000; //当前系统时间和服务器时间的差值 (秒)
loger.warn("服务器时间:" + GlobalConfig.serverTime + " 系统时间:" + new Date().getTime() + " 时间差:" + GlobalConfig.serverAndLoacTimeDistanc);
GlobalConfig.setDocListPrepare(_data.docListPrepare); //提前上传的文档列表
GlobalConfig.setRecordList(_data.recordList); //录制回放地址
GlobalConfig.setDocList(_data.docList); //文档地址
GlobalConfig.setMusicList(_data.musicList); //
GlobalConfig.setMusicListPrepare(_data.musicListPrepare); //提前上传的声音文件列表
GlobalConfig.setVideoCDNAddr(_data.videoCDNAddr); //cdn加速的拉流地址,直播的时候才使用
GlobalConfig.setMediaShareList(_data.sharedMediaList); //提前上传的媒体共享文件列表
//存从Sass获取的MS和MCU服务列表
if (_data.msList2) {
GlobalConfig.setMsList(_data.msList2.msList); //储存Sass ms拉流地址
GlobalConfig.setRtmpPullList(_data.msList2.rtmpPullArray); //储存Sass ms拉流地址
GlobalConfig.setHlsPullList(_data.msList2.hlsPullArray); //储存Sass ms拉流地址
GlobalConfig.setRsList(_data.msList2.rsList); //储存Sass 录制回放hls拉流地址
}
//Sass mcu
GlobalConfig.setMcuList(_data.mcuList); //mcu
loger.warn('从Sass获取的推流拉流列表数据:');
loger.warn('Sass->msList->', GlobalConfig.msList);
loger.warn('Sass->rtmpPullList->', GlobalConfig.rtmpPullList);
loger.warn('Sass->hlsPullList->', GlobalConfig.hlsPullList);
loger.warn('Sass->rsList->', GlobalConfig.rsList);
//没有加载server.json之前,最终的服务列表按Sass的为准,server.json加载完成后会选点
GlobalConfig.msListFinal=GlobalConfig.msList;
GlobalConfig.rtmpPullListFinal=GlobalConfig.rtmpPullList;
GlobalConfig.hlsPullListFinal=GlobalConfig.hlsPullList;
GlobalConfig.rsPullListFinal=GlobalConfig.rsList;
GlobalConfig.mcuListFinal=GlobalConfig.mcuList;
}
//课堂获取Sass数据完成
this._emit(MessageTypes.CLASS_GET_INFO_SUCCESS, GlobalConfig.getClassInfo());
if (_data.currentInfo) {
//根据从Sass获取的数据信息,同步最后一次保存的课堂状态信息
try {
GlobalConfig.setClassStatusInfo(JSON.parse(_data.currentInfo));
} catch (err) {
loger.warn("从Sass获取的课堂数据JSON转换失败->");
console.log("currentInfo", _data.currentInfo);
GlobalConfig.setClassStatusInfo(_data.currentInfo);
}
loger.log(GlobalConfig.classStatusInfo);
} else {
loger.log("还没有保存过课堂状信息");
}
//课堂数据获取完成->进入课堂或进入录制回放
//录制回放不需要获取ip信息和选点
if (GlobalConfig.isRecordPlayBack) {
if (_recordPlayback) {
//获取MCU和MS 推流拉流、录制回放的默认地址
this.getMcuAndMsDefaultServerIp();
//开启录制回放流程
loger.warn("开启录制回放流程");
_recordPlayback.readyRecordPlay();
} else {
loger.warn("开启录制回放流程失败->还未创建模块");
}
} else {
//根据用户的userIp获取信息,获取服务列表选点,选点测速完成后才加入MCU
this.loadServerJsonAndgetUserIpInfo();
}
}
//获取各个服务的默认ip,之后会进行测速选择更快的ip
getMcuAndMsDefaultServerIp() {
//MCU地址
if (GlobalConfig.mcuListFinal && GlobalConfig.mcuListFinal.length > 0) {
//还未开始选点之前随机选择一个
let index = parseInt(Math.random() * GlobalConfig.mcuListFinal.length);
GlobalConfig.MCUServerIP = GlobalConfig.mcuListFinal[index].ip || "";
GlobalConfig.MCUServerPort = GlobalConfig.mcuListFinal[index].port || "";
}
//录制回放时m3u8播流地址
if (GlobalConfig.rsPullListFinal && GlobalConfig.rsPullListFinal.length > 0) {
//还未开始选点之前随机选择一个
let index = parseInt(Math.random() * GlobalConfig.rsPullListFinal.length);
GlobalConfig.RS_RECORD_PLAY_IP = GlobalConfig.rsPullListFinal[index].ip || "";
GlobalConfig.RS_RECORD_PLAY_PORT = GlobalConfig.rsPullListFinal[index].port || "";
}
//推流地址
if (GlobalConfig.msListFinal && GlobalConfig.msListFinal.length > 0) {
//还未开始选点之前随机选择一个
let index = parseInt(Math.random() * GlobalConfig.msListFinal.length);
GlobalConfig.MS_PUBLISH_IP = GlobalConfig.msListFinal[index].ip || "";
GlobalConfig.MS_PUBLISH_PORT = GlobalConfig.msListFinal[index].port || "";
}
//RTMP拉流
if (GlobalConfig.rtmpPullListFinal && GlobalConfig.rtmpPullListFinal.length > 0) {
// //还未开始选点之前随机选择一个
let index = parseInt(Math.random() * GlobalConfig.rtmpPullListFinal.length);
GlobalConfig.MS_PLAY_RTMP_IP = GlobalConfig.rtmpPullListFinal[index].ip || "";
GlobalConfig.MS_PLAY_RTMP_PORT = GlobalConfig.rtmpPullListFinal[index].port || "";
} else {
//如果没有单独的rtmp拉流地址,和推流地址一样即可
GlobalConfig.MS_PLAY_RTMP_IP = GlobalConfig.MS_PUBLISH_IP;
GlobalConfig.MS_PLAY_RTMP_PORT = GlobalConfig.MS_PUBLISH_PORT;
}
//课堂中HLS拉流地址
if (GlobalConfig.hlsPullListFinal && GlobalConfig.hlsPullListFinal.length > 0) {
//有单独的hls拉流地址
let index = parseInt(Math.random() * GlobalConfig.hlsPullListFinal.length);
GlobalConfig.MS_PLAY_HLS_IP = GlobalConfig.hlsPullListFinal[index].ip || "";
GlobalConfig.MS_PLAY_HLS_PORT = GlobalConfig.hlsPullListFinal[index].port || "";
} else {
//没有单独的hls拉流地址,和录制回放地址一样即可
GlobalConfig.MS_PLAY_HLS_IP = GlobalConfig.RS_RECORD_PLAY_IP;
GlobalConfig.MS_PLAY_HLS_PORT = GlobalConfig.RS_RECORD_PLAY_PORT;
}
//文档服务器地址
if (GlobalConfig.docList && GlobalConfig.docList.length > 0) {
//doc上传地址,随机获取一个
let index = parseInt(Math.random() * GlobalConfig.docList.length);
GlobalConfig.DOCServerIP = GlobalConfig.docList[index].ip || "";
GlobalConfig.DOCServerPort = GlobalConfig.docList[index].port || "";
}
//录制回放文件的下载地址
if (GlobalConfig.recordList && GlobalConfig.recordList.length > 0) {
let index = parseInt(Math.random() * GlobalConfig.recordList.length);
GlobalConfig.RecordServerIP = GlobalConfig.recordList[index].ip || "";
GlobalConfig.RecordServerPort = GlobalConfig.recordList[index].port || "";
}
loger.warn('默认->MCU地址->.', GlobalConfig.MCUServerIP, GlobalConfig.MCUServerPort);
loger.warn('默认->MS推流地址->.', GlobalConfig.MS_PUBLISH_IP, GlobalConfig.MS_PUBLISH_PORT);
loger.warn('默认->HLS点播地址->.', GlobalConfig.RS_RECORD_PLAY_IP, GlobalConfig.RS_RECORD_PLAY_PORT);
loger.warn('默认->HLS拉流地址->.', GlobalConfig.MS_PLAY_HLS_IP, GlobalConfig.MS_PLAY_HLS_PORT);
loger.warn('默认->RTMP拉流地址->.', GlobalConfig.MS_PLAY_RTMP_IP, GlobalConfig.MS_PLAY_RTMP_PORT);
loger.warn('默认->文档服务器地址->.', GlobalConfig.DOCServerIP, GlobalConfig.DOCServerPort);
loger.warn('默认->录制回放文件下载地址->.', GlobalConfig.RecordServerIP, GlobalConfig.RecordServerPort);
}
//获取课堂所有参数 api/meeting/detail.do? flash中的接口文件是 getClassParam.do(20170727之前的规则)
/*_sassGetClassParamSuccessHandler(_data) {
loger.log('获取课堂课堂信息完成.');
//包含整个课堂最全的信息,储存数据
if (_data) {
GlobalConfig.mcuDelay = _data.h5Delay || 0; //mcu消息延迟的时间间隔,单位(秒),结合客户端传的messageDelay的值使用
GlobalConfig.className = _data.meetingName || "";
GlobalConfig.classBeginTime = _data.beginTime || "";
GlobalConfig.classEndTime = _data.endTime || "";
GlobalConfig.userIp = _data.userIp || "";
GlobalConfig.maxVideoChannels = _data.maxVideoChannels;
GlobalConfig.maxAudioChannels = _data.maxAudioChannels;
GlobalConfig.maxMediaChannels = Math.max(GlobalConfig.maxVideoChannels, GlobalConfig.maxAudioChannels);
GlobalConfig.ssTunnelAppURL = _data.ssTunnelAppURL || ''; //屏幕共享插件的地址
//视频质量相关设置,每次加入课堂都按最新的获取设置
GlobalConfig.fps = _data.fps || 15;
GlobalConfig.gop = _data.gop || 3;
GlobalConfig.videoQuality = parseInt(_data.videoQuality);
GlobalConfig.curVideoQuality = GlobalConfig.videoQuality;
//是否自动开始(身份是host的时候才用到的)
GlobalConfig.isAutoStartClass = _data.autoRecord || 0;
GlobalConfig.serverTime = _data.serverTime || new Date().getTime(); //获取服务器时间戳
GlobalConfig.serverAndLoacTimeDistanc = (new Date().getTime() - GlobalConfig.serverTime) / 1000; //当前系统时间和服务器时间的差值 (秒)
loger.warn("服务器时间:" + GlobalConfig.serverTime + " 系统时间:" + new Date().getTime() + " 时间差:" + GlobalConfig.serverAndLoacTimeDistanc);
GlobalConfig.setDocListPrepare(_data.docListPrepare); //提前上传的文档列表
GlobalConfig.setRecordList(_data.recordList); //录制回放地址
GlobalConfig.setDocList(_data.docList); //文档地址
GlobalConfig.setMsList(_data.msList); //推流播流服务器地址(需要对列表中的地址进行分类,里面包含了推流和拉流的地址,目前主要是乐视的需要区分开)
GlobalConfig.setRsList(_data.rsList); //播放m3u8格式的地址(录制回放时使用)
GlobalConfig.setMcuList(_data.mcuList); //mcu
GlobalConfig.setMusicList(_data.musicList); //
GlobalConfig.setMusicListPrepare(_data.musicListPrepare); //提前上传的声音文件列表
GlobalConfig.setVideoCDNAddr(_data.videoCDNAddr); //cdn加速的拉流地址,直播的时候才使用
GlobalConfig.setMediaShareList(_data.sharedMediaList); //提前上传的媒体共享文件列表
//MCU地址
if (_data.mcuList && _data.mcuList.length > 0) {
//随机选择一个
let index = parseInt(Math.random() * _data.mcuList.length);
GlobalConfig.MCUServerIP = _data.mcuList[index].ip || "";
GlobalConfig.MCUServerPort = _data.mcuList[index].port || "";
loger.log('初始->MCU->.', GlobalConfig.MCUServerIP, GlobalConfig.MCUServerPort);
}
//录制回放时m3u8播流地址
if (_data.rsList && _data.rsList.length > 0) {
let index = parseInt(Math.random() * _data.rsList.length);
GlobalConfig.RS_RECORD_PLAY_IP = _data.rsList[index].ip || "";
GlobalConfig.RS_RECORD_PLAY_PORT = _data.rsList[index].port || "";
loger.log('初始->RS->.', GlobalConfig.RS_RECORD_PLAY_IP, GlobalConfig.RS_RECORD_PLAY_PORT);
}
//上课中音视频推流地址
if (GlobalConfig.msList && GlobalConfig.msList.length > 0) {
let index = parseInt(Math.random() * GlobalConfig.msList.length);
GlobalConfig.MS_PUBLISH_IP = GlobalConfig.msList[index].ip || "";
GlobalConfig.MS_PUBLISH_PORT = GlobalConfig.msList[index].port || "";
}
loger.log('初始->MS->.', GlobalConfig.MS_PUBLISH_IP, GlobalConfig.MS_PUBLISH_PORT);
//播流的地址和推流地址需要分开的时候,单独设置拉流的地址 rtmp(目前乐视使用)
if (GlobalConfig.rtmpPullList && GlobalConfig.rtmpPullList.length > 0) {
//有单独的rtmp拉流地址
let index = parseInt(Math.random() * GlobalConfig.rtmpPullList.length);
GlobalConfig.MS_PLAY_RTMP_IP = GlobalConfig.rtmpPullList[index].ip || "";
GlobalConfig.MS_PLAY_RTMP_PORT = GlobalConfig.rtmpPullList[index].port || "";
} else {
//如果没有单独的rtmp拉流地址,和推流地址一样即可
GlobalConfig.MS_PLAY_RTMP_IP = GlobalConfig.MS_PUBLISH_IP;
GlobalConfig.MS_PLAY_RTMP_PORT = GlobalConfig.MS_PUBLISH_PORT;
}
loger.log('初始->MSPull->.', GlobalConfig.MS_PLAY_RTMP_IP, GlobalConfig.MS_PLAY_RTMP_PORT);
//播流的地址和推流地址需要分开的时候,单独设置拉流的地址 hls(目前乐视使用)
if (GlobalConfig.hlsList && GlobalConfig.hlsList.length > 0) {
//有单独的hls拉流地址
let index = parseInt(Math.random() * GlobalConfig.hlsList.length);
GlobalConfig.MS_PLAY_HLS_IP = GlobalConfig.hlsList[index].ip || "";
GlobalConfig.MS_PLAY_HLS_PORT = GlobalConfig.hlsList[index].port || "";
} else {
//没有单独的hls拉流地址,和录制回放地址一样即可
GlobalConfig.MS_PLAY_HLS_IP = GlobalConfig.RS_RECORD_PLAY_IP;
GlobalConfig.MS_PLAY_HLS_PORT = GlobalConfig.RS_RECORD_PLAY_PORT;
}
loger.log('初始->MSHls->.', GlobalConfig.MS_PLAY_HLS_IP, GlobalConfig.MS_PLAY_HLS_PORT);
//直播的时候,拉流(rtmp和hls)需要从 videoCDNAddr中获取
//20170531-新规则,所有课堂类型都支持加速
// if(GlobalConfig.classType==ApeConsts.CLASS_TYPE_2&&GlobalConfig.videoCDNAddrList.length>0){
//20170629-直播课堂和移动端设备的时候支持
if (GlobalConfig.classType == ApeConsts.CLASS_TYPE_2 || GlobalConfig.isMobile) {
if (GlobalConfig.videoCDNAddrList.length > 0) {
//videoCDNAddrList中rtmppush和hls是混在一起的,需要分离开;
let listLen = GlobalConfig.videoCDNAddrList.length;
for (let i = 0; i < listLen; i++) {
let ipItem = GlobalConfig.videoCDNAddrList[i];
if (ipItem) {
if (ipItem.indexOf('hls') >= 0) {
//直播的时候m3u8拉流地址
GlobalConfig.MS_PLAY_HLS_IP = ipItem; //ip包含了端口
GlobalConfig.MS_PLAY_HLS_PORT = "";
loger.log('videoCDNAddr>初始->MSHls', GlobalConfig.MS_PLAY_HLS_IP);
}
if (ipItem.indexOf('rtmppull')>= 0) {
//直播的时候rtmp拉流地址
GlobalConfig.MS_PLAY_RTMP_IP = ipItem; //ip包含了端口
GlobalConfig.MS_PLAY_RTMP_PORT = '';
loger.log('videoCDNAddr->初始->MSPull', GlobalConfig.MS_PLAY_RTMP_IP);
}
}
}
} else {
loger.error('videoCDNAddr数据无效->', GlobalConfig.videoCDNAddr);
}
} else {
loger.warn('非直播课堂或不是移动端->不需要videoCDN加速');
}
//文档地址
if (_data.docList && _data.docList.length > 0) {
//doc上传地址,随机获取一个
let index = parseInt(Math.random() * _data.docList.length);
loger.log("docServer->", _data.docList[index]);
GlobalConfig.DOCServerIP = _data.docList[index].ip || "";
GlobalConfig.DOCServerPort = _data.docList[index].port || "";
loger.log('初始->DOC->.', GlobalConfig.DOCServerIP, GlobalConfig.DOCServerPort);
}
//record
if (_data.recordList && _data.recordList.length > 0) {
let index = parseInt(Math.random() * _data.recordList.length);
GlobalConfig.RecordServerIP = _data.recordList[index].ip || "";
GlobalConfig.RecordServerPort = _data.recordList[index].port || "";
loger.log('初始->RECORD->.', GlobalConfig.RecordServerIP, GlobalConfig.RecordServerPort);
}
}
//这里需要考虑是否加延迟处理,课堂信息刚获取完成,客户端需要根据数据创建界面UI,等创建完成后再加入课堂是最合适的(目前没有加延迟)
this._emit(MessageTypes.CLASS_GET_INFO_SUCCESS, GlobalConfig.getClassInfo());
if (_data.currentInfo) {
//根据从Sass获取的数据信息,同步最后一次保存的课堂状态信息
loger.log("本地同步最后一次保存过的课堂状态信息");
try {
GlobalConfig.setClassStatusInfo(JSON.parse(_data.currentInfo));
} catch (err) {
loger.warn("从Sass获取的课堂数据JSON转换失败->");
console.log("currentInfo", _data.currentInfo);
GlobalConfig.setClassStatusInfo(_data.currentInfo);
}
loger.log(GlobalConfig.classStatusInfo);
} else {
loger.log("还没有保存过课堂状信息");
}
//录制回放不需要获取ip信息和选点
if (GlobalConfig.isRecordPlayBack) {
if (_recordPlayback) {
//开启录制回放流程
loger.log("开启录制回放流程");
_recordPlayback.readyRecordPlay();
} else {
loger.warn("开启录制回放流程失败->还未创建模块");
}
} else {
//根据用户的userIp获取信息,选点
this.getUserIpInfo();
}
}*/
//ChatApe
// 发送聊天消息
_sendChatMsg(_messageInfo) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": ""};
}
if (_messageInfo === null || EngineUtils.isEmptyObject(_messageInfo)) {
loger.log('发送聊天消息失败->参数错误', _messageInfo);
return {"code": ApeConsts.RETURN_FAILED, "data": ""};
}
if (_chat_ape) {
_chat_ape.sendChatMsg(_messageInfo);
}
}
//监听摄像头麦克风状态
userDeviecStatusChange(_data) {
/* nodeId:GlobalConfig.nodeId,
userRole:GlobalConfig.userRole,
userName:GlobalConfig.userName,
userId:GlobalConfig.userId,
openCamera:GlobalConfig.openCamera,
openMicrophones:GlobalConfig.openMicrophones*/
if (_confer_ape) {
_confer_ape.updaterUserDeviecStatusChange(_data);
}
}
//屏幕共享
//开始屏幕共享
_publishScreenShare(_param) {
if (_video_ape) {
_video_ape.publishScreenShare(_param);
}
}
//停止屏幕共享
_stopPublishScreenShare(_param) {
if (_video_ape) {
_video_ape.stopPublishScreenShare(_param);
}
}
//VidoeApe
videoUpdate(_data) {
//视频同步的消息发送改变,需要通知ferApe模块中的用户更新状态
if (_confer_ape) {
_confer_ape.updaterRosterStatus(_data);
}
}
_sendVideoBroadcastMsg(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": ""};
}
if (_video_ape) {
return _video_ape.sendVideoBroadcastMsg(_param);
}
}
_getVideoPlayPath(_param) {
if (_video_ape) {
return _video_ape.getPlayVideoPath(_param);
}
}
_getVideoPublishPath(_param) {
if (_video_ape) {
return _video_ape.getPublishVideoPath(_param);
}
}
_getVideoAllChannelInfo(_param) {
if (_video_ape) {
return _video_ape.getAllChannelInfo(_param);
}
}
_publishVideo(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": ""};
}
if (_video_ape) {
return _video_ape.publishVideo(_param);
}
}
_stopPublishVideo(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": ""};
}
if (_video_ape) {
return _video_ape.stopPublishVideo(_param);
}
}
//AudioApe
audioUpdate(_data) {
//音频同步的消息发送改变,需要通知ferApe模块中的用户更新状态
if (_confer_ape) {
_confer_ape.updaterRosterStatus(_data);
}
}
sendAudioCommandMsg(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": ""};
}
if (_audio_ape) {
return _audio_ape.sendAudioBroadcastMsg(_param);
}
}
_getPlayAudioPath(_param) {
if (_audio_ape) {
return _audio_ape.getAudioPlayPath(_param);
}
}
_getPublishAudioPath(_param) {
if (_audio_ape) {
return _audio_ape.getAudioPublishPath(_param);
}
}
_getAudioAllChannelInfo(_param) {
if (_audio_ape) {
return _audio_ape.getAllChannelInfo(_param);
}
}
_publishAudio(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": ""};
}
if (_audio_ape) {
return _audio_ape.publishAudio(_param);
}
}
_stopPublishAudio(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": ""};
}
if (_audio_ape) {
return _audio_ape.stopPublishAudio(_param);
}
}
//WhiteBoardApe
// 添加标注,发送信息
_sendInsertAnnotaion(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_whiteboard_ape) {
_whiteboard_ape.sendInsetAnnotaion(_param);
}
}
//CursorApe
// 添加鼠标同步
_sendInsertCursor(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_cursor_ape) {
_cursor_ape.sendInsertCursor(_param);
}
}
//删除当前页面上的所有标注
_sendDeleteCurPageAnnotation(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_whiteboard_ape) {
_whiteboard_ape.sendDeleteCurPageAnnotation(_param);
}
}
//删除所有标注
_sendDeleteAllAnnotation(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_whiteboard_ape) {
_whiteboard_ape.sendDeleteAllAnnotation(_param);
}
}
//返回上一步标注
_sendGotoPrev(_param) {
if (_whiteboard_ape) {
_whiteboard_ape.sendGotoPrev(_param);
}
}
//DocApe
//获取文档的所有资源地址
_getDocFullAddress(_param) {
if (_doc_ape) {
return _doc_ape.getDocFullAddress(_param);
} else {
loger.error("文档模块还没有创建无法获取");
return {"code": ApeConsts.RETURN_FAILED, "data": "文档模块还没有创建无法获取"};
}
}
//获取文档完整路径
_getDocImageFullPath(_param) {
if (_doc_ape) {
return _doc_ape.getDocImageFullPath(_param);
} else {
loger.error("文档模块还没有创建无法获取");
return [];
}
}
_getDocPDFFullPath(_param) {
if (_doc_ape) {
return _doc_ape.getDocPDFFullPath(_param);
} else {
loger.error("文档模块还没有创建,无法获取");
return [];
}
}
//上传文档
_sendDocumentUpload(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_doc_ape) {
_doc_ape.documentUpload(_param);
}
}
//切换文档
_sendDocumentSwitchDoc(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_doc_ape) {
_doc_ape.documentSwitchDoc(_param);
}
}
//操作文档(翻页)
_sendDocumentSwitchPage(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_doc_ape) {
_doc_ape.documentSwitchPage(_param);
}
}
//操作文档(页码上的动画步骤操作)
_sendDocumentSwitchAnimation(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_doc_ape) {
_doc_ape.documentSwitchAnimation(_param);
}
}
//操作文档(缩放、滚动...)
_sendDocumentCommand(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_doc_ape) {
_doc_ape.documentCommand(_param);
}
}
//删除文档
_sendDocumentDelete(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_doc_ape) {
_doc_ape.documentDelete(_param);
}
}
//删除所有文档
_documentDeleteAll(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_doc_ape) {
_doc_ape.documentDeleteAll(_param);
}
}
//// 文档变更,白板也需要做处理
docUpdateHandler(_data) {
if (!_mcu.connected && !GlobalConfig.isRecordPlayBack) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
//loger.log('Doc UpdateId ->');
//loger.log(_data);
if (_whiteboard_ape) {
_whiteboard_ape.docUpdateHandler(_data);
}
}
//文档删除,白板也需要做处理
docDeleteHandler(_data) {
if (_whiteboard_ape) {
_whiteboard_ape.docDeleteHandler(_data);
}
}
//文档加入频道成功,同步到MCU服务器上的数据
docJoinChannelSuccess() {
loger.log("docJoinChannelSuccess->isHost=", GlobalConfig.isHost, "当前总人数:", GlobalConfig.rosterNumber, "sassDoclength=", GlobalConfig.docListPrepare.length);
//loger.log("docJoinChannelSuccess docListPrepare=");
//如果是主持人,那么需要判断一下文档模块同步的数据和从sass获取的文档数据是否相同,如果mcu服务器不存在的,需要上传
if (GlobalConfig.docListPrepare && GlobalConfig.docListPrepare.length > 0) {
//如果当前身份是老师或者当前课堂内只有一个人,有权限同步文档到MCU
if (GlobalConfig.isHost || GlobalConfig.rosterNumber <= 1) {
for (let i = 0; i < GlobalConfig.docListPrepare.length; i++) {
let value = GlobalConfig.docListPrepare[i];
if (value) {
//loger.log("判断是否需要把提前上传的文档上传到mcu", value);
let paramInfo = {
"pageNum": value.pdfSize,
"fileName": value.name,
"fileType": value.type,
"relativeUrl": value.relativeLocation,
"url": value.absoluteLocation,
"creatUserId": value.createUserID,
"docId": value.id,
"md5": value.MD5,
"visible": false
};
this._sendDocumentUpload(paramInfo);
}
}
}
}
}
//媒体共享模块的接口
//上传
_sendMediaSharedUpload(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_mediaShareApe) {
_mediaShareApe.mediaSharedUpload(_param);
}
}
//音乐共享模块的接口
//上传
_sendMusicSharedUpload(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_musicShareApe) {
_musicShareApe.musicSharedUpload(_param);
}
}
//Sass删除媒体文件数据
_sassDeletMediaShare(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
//判断传入的参数是否存在
if (_param == null || EngineUtils.isEmptyObject(_param)) {
loger.error('删除媒体文件失败->参数错误', _param);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_MEDIASHARE_DELETE_FAILED_PARAM);
return;
}
//判断必要的参数字段值
if (_param.itemIdx == null || isNaN(_param.itemIdx) || _param.fileId == null || _param.fileId == "") {
loger.error('删除媒体文件失败->', _param);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_MEDIASHARE_DELETE_FAILED_PARAM);
return;
}
loger.log('删除媒体文件->', _param);
if (_sass) {
_sass.sassDeletMediaShare(_param);
}
}
// 删除Music
_sassDeletMusicShare(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
//判断传入的参数是否存在
if (_param == null || EngineUtils.isEmptyObject(_param)) {
loger.error('删除媒体文件失败->参数错误', _param);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_MUSICSHARE_DELETE_FAILED_PARAM);
return;
}
//判断必要的参数字段值
if (_param.itemIdx == null || isNaN(_param.itemIdx) || _param.fileId == null || _param.fileId == "") {
loger.error('删除媒体文件失败->', _param);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_MUSICSHARE_DELETE_FAILED_PARAM);
return;
}
loger.log('删除媒体文件->', _param);
if (_sass) {
_sass.sassDeletMusicShare(_param);
}
}
//删除媒体
_sendMediaSharedDelete(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_mediaShareApe) {
_mediaShareApe.mediaSharedDelete(_param);
}
}
//删除媒体
_sendMusicSharedDelete(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_musicShareApe) {
_musicShareApe.musicSharedDelete(_param);
}
}
//音乐更新
_sendMusicSharedUpdate(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_musicShareApe) {
_musicShareApe.musicSharedUpdate(_param);
}
}
//音乐播放
_sendMusicSharedPlay(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_musicShareApe) {
_musicShareApe.musicSharedPlay(_param);
}
}
//音乐停止
_sendMusicSharedStop(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_musicShareApe) {
_musicShareApe.musicSharedStop(_param);
}
}
//更新媒体文件的状态信息
_sendMediaSharedUpdate(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_mediaShareApe) {
_mediaShareApe.mediaSharedUpdate(_param);
}
}
//播放
_sendMediaSharedPlay(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_mediaShareApe) {
_mediaShareApe.mediaSharedPlay(_param);
}
}
//停止
_sendMediaSharedStop(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_mediaShareApe) {
_mediaShareApe.mediaSharedStop(_param);
}
}
//音乐共享模块加入频道成功,同步到MCU服务器上的数据
musicShareApeJoinChannelSuccess() {
loger.log("伴音MUSIC模块加入频道成功->isHost=", GlobalConfig.isHost, "length=", GlobalConfig.musicListPrepare.length);
console.log("伴音MUSIC模块共享模数据->", GlobalConfig.musicListPrepare);
//如果是主持人,那么需要判断一下文档模块同步的数据和从sass获取的文档数据是否相同,如果mcu服务器不存在的,需要上传
if (GlobalConfig.isHost && GlobalConfig.musicListPrepare.length > 0) {
for (let i = 0; i < GlobalConfig.musicListPrepare.length; i++) {
let value = GlobalConfig.musicListPrepare[i];
if (value) {
let paramInfo = {
"status": 0,
"creatUserId": value.creatUserId,
"creatUserName": value.createUserName,
"url": value.url || value.absoluteLocation,//伴音上传的接口有差异,课堂内上传返回的是url字段,后台带入的字段是absoluteLocation
"fileType": value.type,
"fileId": "" + value.id,
"fileName": value.name,
"seek": 0
};
this._sendMusicSharedUpload(paramInfo);
}
}
}
}
//媒体共享模块加入频道成功,同步到MCU服务器上的数据
mediaShareApeJoinChannelSuccess() {
loger.log("媒体共享模块加入频道成功->isHost=", GlobalConfig.isHost, "length=", GlobalConfig.sharedMediaList.length);
console.log("媒体共享模数据->", GlobalConfig.sharedMediaList);
//如果是主持人,那么需要判断一下文档模块同步的数据和从sass获取的文档数据是否相同,如果mcu服务器不存在的,需要上传
if (GlobalConfig.isHost && GlobalConfig.sharedMediaList.length > 0) {
for (let i = 0; i < GlobalConfig.sharedMediaList.length; i++) {
let value = GlobalConfig.sharedMediaList[i];
if (value) {
let paramInfo = {
"status": 0,
"creatUserId": value.creatUserId,
"creatUserName": value.createUserName,
"url": value.url,
"fileType": value.type,
"fileId": "" + value.id,
"fileName": value.name,
"seek": 0
};
this._sendMediaSharedUpload(paramInfo);
}
}
}
}
//录制回放相关的处理------------------------------------------------
//录制回放初始化
_initRecordPlayback(_param) {
//{"classId":"1653304953","portal":"112.126.80.182:80","userRole":"normal","userId":0}
if (_param == null) {
loger.error('录制回放初始化失败->参数错误');
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_INIT_RECORD_PLAY_BACK_FAILED);
return;
}
//判断必要的参数字段值
if (_param.classId == null || isNaN(_param.classId) || _param.portal == null || _param.portal == "") {
loger.error('录制回放初始化失败->', _param);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_INIT_RECORD_PLAY_BACK_FAILED);
return;
}
loger.log('录制回放初始化->', _param);
//保存参数
GlobalConfig.isRecordPlayBack = true; //设置为录制回放状态
GlobalConfig.classId = parseInt(_param.classId);
GlobalConfig.portal = _param.portal;
GlobalConfig.userRole = ApeConsts.normal; //*************很重要,录制回放的时候,身份模式是普通人********
GlobalConfig.userId = _param.userId || "0";
GlobalConfig.userName = _param.userName || "";
//获取课堂最完整的数据,录制回放需要获取课堂数据
if (_sass) {
_sass.getClassParam();
}
}
//开始录制回放
_startRecordPlayback(_param) {
if (_recordPlayback) {
_recordPlayback.startRecordPlayback(_param);
}
}
//停止录制回放
_stopRecordPlayback(_param) {
if (_recordPlayback) {
_recordPlayback.stopRecordPlayback(_param);
}
}
//暂停录制回放
_pauseRecordPlayback(_param) {
if (_recordPlayback) {
_recordPlayback.pauseRecordPlayback(_param);
}
}
//seek录制回放
_seekRecordPlayback(_param) {
if (_recordPlayback) {
_recordPlayback.seekRecordPlayback(_param);
}
}
//录制回放状态更新
_recordPlaybackClearDataHandler(_param) {
loger.log("录制回放状态更新->")
if (_doc_ape) {
_doc_ape.clearData();
}
if (_whiteboard_ape) {
_whiteboard_ape.clearData();
}
if (_video_ape) {
_video_ape.clearData();
}
}
//录制回放加入 课堂成功
_joinRecordPlaybackSuccessHandler(_data) {
loger.log('加入录制回放成功.');
GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_2);
//返回给客户端初始化成功的数据
let joinClassSuccessCallBackData = {};
joinClassSuccessCallBackData.isRecordPlayBack = GlobalConfig.isRecordPlayBack;
joinClassSuccessCallBackData.DOCServerIP = GlobalConfig.DOCServerIP;
joinClassSuccessCallBackData.DOCServerPort = GlobalConfig.DOCServerPort;
joinClassSuccessCallBackData.classStatus = GlobalConfig.classStatus;
joinClassSuccessCallBackData.classId = GlobalConfig.classId;
joinClassSuccessCallBackData.className = GlobalConfig.className;
joinClassSuccessCallBackData.h5Module = GlobalConfig.h5Module;
joinClassSuccessCallBackData.isHost = GlobalConfig.isHost; //
joinClassSuccessCallBackData.maxAudioChannels = GlobalConfig.maxAudioChannels;
joinClassSuccessCallBackData.maxVideoChannels = GlobalConfig.maxVideoChannels;
joinClassSuccessCallBackData.maxMediaChannels = GlobalConfig.maxMediaChannels;
joinClassSuccessCallBackData.mcuDelay = GlobalConfig.mcuDelay;
joinClassSuccessCallBackData.msType = GlobalConfig.msType;
joinClassSuccessCallBackData.nodeId = GlobalConfig.nodeId;
joinClassSuccessCallBackData.password = GlobalConfig.password;
joinClassSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired; // 老师的默认是true
//GlobalConfig.passwordRequired 老师的默认是true
//GlobalConfig.portal=_data.portal;
joinClassSuccessCallBackData.role = GlobalConfig.role;
joinClassSuccessCallBackData.siteId = GlobalConfig.siteId;
joinClassSuccessCallBackData.topNodeID = GlobalConfig.topNodeID;
joinClassSuccessCallBackData.userId = GlobalConfig.userId;
joinClassSuccessCallBackData.userName = GlobalConfig.userName;
joinClassSuccessCallBackData.userRole = GlobalConfig.userRole;
joinClassSuccessCallBackData.userType = GlobalConfig.userType;
joinClassSuccessCallBackData.siteId = GlobalConfig.siteId;
joinClassSuccessCallBackData.classId = GlobalConfig.classId;
joinClassSuccessCallBackData.userRole = GlobalConfig.userRole;
joinClassSuccessCallBackData.userId = GlobalConfig.userId;
joinClassSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired;
joinClassSuccessCallBackData.classType = GlobalConfig.classType || ApeConsts.CLASS_TYPE_1;
joinClassSuccessCallBackData.country = GlobalConfig.country; //国家
joinClassSuccessCallBackData.city = GlobalConfig.city; //城市
joinClassSuccessCallBackData.province = GlobalConfig.province; //服务商
joinClassSuccessCallBackData.isp = GlobalConfig.isp; //服务商
joinClassSuccessCallBackData.classTimestamp = GlobalConfig.classTimestamp; //课堂进行的累积时间
joinClassSuccessCallBackData.recordTimestamp = GlobalConfig.recordTimestamp; //录制累积的总时间
joinClassSuccessCallBackData.recordPlaybackMaxTime = GlobalConfig.recordPlaybackMaxTime; //录制回放的总时间
joinClassSuccessCallBackData.fps = GlobalConfig.fps;
joinClassSuccessCallBackData.gop = GlobalConfig.gop;
joinClassSuccessCallBackData.videoQuality = GlobalConfig.videoQuality;
joinClassSuccessCallBackData.ssTunnelAppURL = GlobalConfig.ssTunnelAppURL;
joinClassSuccessCallBackData.currentSceneTableId = GlobalConfig.currentSceneTableId; //文档区域的模块显示
joinClassSuccessCallBackData.serverAndLoacTimeDistanc = GlobalConfig.serverAndLoacTimeDistanc;
joinClassSuccessCallBackData.deviceType = GlobalConfig.deviceType;
joinClassSuccessCallBackData.language = GlobalConfig.language;
joinClassSuccessCallBackData.explorer = GlobalConfig.explorer;
joinClassSuccessCallBackData.explorerVersion = GlobalConfig.explorerVersion;
joinClassSuccessCallBackData.os = GlobalConfig.os;
loger.log(joinClassSuccessCallBackData);
//和加入课堂成功使用同样的消息处理
this._emit(MessageTypes.CLASS_JOIN_SUCCESS, joinClassSuccessCallBackData);
}
// //答题卡
_creatQuestion(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_questionApe) {
_questionApe.creatQuestion(_param);
}
}
_getQuestion(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_questionApe) {
_questionApe.getQuestion(_param);
}
}
_getQuestionResult(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_questionApe) {
_questionApe.getQuestionResult(_param);
}
}
_stopQuestion(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_questionApe) {
_questionApe.stopQuestion(_param);
}
}
_sendAnswer(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_questionApe) {
_questionApe.sendAnswer(_param);
}
}
}
... ... @@ -135,7 +135,8 @@ class GlobalConfig {
this.classTimestamp = data.classTimestamp || this.classTimestamp; //相对于点开始课堂的时间戳
this.recordStatus = data.recordStatus || this.recordStatus; //当前录制状态
//this.recordStatus = data.recordStatus || this.recordStatus; //当前录制状态
this.recordStatus = data.recordStatus ||false; //当前录制状态
this.recordTimestamp = data.recordTimestamp || this.recordTimestamp; //相对于首次开始录制的时间戳
this.recordFileName = data.recordFileName || this.recordFileName; //录制的文件名
this.recordDownloadUrl = data.recordDownloadUrl || this.recordDownloadUrl; //下载地址
... ... @@ -522,7 +523,7 @@ GlobalConfig.recordReplaytickValues = {}; // 滚动条关键点,用于快进
GlobalConfig.isAutoStartClass = 0; //是否自动开始上课 0-否 ;1 是
GlobalConfig.updateClassInfoDelay = 30; //(秒),每隔30秒同步一次课堂状态的并保存到Sass
GlobalConfig.updateClassInfoDelay = 20; //(秒),每隔30秒同步一次课堂状态的并保存到Sass
GlobalConfig.msDynamicChooseIpDelay = 60 * 3; //(秒)MS动态选点的间隔
//GlobalConfig.serverTimestamp=0;//当前的系统时间戳 用get set 获取
... ... @@ -540,7 +541,7 @@ GlobalConfig.classDetail = {}; //Sass直接返回的当前课堂基本信息
GlobalConfig.isRecordPlayBack = false; //是否是录制回放,默认是否
GlobalConfig.allowRecordMaxTime = 24*60*60; //(秒)允许录制的最长时间
GlobalConfig.allowRecordMaxTime = 48*60*60; //(秒)允许录制的最长时间
GlobalConfig.siteId_letv = 'shchuanbao'; //乐视,MS不需要动态选点的站点
GlobalConfig.ssTunnelAppURL = ''; //屏幕共享插件的地址
... ...
... ... @@ -7,7 +7,6 @@ import ApeConsts from './ApeConsts';
import ThirdMessage from './ThirdMessage';
import MessageTypes from 'MessageTypes';
import pdu from 'pdus';
//import { Zlib } from 'zlibjs/bin/zlib.min';
import UTF8 from 'utf-8';
import Loger from 'Loger';
import GlobalConfig from 'GlobalConfig';
... ... @@ -28,6 +27,7 @@ class ConferApe extends Ape {
this.rosters = {}; //用户列表
this.rosterLen = 0;//当前课堂人数
this.timerCounter = new TimerCounter(); //计时器
this.startClassTimer;//开始课堂和开始录制的计时器
//第三方消息控制 parent和Iframe直接的通讯
this.thirdMessage = new ThirdMessage();
... ... @@ -246,7 +246,6 @@ class ConferApe extends Ape {
//保存当前的录制状态
GlobalConfig.recordStatus = _param.recordStatus || false;
let conferRecordSendPdu = new pdu['RCConferenceRecordRequestPdu'];
conferRecordSendPdu.type = pdu.RCPDU_CONFERENCE_RECORD_REQUEST;
conferRecordSendPdu.peer = 0; //channel 为0
... ... @@ -257,9 +256,12 @@ class ConferApe extends Ape {
//conferRecordSendPdu.classTime = GlobalConfig.classTimestamp;//不能使用课堂进行时间,这个时间结束课堂的时候会被清除
conferRecordSendPdu.classTime = GlobalConfig.recordTimestamp; //课堂录制的累积时间,不会被清除
conferRecordSendPdu.filename = GlobalConfig.recordFileName || GlobalConfig.classId + "_" + EngineUtils.creatTimestampYMD() + ".rec";
if(GlobalConfig.recordStatus){
loger.log("发送录制的指令->开启",conferRecordSendPdu);
}else {
loger.log("发送录制的指令->停止",conferRecordSendPdu);
}
this.sendChatUniform(conferRecordSendPdu);
// to, message
loger.warn('发送录制消息-》', _param);
}
//开启录制
... ... @@ -270,22 +272,27 @@ class ConferApe extends Ape {
return;
}
loger.warn('开启录制', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus);
//如果是host
if (GlobalConfig.isHost) {
GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
this.sendConferRecordMsg({"recordStatus": true});
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
this._emit(MessageTypes.CLASS_RECORD_START); //课堂开始录制
//如果是host或者当前课堂只有1个人
if (GlobalConfig.isHost||this.rosterLen<=1) {
if(GlobalConfig.recordStatus){
loger.warn("课堂已经是录制状态不->不需要再开启,isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus,"当前人数:"+this.rosterLen);
}else{
loger.warn('开启录制', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus,"当前人数:"+this.rosterLen);
GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
this.sendConferRecordMsg({"recordStatus": true});
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
this._emit(MessageTypes.CLASS_RECORD_START); //课堂开始录制
}
}
}
//停止录制
stopRecord(isForce) {
loger.warn('停止录制', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus);
if (isForce && isForce == true) {
/* if (isForce && isForce == true) {
//强制停止,可以是host之外的身份(比如当前课堂老师异常退出,没有老师,会随机选择一个人来做释放操作)
if (GlobalConfig.recordStatus) {
loger.warn('停止录制', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus);
GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
this.sendConferRecordMsg({"recordStatus": false});
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
... ... @@ -297,6 +304,15 @@ class ConferApe extends Ape {
this.sendConferRecordMsg({"recordStatus": false});
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
}
}*/
//身份是host
if (GlobalConfig.isHost) {
loger.warn('停止录制', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus);
GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
this.sendConferRecordMsg({"recordStatus": false});
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
}else {
loger.warn('没有权限停止录制', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus);
}
}
... ... @@ -339,9 +355,10 @@ class ConferApe extends Ape {
GlobalConfig.classTimestamp = 0;
GlobalConfig.classStatus = ApeConsts.CLASS_STATUS_WAIT;
GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
this.stopRecord();
//this.stopRecord();//停止录制的接口单独调用
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
this.sendUpdaterClassStatusInfo({"actionType": 0, isStopAllPublishMedia: true});
//this.sendUpdaterClassStatusInfo({"actionType": 0, isStopAllPublishMedia: true});
this.sendUpdaterClassStatusInfo({"actionType": ApeConsts.CLASS_STATUS_WAIT, isStopAllPublishMedia: false});
loger.log('restorClass');
}
... ... @@ -376,7 +393,6 @@ class ConferApe extends Ape {
//开始上课
startClass(_param) {
if (GlobalConfig.isHost) {
let timestamp = EngineUtils.creatTimestampStr();
GlobalConfig.classStopTime = timestamp;
... ... @@ -391,13 +407,13 @@ class ConferApe extends Ape {
}
GlobalConfig.classStatus = ApeConsts.CLASS_STATUS_STARTED;
//开始录制
this.startRecord();
//课堂状态改变
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
////开始录制
//this.startRecord();
////课堂状态改变
//this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
//同步课堂状态
this.sendUpdaterClassStatusInfo({"actionType": 1, isStopAllPublishMedia: true});
//this.sendUpdaterClassStatusInfo({"actionType": 1, isStopAllPublishMedia: true});
this.sendUpdaterClassStatusInfo({"actionType": ApeConsts.CLASS_STATUS_STARTED, isStopAllPublishMedia: false});
//开始计时
this.startTimerCounter();
} else {
... ... @@ -414,9 +430,10 @@ class ConferApe extends Ape {
GlobalConfig.classStatus = ApeConsts.CLASS_STATUS_PAUSE;
GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
this.stopRecord();
//this.stopRecord();
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE, _param);
this.sendUpdaterClassStatusInfo({"actionType": 2, isStopAllPublishMedia: true});
//this.sendUpdaterClassStatusInfo({"actionType": 2, isStopAllPublishMedia: true});
this.sendUpdaterClassStatusInfo({"actionType": ApeConsts.CLASS_STATUS_PAUSE, isStopAllPublishMedia: false});
this.stopTimerCounter();
}
... ... @@ -426,11 +443,12 @@ class ConferApe extends Ape {
loger.warn('还没有开始,不能点关闭');
return;
}
loger.warn("调用关闭课堂->");
this.stopTimerCounter();
this.restorClass();
//把所有人都踢出课堂
this.sendConferMsg({"to": 0, "message": "所有人退出课堂", "actionType": ApeConsts.CLASS_ACTION_CLOSE_ALL});
this.stopRecord();//关闭课堂的时候停止录制
}
//更新设备信息
... ... @@ -525,7 +543,7 @@ class ConferApe extends Ape {
//保存数据到Sass
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
//同步消息给其他人
this.sendUpdaterClassStatusInfo({"actionType": 1, isStopAllPublishMedia: false});
this.sendUpdaterClassStatusInfo({"actionType": ApeConsts.CLASS_STATUS_STARTED, isStopAllPublishMedia: false});
}
}
... ... @@ -542,7 +560,6 @@ class ConferApe extends Ape {
}
let itemIdx = ApeConsts.CONFERENCE_OBJ_TABLE_ID; // itemIdx=_param.itemIdx;
let modelPdu = this.packPdu(_param, itemIdx);
loger.log(modelPdu);
if (modelPdu == null) {
loger.log('发送更新课堂信息->参数错误');
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
... ... @@ -582,14 +599,32 @@ class ConferApe extends Ape {
/////收到消息处理/////////////////////////////////////////////////////////////////////////////////
//加入channel成功
onJoinChannelHandlerSuccess() {
loger.log('ConferApe.onJoinChannelHandlerSuccess', GlobalConfig.classStatus);
if(GlobalConfig.isRecordPlayBack){
loger.log('课堂模块初始完成->当前是录制回放:'+ GlobalConfig.classStatus);
return;
}
loger.log('课堂模块初始完成->当前课堂状态:'+ GlobalConfig.classStatus,"recordStatus:"+GlobalConfig.recordStatus);
this.timerCounter.addTimerCallBack(this.timerCounterUptate.bind(this), 1);
//如果当前课堂正在进行中,开启计时器
//2秒后执行开始上课和开始录制的判断逻辑
clearTimeout(this.startClassTimer);
this.startClassTimer=setTimeout(()=>{
//开启录制,录制接口中会自动判断是否需要录制
this.startRecord();
//如果当前课堂正在进行中,开启计时器
if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) {
//开始计时
this.startTimerCounter();
//this.startRecord();
} else {
loger.log('自动开始上课->classStatus:', GlobalConfig.classStatus, " isHost:", GlobalConfig.isHost, " isAutoStartClass:", GlobalConfig.isAutoStartClass, " isRecordPlayBack:", GlobalConfig.isRecordPlayBack);
this.startClass();
}
},2000);
/* //如果当前课堂正在进行中,开启计时器
if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) {
//开始计时
this.startTimerCounter();
//如果是host ,开始录制
this.startRecord();
} else if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_WAIT &&
GlobalConfig.isHost && GlobalConfig.isAutoStartClass && !GlobalConfig.isRecordPlayBack) {
... ... @@ -597,7 +632,8 @@ class ConferApe extends Ape {
//1.如果自己是host,2.Sass配置的是自动开始上课,3.并且当前是未开始状态,4.当前不是录制回放,开始自动上课
loger.log('自动开始上课->classStatus:', GlobalConfig.classStatus, " isHost:", GlobalConfig.isHost, " isAutoStartClass:", GlobalConfig.isAutoStartClass, " isRecordPlayBack:", GlobalConfig.isRecordPlayBack);
this.startClass();
}
}*/
}
//开启计时器
... ... @@ -606,7 +642,6 @@ class ConferApe extends Ape {
if (this.timerCounter) {
this.timerCounter.startTimer();
}
}
//停止计时器
... ... @@ -621,46 +656,92 @@ class ConferApe extends Ape {
if (!this.mcu.connected) {
loger.warn('MCU 连接已经断开');
this.stopTimerCounter();
}
//如果还没开始或已经暂停、关闭,不做计时处理
if (GlobalConfig.classStatus != ApeConsts.CLASS_STATUS_STARTED) {
loger.warn('当前课堂已经暂停或者未开始,不计时', "classStatus-->", GlobalConfig.classStatus);
return;
}
GlobalConfig.classTimestamp = GlobalConfig.classTimestamp + 1; //计时
//课堂开始的状态下,课堂进行时间和录制时间都需要更加,录制时间会大于或等于课堂开始的累积时间
if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) {
GlobalConfig.classTimestamp = GlobalConfig.classTimestamp + 1; //计时
//老师身份的时候要记录录制的时间
if (GlobalConfig.isHost||this.rosterLen<=1) {
GlobalConfig.recordTimestamp = GlobalConfig.recordTimestamp + 1;
}
//向应用层更新当前课堂进行的时间长度 (秒)
this._emit(MessageTypes.CLASS_UPDATE_TIMER, {"classTimestamp": GlobalConfig.classTimestamp});
//以一定的时间间隔同步课堂内所有人的累积上课时间
if (GlobalConfig.classTimestamp % GlobalConfig.updateClassInfoDelay == 0) {
//如果是host身份,需要同步时间给其他人,同时把当前的状态上传到服务器
if (GlobalConfig.isHost||this.rosterLen<=1) {
//保存数据到Sass
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
//同步消息给其他人
this.sendUpdaterClassStatusInfo({"actionType": ApeConsts.CLASS_STATUS_STARTED, isStopAllPublishMedia: false});
}
}
//老师身份的时候要记录录制的时间
if (GlobalConfig.isHost) {
GlobalConfig.recordTimestamp = GlobalConfig.recordTimestamp + 1;
//进行MS动态选点,选择最快的MS服务器地址(录制回放不做处理)
if (!GlobalConfig.isRecordPlayBack && GlobalConfig.classTimestamp % GlobalConfig.msDynamicChooseIpDelay == 0) {
//MS推流选点
this._emit(MessageTypes.SWITCH_MS_IP);
//MS拉流选点
this._emit(MessageTypes.SWITCH_RTMP_PULL_IP);
//HLS拉流选点
this._emit(MessageTypes.SWITCH_HLS_IP);
}
}else {
//课堂暂停或未开始的情况下,如果已经开始录制,需要更新录制的时间
if (GlobalConfig.isHost||this.rosterLen<=1) {
GlobalConfig.recordTimestamp = GlobalConfig.recordTimestamp + 1;
//以一定的时间间隔同步课堂内所有人的累积上课时间
if (GlobalConfig.classTimestamp % GlobalConfig.updateClassInfoDelay == 0) {
//保存数据到Sass
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
//同步消息给其他人
this.sendUpdaterClassStatusInfo({"actionType": ApeConsts.CLASS_STATUS_STARTED, isStopAllPublishMedia: false});
}
}
}
//loger.log('课堂进行时间',GlobalConfig.classTimestamp);
this._emit(MessageTypes.CLASS_UPDATE_TIMER, {"classTimestamp": GlobalConfig.classTimestamp});
if (GlobalConfig.classTimestamp % GlobalConfig.updateClassInfoDelay == 0) {
//如果是host身份,需要同步时间给其他人,同时把当前的状态上传到服务器
if (GlobalConfig.isHost) {
//保存数据到Sass
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
/* //如果还没开始或已经暂停、关闭,不做计时处理
if (GlobalConfig.classStatus != ApeConsts.CLASS_STATUS_STARTED) {
loger.warn('当前课堂已经暂停或者未开始,不计时', "classStatus-->", GlobalConfig.classStatus);
return;
}
GlobalConfig.classTimestamp = GlobalConfig.classTimestamp + 1; //计时
//同步消息给其他人
this.sendUpdaterClassStatusInfo({"actionType": 1, isStopAllPublishMedia: false});
}
}
//老师身份的时候要记录录制的时间
if (GlobalConfig.isHost) {
GlobalConfig.recordTimestamp = GlobalConfig.recordTimestamp + 1;
}
//向应用层更新当前课堂进行的时间长度 (秒)
this._emit(MessageTypes.CLASS_UPDATE_TIMER, {"classTimestamp": GlobalConfig.classTimestamp});
//以一定的时间间隔同步课堂内所有人的累积上课时间
if (GlobalConfig.classTimestamp % GlobalConfig.updateClassInfoDelay == 0) {
//如果是host身份,需要同步时间给其他人,同时把当前的状态上传到服务器
if (GlobalConfig.isHost) {
//保存数据到Sass
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
//同步消息给其他人
this.sendUpdaterClassStatusInfo({"actionType": ApeConsts.CLASS_STATUS_STARTED, isStopAllPublishMedia: false});
}
}
//进行MS动态选点,选择最快的MS服务器地址(录制回放不做处理)
if (!GlobalConfig.isRecordPlayBack && GlobalConfig.classTimestamp % GlobalConfig.msDynamicChooseIpDelay == 0) {
//MS推流选点
this._emit(MessageTypes.SWITCH_MS_IP);
//MS拉流选点
this._emit(MessageTypes.SWITCH_RTMP_PULL_IP);
//HLS拉流选点
this._emit(MessageTypes.SWITCH_HLS_IP);
}
//进行MS动态选点,选择最快的MS服务器地址(录制回放不做处理)
if (!GlobalConfig.isRecordPlayBack && GlobalConfig.classTimestamp % GlobalConfig.msDynamicChooseIpDelay == 0) {
//MS推流选点
this._emit(MessageTypes.SWITCH_MS_IP);
//MS拉流选点
this._emit(MessageTypes.SWITCH_RTMP_PULL_IP);
//HLS拉流选点
this._emit(MessageTypes.SWITCH_HLS_IP);
}*/
}
tableUpdateHandler(owner, itemIdx, itemData) {
try {
let model = this.unPackPdu(owner, itemIdx, itemData);
loger.log("课堂更新->",model);
//处理课堂更新的信息
if (model && model.classStatusInfo) {
try {
... ... @@ -668,9 +749,7 @@ class ConferApe extends Ape {
} catch (err) {
}
GlobalConfig.setClassStatusInfo(model.classStatusInfo);
if (model.classStatusInfo.isStopAllPublishMedia) {
//课堂状态发送改变 需要对当前正在推的流进行停止,因为录制的问题;
this._emit(MessageTypes.STOP_ALL_MEDIA_PUBLISH);
... ... @@ -697,16 +776,11 @@ class ConferApe extends Ape {
this.stopTimerCounter();
}
} catch (err) {
loger.warn('ConferApe table update got exception->err', err.message);
loger.warn('课堂更新->error', err.message);
}
}
conferMsgComingHandler(_data) {
//flash RCConferenceSendDataRequestPdu
//loger.warn('conferMsgComingHandler needs to be handled.');
//const recordInfo = pdu['RCWhiteboardDataRequestPdu'].decode(pdu);
//loger.log("conferMsgComingHandler",recordInfo);
let chatReceivePdu = pdu['RCConferenceSendDataRequestPdu'].decode(_data);
let chatMsg = {};
... ... @@ -823,19 +897,26 @@ class ConferApe extends Ape {
//------------------第三方消息 end-----------------------------------------
//监听MCU录制状态消息
onSendConferRecordRequestHandler(_data) {
try {
let conferRecordSendPdu = pdu['RCConferenceRecordRequestPdu'].decode(_data);
// {"initiator":820461225,"record":false,"classTime":3213,"filename":"h5dev/20170410/1437784290_20170410.rec"}
loger.log("录制回放控制操作成功->", conferRecordSendPdu);
if (conferRecordSendPdu && conferRecordSendPdu.record == true || conferRecordSendPdu.record == "true") {
//每次开启录制的时候,需要把当前显示的文档数据更新一次,否则无法录制已经显示的文件
this._emit(MessageTypes.CLASS_RECORD_SUCCESS);
//{"initiator":564398684,"record":true,"classTime":39,"filename":"markettest/20170823/1096250804_20170823.rec"}//开启成功
//{"initiator":564398684,"record":false,"classTime":39,"filename":"markettest/20170823/1096250804_20170823.rec"} //停止成功
loger.warn("录制回放控制操作成功->", conferRecordSendPdu);
if (conferRecordSendPdu ){
if(conferRecordSendPdu.record == true || conferRecordSendPdu.record == "true") {
//每次开启录制的时候,需要把当前显示的文档数据更新一次,否则无法录制已经显示的文件
loger.warn("MCU已经开启录制");
this._emit(MessageTypes.CLASS_RECORD_SUCCESS);
}else{
//停止录制成功
loger.warn("MCU已经停止录制");
}
}
} catch (err) {
loger.warn("录制回放控制操作错误->", err.message);
loger.error("录制回放控制操作错误->", err.message);
}
}
rosterInsertHandler(nodeId, nodeData) {
... ... @@ -858,10 +939,10 @@ class ConferApe extends Ape {
// 1.当前课堂只有自己;2.自己的身份不是host;3当前的课堂状态为(CLASS_STATUS_STARTED= 1;//直播中)
this.rosterLen = Object.keys(this.rosters).length;
GlobalConfig.rosterNumber = this.rosterLen;//记录当前的总人数
if (this.rosterLen < 1 && !GlobalConfig.isHost && GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) {
if (this.rosterLen <=1 && !GlobalConfig.isHost && GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) {
loger.warn("当前课堂没有老师->暂停课堂");
this.pauseClass({isForce: true});
this.stopRecord(true);
//this.stopRecord(true);
}
//处理用户信息
this.unPackRosterInfo(nodeId, nodeData);
... ... @@ -882,10 +963,11 @@ class ConferApe extends Ape {
deviceType: nodeData.deviceType
}
if (nodeData.role == ApeConsts.NR_HOST && GlobalConfig.isHost) {
loger.warn("相同身份的人进入->自己被踢出->进入的人员信息", nodeData);
this.kickOutRoster(newUserInfo);
return;
} else if (nodeData.userId == GlobalConfig.userId && GlobalConfig.userId != "0") {
loger.log("异地登陆->userId->", GlobalConfig.userId);
loger.warn("异地登陆->userId->", GlobalConfig.userId);
this._emit(MessageTypes.MCU_ERROR, {type:MessageTypes.ERR_CLASS_REMOTE_LANDING, data:newUserInfo});
this._emit(MessageTypes.CLASS_RUN_EXIT, {'type': 1});
}
... ... @@ -929,14 +1011,14 @@ class ConferApe extends Ape {
newNodeData.userData = userDataObj;
//如果是监课,不告诉其他人
if (nodeData.role == ApeConsts.NR_INVISIBLE && GlobalConfig.userRole != ApeConsts.invisible) {
loger.log("NR_INVISIBLE");
loger.log("监课进入或更新数据");
return;
}
if (!rosterExists) {
this.rosterLen = Object.keys(this.rosters).length;
GlobalConfig.rosterNumber = this.rosterLen;//记录当前的总人数
newNodeData.rosterLen = this.rosterLen;
//loger.log("人员加入->", newNodeData);
loger.log("人员加入->", newNodeData);
this._emit(MessageTypes.CLASS_INSERT_ROSTER, {"nodeId": nodeId, "nodeData": newNodeData});
this.emitRosterChange();
} else {
... ... @@ -944,7 +1026,9 @@ class ConferApe extends Ape {
this.rosterLen = Object.keys(this.rosters).length;
GlobalConfig.rosterNumber = this.rosterLen;//记录当前的总人数
newNodeData.rosterLen = this.rosterLen;
loger.log("人员更新信息->", newNodeData);
if(nodeId!=GlobalConfig.nodeId){
loger.log("人员更新信息->", newNodeData);
}
this._emit(MessageTypes.CLASS_UPDATE_ROSTER, {"nodeId": nodeId, "nodeData": newNodeData});
}
}
... ... @@ -970,33 +1054,6 @@ class ConferApe extends Ape {
loger.log("媒体模块被占用->占有人已经不存在课堂中->释放->", _param);
this._emit(MessageTypes.CLASS_NONENTITY_ROSTER, {"nodeId": _param.fromNodeId});
}
/* if (_param && _param.status == ApeConsts.CHANNEL_STATUS_OPENING) {
if(this.rosters[_param.fromNodeId] == null){
loger.log("媒体模块被占用,占有人已经不存在课堂中,释放Channel,_param->", _param);
this._emit(MessageTypes.CLASS_NONENTITY_ROSTER, {"nodeId": _param.fromNodeId});
}
//如果音视频消息是自己的,需要设置麦克风和摄像头状态
if(_param.fromNodeId==GlobalConfig.nodeId){
if(_param.mediaId==ApeConsts.MEDIA_TYPE_AUDIO){
GlobalConfig.openMicrophones=EngineUtils.creatTimestamp();
GlobalConfig.openCamera=0;
}else {
GlobalConfig.openCamera=EngineUtils.creatTimestamp();
GlobalConfig.openMicrophones=GlobalConfig.openCamera;
}
this.updateUserInfo();
}
}else if (_param && _param.status == ApeConsts.CHANNEL_STATUS_RELEASED) {
//如果音视频消息是自己的,需要设置麦克风和摄像头状态
if(_param.fromNodeId==GlobalConfig.nodeId){
GlobalConfig.openCamera=0;
GlobalConfig.openMicrophones=0;
this.updateUserInfo();
}
}*/
}
//设备状态更新
... ... @@ -1034,8 +1091,10 @@ class ConferApe extends Ape {
if (user && user.role == ApeConsts.NR_HOST) {
this.pauseClass();
//强制停止录制
this.stopRecord(true);
/* //强制停止录制
this.stopRecord(true)*/;
}
} else {
loger.warn(GlobalConfig.nodeId, "没有权限检查离开的人员是否占用channel");
... ... @@ -1080,7 +1139,7 @@ class ConferApe extends Ape {
classStatusInfo.serverTimestamp = GlobalConfig.serverTimestamp; //当前的系统时间戳
classStatusInfo.activeDocId = GlobalConfig.activeDocId; //当前激活的文档id
classStatusInfo.activeDocCurPage = GlobalConfig.activeDocCurPage; //当前激活的文档的当前页
classStatusInfo.isStopAllPublishMedia = _param.isStopAllPublishMedia || false;
classStatusInfo.isStopAllPublishMedia = Boolean(_param.isStopAllPublishMedia) || false;
classStatusInfo.currentSceneTableId = GlobalConfig.currentSceneTableId;
classStatusInfo.silence = GlobalConfig.silence;
classStatusInfo.silenceUsers = JSON.stringify(GlobalConfig.silenceUsers);
... ...
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.share=t():e.share=t()}(this,function(){return function(e){function t(n){if(_[n])return _[n].exports;var a=_[n]={exports:{},id:n,loaded:!1};return e[n].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var _={};return t.m=e,t.c=_,t.p="",t(0)}([function(e,t,_){e.exports=_(2)},function(e,t){"use strict";function _(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var n=function(){function e(e,t){for(var _=0;_<t.length;_++){var n=t[_];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,_,n){return _&&e(t.prototype,_),n&&e(t,n),t}}(),a=function(){function e(){_(this,e),this.MAPS={}}return n(e,[{key:"on",value:function(e,t){if(e&&t){var _=this.MAPS[e];if(!_)return this.MAPS[e]=[t];_.push(t)}}},{key:"off",value:function(e,t){if(e){var _=this.MAPS[e];if(_){if(t)return _.splice(_.indexOf(t),1);_.length=0}}}},{key:"emit",value:function(e,t){if(e){var _=this.MAPS["*"];_&&_.length&&_.forEach(function(_){_(e,t)});var n=this.MAPS[e];n&&n.length&&n.forEach(function(e){e(t)})}}}]),e}();t.default=a},function(e,t,_){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function a(e){var t,_,n,a;n=e.length,t=new Uint8Array(3*n);var r=0;for(_=0;_<n;_++)a=e.charCodeAt(_),a>=1&&a<=127?t[r++]=a:a>2047?(t[r++]=224|a>>12&15,t[r++]=128|a>>6&63,t[r++]=128|a>>0&63):(t[r++]=192|a>>6&31,t[r++]=128|a>>0&63);return new Uint8Array(t.buffer,0,r)}function r(e){var t,_,n,a,r,o;for(t="",n=e.length,_=0;_<n;)switch(a=e[_++],a>>4){case 0:case 1:case 2:case 3:case 4:case 5:case 6:case 7:t+=String.fromCharCode(a);break;case 12:case 13:r=e[_++],t+=String.fromCharCode((31&a)<<6|63&r);break;case 14:r=e[_++],o=e[_++],t+=String.fromCharCode((15&a)<<12|(63&r)<<6|(63&o)<<0)}return t}function o(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",_=new Object;if(_.data_len=0,_.data="",_.name=e,"mov_start"==e)_.type=1;else if("mov_stop"==e)_.type=2;else if("mov_pause"==e){if(_.type=3,pos=t,pos.length>0){_.data_len=4;var n=new ArrayBuffer(_.data_len),r=new Uint32Array(n,0,1);r[0]=parseInt(pos),_.data=new Uint8Array(n,0,4)}}else if("mov_resume"==e)_.type=4;else if("mov_seek"==e){if(_.type=5,pos=t,pos.length>0){_.data_len=4;var n=new ArrayBuffer(_.data_len),r=new Uint32Array(n,0,1);r[0]=parseInt(pos),_.data=new Uint8Array(n,0,4)}}else if("ss_start"==e)_.type=6,_.data=a(t),_.data_len=_.data.length;else if("ss_stop"==e)_.type=7;else if("ss_version"==e)_.type=14;else if("get_mic"==e)_.type=26;else{if("ds_start"==e){_.type=27,_.data_len=536;var n=new ArrayBuffer(_.data_len),o=new Uint32Array(n,0,6);coordstr=t;var i=coordstr.split(",");if(4!=i.length)return;o[0]=parseInt(i[0]),o[1]=parseInt(i[1]),o[2]=parseInt(i[2]),o[3]=parseInt(i[3]);var s=new Uint8Array(n,24,256);window_name=t;for(var S=a(window_name),E=0;E<S.length;E++)s[E]=S[E];o[4]=S.length,o[5]=0;new Uint8Array(n,280,256);return _.data=new Uint8Array(n,0,_.data_len),void A(_)}if("ds_stop"==e)_.type=28;else{if("aud_start"==e){_.type=29,_.data_len=520;var n=new ArrayBuffer(_.data_len),l=new Uint32Array(n,0,1),C=t;l[0]=C.length;var f=new Uint32Array(n,4,1);f[0]=0;for(var c=new Uint8Array(n,8,256),O=a(C),E=0;E<O.length;E++)c[E]=O[E];new Uint8Array(n,264,256);return _.data=new Uint8Array(n,0,_.data_len),void A(_)}if("aud_stop"==e)_.type=30;else if("get_cam"==e)_.type=41;else{if("cam_start"==e){_.type=42,_.data_len=520;var n=new ArrayBuffer(_.data_len),I=new Uint32Array(n,0,1),T=t;I[0]=T.length;var f=new Uint32Array(n,4,1);f[0]=0;for(var U=new Uint8Array(n,8,256),u=a(T),E=0;E<u.length;E++)U[E]=u[E];new Uint8Array(n,264,256);return _.data=new Uint8Array(n,0,_.data_len),void A(_)}"cam_stop"==e?_.type=43:"set_videoparam"==e?(_.type=46,_.data=a(t),_.data_len=_.data.length):"get_videoparam"==e?(_.type=47,_.data=a(t),_.data_len=_.data.length):"start_record"==e?(_.type=48,_.data=a(t),_.data_len=_.data.length):"stop_record"==e?(_.type=49,_.data=a(t),_.data_len=_.data.length):"start_push"==e?(_.type=50,_.data=a(t),_.data_len=_.data.length):"stop_push"==e?(_.type=51,_.data=a(t),_.data_len=_.data.length):"get_rtmp_port"==e?_.type=52:"set_mic_vol"==e?(_.type=53,_.data=a(t),_.data_len=_.data.length):"get_mic_vol"==e&&(_.type=54)}}}A(_)}function A(e){var t=8+e.data_len,_=new ArrayBuffer(t),n=new Uint16Array(_,0,1),a=new Uint8Array(_,2,1),r=new Uint32Array(_,4,1);if(n[0]=e.type,a[0]=0,r[0]=e.data_len,e.data_len>0)for(var o=new Uint8Array(_,8,e.data_len),A=0;A<e.data_len;A++)o[A]=e.data[A];R&&R.send(_)}function i(){try{R&&(R.close(),R=R.onopen=R.onclose=R.onerror=R.onmessage=null,C.emit(C.CLOSE))}catch(e){console.log(e)}}function s(){i()}function S(){R&&i(),R=new WebSocket("ws://"+p+":"+L),g=setTimeout(function(){clearTimeout(g),i()},1500),R.timeout=1500,R.binaryType="arraybuffer",R.onopen=function(){clearTimeout(g),o("get_rtmp_port"),o("get_mic"),o("get_cam"),o("get_mic_vol"),C.emit(C.OPEN)},R.onclose=function(){i()},R.onerror=function(){i()},R.onmessage=function(e){var t=e.data;if("string"==typeof e.data)console.log("on message [string] ignore.");else{var _=new DataView(t),n=_.getUint16(0,!0);console.log("onmessage code->",n);var a=(_.getUint8(2,!0),_.getUint32(4,!0));if(n>=0&&n<f.length){f[n]}if(0==n||6==n||8==n)console.log("mov_start,mov_pause,mov_seek success");else if(10==n){if(a>36){var o=new Uint32Array(t,8,8),A="width:"+o[0]+" height:"+o[1];A="framerate:"+o[2]+" duration:"+o[3],A="playpos:"+o[4]+" filesize:"+o[5],c=A;var i=o[6],s=new Uint8Array(t,40,i),S=r(s);c.filename=S,C.emit(C.MOVIE_INFO_CHANGE,c)}}else if(11==n)console.log("ss_start success"),C.emit(C.SS_START);else if(24<=n&&26>=n){if(a>=4){var E=_.getUint32(8,!0);O=E.toString(),C.emit(C.VERSION_INFO_CHANGE,O)}}else if(55==n)console.log("ds_start success");else if(59==n)console.log("as start success");else if(83==n){if(console.log("get camera sucess"),a>4){var l=_.getUint32(8,!0),R=12;I.length=0;for(var p=0;p<l;p++){var L=_.getUint32(R,!0);R+=4;var g=new Uint8Array(t,R,L-1);R+=L;var y=r(g);I.push(y)}C.emit(C.CAMERA_INFO_CHANGE,I)}}else if(53==n){if(a>4){var v=_.getUint32(8,!0),R=12;T.length=0;for(var p=0;p<v;p++){var M=_.getUint32(R,!0);R+=4;var P=new Uint8Array(t,R,M-1);R+=M;var y=r(P);T.push(y)}C.emit(C.MIC_INFO_CHANGE,T)}}else if(85==n)console.log("cam_share success");else if(95==n){console.log("get_videoparam success");var N=new Uint8Array(t,8,t.byteLength-8-1),y=r(N);U=y,C.emit(C.VIDEO_INFO_CHANGE,U)}else if(105==n){console.log("get_rtmp_port_success");var N=new Uint8Array(t,8,t.byteLength-8-1),y=r(N);u=y,C.emit(C.RTMP_PORT_CHANGE,u)}else if(109==n){console.log("get_mic_vol success");var N=new Uint8Array(t,8,t.byteLength-8-1),y=r(N);d=y,C.emit(C.MIC_VOL_CHANGE,d)}else if(111<=n&&114>=n){var N=new Uint8Array(t,8,t.byteLength-8),V=r(N);console.log("url->",V)}else if(13==n)C.emit(C.SS_STOP);else{var N=new Uint8Array(t,8,t.byteLength-8),y=r(N);console.log("data ->",y)}}}}Object.defineProperty(t,"__esModule",{value:!0});var E=_(1),l=n(E),C=new l.default,f=["MOV_START_SUC","MOV_START_FAIL","MOV_STOP_SUC","MOV_STOP_FAIL","MOV_PAUSE_SUC","MOV_PAUSE_FAIL","MOV_RESUME_SUC","MOV_RESUME_FAIL","MOV_SEEK_SUC","MOV_SEEK_FAIL","MOV_PROPERTY","SS_START_SUC","SS_START_FAIL","SS_STOP_SUC","SS_STOP_FAIL","REC_START_SUC","REC_START_FAIL","REC_STOP_SUC","REC_STOP_FAIL","REC_PAUSE_SUC","REC_PAUSE_FAIL","REC_RESUME_SUC","REC_RESUME_FAIL","MOV_PLAY_FINISH","MOV_VERSION","SS_VERSION","REC_VERSION","MOV_SELECT_FILE_CANCEL","QAV_LOGIN_SUC","QAV_LOGIN_FAIL","QAV_LOGOUT_SUC","QAV_LOGOUT_FAIL","QAV_ENTERROOM_SUC","QAV_ENTERROOM_FAIL","QAV_LEAVEROOM_SUC","QAV_LEAVEROOM_FAIL","QAV_OPEN_MIC_SUC","QAV_OPEN_MIC_FAIL","QAV_OPEN_MIC_NODEV","QAV_CLOSE_MIC_SUC","QAV_CLOSE_MIC_FAIL","QAV_CLOSE_MIC_NODEV","QAV_OPEN_PLAYER_SUC","QAV_OPEN_PLAYER_FAIL","QAV_OPEN_PLAYER_NODEV","QAV_CLOSE_PLAYER_SUC","QAV_CLOSE_PLAYER_FAIL","QAV_CLOSE_PLAYER_NODEV","QAV_MUTE_AUDIO_SUC","QAV_MUTE_AUDIO_FAIL","QAV_UNMUTE_AUDIO_SUC","QAV_UNMUTE_AUDIO_FAIL","REC_SAVE_FILE_CANCEL","GET_MIC_SUC","GET_MIC_FAIL","DS_START_SUC","DS_START_FAIL","DS_STOP_SUC","DS_STOP_FAIL","AUD_START_SUC","AUD_START_FAIL","AUD_STOP_SUC","AUD_STOP_FAIL","AUD_DATA","SS_DATA","MOV_DATA","PEN_START_SUC","PEN_START_FAIL","PEN_STOP_SUC","PEN_STOP_FAIL","PEN_VERSION","QAV_DEVICE_SUC","QAV_DEVICE_FAIL","CBD_QUERY_SUC","CBD_QUERY_FAIL","CBD_GET_SUC","CBD_GET_FAIL","FILE_GET_SUC","FILE_GET_FAIL","FILE_SET_SUC","FILE_SET_FAIL","RESTART_SUC","RESTART_FAIL","GET_CAM_SUC","GET_CAM_FAIL","CAM_START_SUC","CAM_START_FAIL","CAM_STOP_SUC","CAM_STOP_FAIL","SWITCH_SCENE_SUC","SWITCH_SCENE_FAIL","PUSH_STREAM_FAIL","SHOW_UI_SUC","SET_VIDEO_PARAM_SUC","SET_VIDEO_PARAM_FAIL","GET_VIDEO_PARAM_SUC","GET_VIDEO_PARAM_FAIL","START_RECORD_SUC","START_RECORD_FAIL","STOP_RECORD_SUC","STOP_RECORD_FAIL","START_PUSH_SUC","START_PUSH_FAIL","STOP_PUSH_SUC","STOP_PUSH_FAIL","GET_RTMP_PORT_SUC","GET_RTMP_PORT_FAIL","SET_MIC_VOL_SUC","SET_MIC_VOL_FAIL","GET_MIC_VOL_SUC","GET_MIC_VOL_FAIL","RTMP_CONNECTING","RTMP_CONNECT_SUC","RTMP_CONNECT_FAIL","RTMP_CONNECT_CLOSED"],c=null,O="",I=[],T=[],U="",u="",d="",R=null,p="127.0.0.1",L=8090,g=0;C.infos={movieInfo:c,versionInfo:O,cameraInfo:I,micInfo:T,videoInfo:U,rtmpPort:u,micVol:d},C.MOVIE_INFO_CHANGE="MOVIE_INFO_CHANGE",C.VERSION_INFO_CHANGE="VERSION_INFO_CHANGE",C.CAMERA_INFO_CHANGE="CAMERA_INFO_CHANGE",C.MIC_INFO_CHANGE="MIC_INFO_CHANGE",C.VIDEO_INFO_CHANGE="VIDEO_INFO_CHANGE",C.RTMP_PORT_CHANGE="RTMP_PORT_CHANGE",C.MIC_VOL_CHANGE="MIC_VOL_CHANGE",C.SS_START="SS_START",C.SS_STOP="SS_STOP",C.OPEN="OPEN",C.CLOSE="CLOSE",C.ERROR="ERROR",C.getRTMPPort=function(){o("get_rtmp_port")},C.getMicInfo=function(){o("get_mic")},C.getCamInfo=function(){o("get_cam")},C.getMicVol=function(){o("get_mic_vol")},C.start=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"127.0.0.1",t=arguments[1];p=e,L=t,S()},C.stop=function(){s()},C.startShareScreen=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";o("ss_start",e)},C.stopShareScreen=function(){o("ss_stop")},t.default=C}])});
\ No newline at end of file