Toggle navigation
Toggle navigation
此项目
正在载入...
Sign in
李勇
/
McuClient
转到一个项目
Toggle navigation
项目
群组
代码片段
帮助
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
李勇
2017-08-25 09:08:04 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
0a4aa530d71b3c447dbe07f0a06c2d190ceca8fb
0a4aa530
1 parent
d53faee0
修改开启录制和停止录制的逻辑,课堂开启录制之后只有课堂内主动调用停止或课堂内10分钟没有人的时候才会停止
显示空白字符变更
内嵌
并排对比
正在显示
5 个修改的文件
包含
156 行增加
和
2640 行删除
src/EngineEntrance.js
src/EngineEntranceOld.js
src/GlobalConfig.js
src/apes/ConferApe.js
src/ss.js
src/EngineEntrance.js
查看文件 @
0a4aa53
...
...
@@ -58,7 +58,7 @@ export default class MessageEntrance extends Emiter {
constructor
()
{
super
();
//sdk 信息
GlobalConfig
.
sdkVersion
=
"v1.8
0.1.20170823
"
;
GlobalConfig
.
sdkVersion
=
"v1.8
1.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
);
...
...
src/EngineEntranceOld.js
已删除
100644 → 0
查看文件 @
d53faee
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
);
}
}
}
src/GlobalConfig.js
查看文件 @
0a4aa53
...
...
@@ -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
=
3
0
;
//(秒),每隔30秒同步一次课堂状态的并保存到Sass
GlobalConfig
.
updateClassInfoDelay
=
2
0
;
//(秒),每隔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
=
''
;
//屏幕共享插件的地址
...
...
src/apes/ConferApe.js
查看文件 @
0a4aa53
...
...
@@ -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
)
{
//如果是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
);
//如果是host ,开始录制
/* //如果当前课堂正在进行中,开启计时器
if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) {
//开始计时
this.startTimerCounter();
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,8 +656,53 @@ class ConferApe extends Ape {
if
(
!
this
.
mcu
.
connected
)
{
loger
.
warn
(
'MCU 连接已经断开'
);
this
.
stopTimerCounter
();
return
;
}
//如果还没开始或已经暂停、关闭,不做计时处理
//课堂开始的状态下,课堂进行时间和录制时间都需要更加,录制时间会大于或等于课堂开始的累积时间
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
});
}
}
//进行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
});
}
}
}
/* //如果还没开始或已经暂停、关闭,不做计时处理
if (GlobalConfig.classStatus != ApeConsts.CLASS_STATUS_STARTED) {
loger.warn('当前课堂已经暂停或者未开始,不计时', "classStatus-->", GlobalConfig.classStatus);
return;
...
...
@@ -633,17 +713,17 @@ class ConferApe extends Ape {
if (GlobalConfig.isHost) {
GlobalConfig.recordTimestamp = GlobalConfig.recordTimestamp + 1;
}
//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);
//同步消息给其他人
this
.
sendUpdaterClassStatusInfo
({
"actionType"
:
1
,
isStopAllPublishMedia
:
false
});
this.sendUpdaterClassStatusInfo({"actionType": ApeConsts.CLASS_STATUS_STARTED
, isStopAllPublishMedia: false});
}
}
...
...
@@ -655,12 +735,13 @@ class ConferApe extends Ape {
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->er
r'
,
err
.
message
);
loger
.
warn
(
'
课堂更新->erro
r'
,
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"
)
{
//{"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
;
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
);
...
...
src/ss.js
已删除
100644 → 0
查看文件 @
d53faee
!
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
请
注册
或
登录
后发表评论