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-21 19:19:43 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
d333c3126cfdc0a63a24fa7c2f17f6c4ba12e6b9
d333c312
1 parent
ee8cdea7
1.音视频模块推流接口增加optionJsonData:{"bufferTime":0}} 用于设置播放流的时候的bufferTime
显示空白字符变更
内嵌
并排对比
正在显示
3 个修改的文件
包含
485 行增加
和
403 行删除
src/EngineEntrance.js
src/apes/AudioApe.js
src/apes/VideoApe.js
src/EngineEntrance.js
查看文件 @
d333c31
...
...
@@ -58,7 +58,7 @@ export default class MessageEntrance extends Emiter {
constructor
()
{
super
();
//sdk 信息
GlobalConfig
.
sdkVersion
=
"v1.79.
4
.20170821"
;
GlobalConfig
.
sdkVersion
=
"v1.79.
5
.20170821"
;
loger
.
warn
(
"sdkVersion:"
+
GlobalConfig
.
sdkVersion
);
//设置
...
...
@@ -1796,7 +1796,6 @@ export default class MessageEntrance extends Emiter {
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
""
};
}
if
(
_video_ape
)
{
GlobalConfig
.
optionJsonData
=
_param
.
optionJsonData
||
""
;
return
_video_ape
.
publishVideo
(
_param
);
}
}
...
...
@@ -1853,7 +1852,6 @@ export default class MessageEntrance extends Emiter {
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
""
};
}
if
(
_audio_ape
)
{
GlobalConfig
.
optionJsonData
=
_param
.
optionJsonData
||
""
;
return
_audio_ape
.
publishAudio
(
_param
);
}
}
...
...
src/apes/AudioApe.js
查看文件 @
d333c31
...
...
@@ -21,11 +21,11 @@ class AudioApe extends Ape {
ApeConsts
.
AUDIO_SESSION_TAG
);
this
.
releaseTimeId
=
0
this
.
mediaModule
=
new
MediaModule
();
this
.
mediaModule
.
MEDIA_OBJ_TABLE_ID
=
ApeConsts
.
AUDIO_OBJ_TABLE_ID
;
this
.
mediaModule
.
mediaChannels
=
{};
this
.
mediaModule
.
mediaType
=
ApeConsts
.
MEDIA_TYPE_AUDIO
;
this
.
releaseTimeId
=
0
this
.
mediaModule
=
new
MediaModule
();
this
.
mediaModule
.
MEDIA_OBJ_TABLE_ID
=
ApeConsts
.
AUDIO_OBJ_TABLE_ID
;
this
.
mediaModule
.
mediaChannels
=
{};
this
.
mediaModule
.
mediaType
=
ApeConsts
.
MEDIA_TYPE_AUDIO
;
// Ape Models
this
.
registerKey
(
this
.
_session_id
,
this
.
_session_name
,
this
.
_session_tag
,
new
ArrayBuffer
);
this
.
registerObj
(
pdu
.
RCPDU_REG_REGISTER_TABLE
,
ApeConsts
.
AUDIO_OBJ_TABLE_ID
,
ApeConsts
.
AUDIO_OBJ_TABLE_NAME
,
ApeConsts
.
AUDIO_OBJ_TABLE_TAG
,
0
,
new
ArrayBuffer
);
...
...
@@ -33,10 +33,11 @@ class AudioApe extends Ape {
// 广播消息,用户之间的消息传递
this
.
on
(
pdu
.
RCPDU_SEND_AUDIO_DATA_REQUEST
,
this
.
receiveAudiooCommandHandler
.
bind
(
this
));
}
//ape加入成功
onJoinChannelHandlerSuccess
()
{
onJoinChannelHandlerSuccess
()
{
//这个设置很重要,因为只有Sass流程完成之后,APE才能取得GlobalConfig中的数据
this
.
mediaModule
.
maxMediaChannel
=
GlobalConfig
.
maxAudioChannels
;
this
.
mediaModule
.
maxMediaChannel
=
GlobalConfig
.
maxAudioChannels
;
}
/////////////发送数据操作////////////////////////////////////////////
...
...
@@ -49,66 +50,77 @@ class AudioApe extends Ape {
//获取推流地址
getAudioPublishPath
(
_param
)
{
loger
.
log
(
'获取推流地址->'
);
if
(
!
this
.
mcu
.
connected
)
{
if
(
!
this
.
mcu
.
connected
)
{
loger
.
warn
(
GlobalConfig
.
getCurrentStatus
());
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"已经断开连接"
};;
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"已经断开连接"
};
;
}
//监课比较特殊,不占用课堂内的音视频路数,额外创建
if
(
GlobalConfig
.
userRole
==
ApeConsts
.
invisible
){
let
result
=
this
.
mediaModule
.
getMediaPublishPathForInVisible
(
_param
);
this
.
_emit
(
MessageTypes
.
AUDIO_GET_PUBLISH_PATH
,
result
);
if
(
GlobalConfig
.
userRole
==
ApeConsts
.
invisible
)
{
let
result
=
this
.
mediaModule
.
getMediaPublishPathForInVisible
(
_param
);
this
.
_emit
(
MessageTypes
.
AUDIO_GET_PUBLISH_PATH
,
result
);
return
result
;
}
//非监课的身份,需要判断是否可以继续推流
//需要判断当前已经使用的流路数
let
openChannel
=
0
;
let
allChannels
=
MediaModule
.
allMediaChannelsList
;
for
(
let
i
in
allChannels
){
let
channel
=
allChannels
[
i
];
if
(
channel
&&
channel
.
status
==
ApeConsts
.
CHANNEL_STATUS_OPENING
&&
channel
.
userRole
!=
ApeConsts
.
invisible
){
let
openChannel
=
0
;
let
allChannels
=
MediaModule
.
allMediaChannelsList
;
for
(
let
i
in
allChannels
)
{
let
channel
=
allChannels
[
i
];
if
(
channel
&&
channel
.
status
==
ApeConsts
.
CHANNEL_STATUS_OPENING
&&
channel
.
userRole
!=
ApeConsts
.
invisible
)
{
//正在开启的才计数,监课开启的不计算在内
openChannel
++
;
}
}
//如果已经开启的数量大于等于最大允许开启的数量,不允许再推流
if
(
openChannel
>=
GlobalConfig
.
maxMediaChannels
){
loger
.
warn
(
'不能再打开设备->当前开启的设备数量->'
,
openChannel
);
if
(
openChannel
>=
GlobalConfig
.
maxMediaChannels
)
{
loger
.
warn
(
'不能再打开设备->当前开启的设备数量->'
,
openChannel
);
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"不能再打开设备,当前开启的设备数量"
};
}
let
result
=
this
.
mediaModule
.
getMediaPublishPath
(
_param
);
this
.
_emit
(
MessageTypes
.
AUDIO_GET_PUBLISH_PATH
,
result
);
let
result
=
this
.
mediaModule
.
getMediaPublishPath
(
_param
);
this
.
_emit
(
MessageTypes
.
AUDIO_GET_PUBLISH_PATH
,
result
);
return
result
;
}
//获取当前所有频道信息
getAllChannelInfo
(
_param
)
{
getAllChannelInfo
(
_param
)
{
loger
.
log
(
'获取当前所有频道信息->'
);
return
this
.
mediaModule
.
getAllMediaChannelInfo
();
}
//推流
publishAudio
(
_param
)
{
if
(
!
this
.
mcu
.
connected
)
{
if
(
!
this
.
mcu
.
connected
)
{
loger
.
warn
(
GlobalConfig
.
getCurrentStatus
());
this
.
_emit
(
MessageTypes
.
AUDIO_PUBLISH_RESULT
,{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"已经断开连接!"
,
"mediaId"
:
0
});
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"已经断开连接"
,
"mediaId"
:
0
};
this
.
_emit
(
MessageTypes
.
AUDIO_PUBLISH_RESULT
,
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"已经断开连接!"
,
"mediaId"
:
0
});
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"已经断开连接"
,
"mediaId"
:
0
};
}
if
(
_param
==
null
||
_param
.
publishUrl
==
null
)
{
if
(
_param
==
null
||
_param
.
publishUrl
==
null
)
{
loger
.
warn
(
'推流->参数错误'
,
_param
);
this
.
_emit
(
MessageTypes
.
MCU_ERROR
,
MessageTypes
.
ERR_APE_INTERFACE_PARAM_WRONG
);
this
.
_emit
(
MessageTypes
.
AUDIO_PUBLISH_RESULT
,{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"参数错误!"
,
"mediaId"
:
0
});
this
.
_emit
(
MessageTypes
.
AUDIO_PUBLISH_RESULT
,
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"参数错误!"
,
"mediaId"
:
0
});
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"参数错误"
};
}
//获取可选参数,转换为JSON字符串
try
{
GlobalConfig
.
optionJsonData
=
JSON
.
stringify
(
_param
.
optionJsonData
)
||
""
}
catch
(
err
)
{
GlobalConfig
.
optionJsonData
=
""
;
}
//根据推流的地址获取对应的频道信息
let
needPublishChannelInfo
=
this
.
mediaModule
.
getNeedPublishMediaChannel
(
_param
.
publishUrl
);
if
(
needPublishChannelInfo
==
null
){
let
needPublishChannelInfo
=
this
.
mediaModule
.
getNeedPublishMediaChannel
(
_param
.
publishUrl
);
if
(
needPublishChannelInfo
==
null
)
{
loger
.
warn
(
'推流->推流数据已经无效'
,
_param
);
this
.
_emit
(
MessageTypes
.
AUDIO_PUBLISH_RESULT
,{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"推流数据已经无效!"
,
"mediaId"
:
0
});
this
.
_emit
(
MessageTypes
.
AUDIO_PUBLISH_RESULT
,
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"推流数据已经无效!"
,
"mediaId"
:
0
});
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"推流数据已经无效"
};
}
...
...
@@ -116,90 +128,111 @@ class AudioApe extends Ape {
let
freeChannel
=
this
.
mediaModule
.
getFreeMediaChannel
();
if
(
freeChannel
==
0
)
{
loger
.
warn
(
"推流->不能再打开更多的设备"
);
this
.
_emit
(
MessageTypes
.
AUDIO_PUBLISH_RESULT
,{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"不能再打开更多的设备"
,
"mediaId"
:
0
});
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"不能再打开更多的设备"
,
"mediaChannels"
:
this
.
mediaModule
.
mediaChannels
};
this
.
_emit
(
MessageTypes
.
AUDIO_PUBLISH_RESULT
,
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"不能再打开更多的设备"
,
"mediaId"
:
0
});
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"不能再打开更多的设备"
,
"mediaChannels"
:
this
.
mediaModule
.
mediaChannels
};
}
//判断当前的频道是否已经占用
if
(
this
.
mediaModule
.
checkChannelIsOpening
(
needPublishChannelInfo
.
channelId
)){
if
(
needPublishChannelInfo
.
nodeId
==
GlobalConfig
.
nodeId
){
loger
.
warn
(
needPublishChannelInfo
.
channelId
,
"已经推送过消息,不需要再次推送!"
);
this
.
_emit
(
MessageTypes
.
AUDIO_PUBLISH_RESULT
,{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
"已经推送过消息,不需要再次推送!"
,
"mediaId"
:
needPublishChannelInfo
.
channelId
});
return
{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
"已经推送过消息,不需要再次推送!"
,
"mediaId"
:
needPublishChannelInfo
.
channelId
};
}
else
{
loger
.
warn
(
needPublishChannelInfo
.
channelId
,
"频道已经被占用"
);
this
.
_emit
(
MessageTypes
.
AUDIO_PUBLISH_RESULT
,{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"频道已经被占用!"
,
"mediaId"
:
0
});
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"频道已经被占用!"
};
if
(
this
.
mediaModule
.
checkChannelIsOpening
(
needPublishChannelInfo
.
channelId
))
{
if
(
needPublishChannelInfo
.
nodeId
==
GlobalConfig
.
nodeId
)
{
loger
.
warn
(
needPublishChannelInfo
.
channelId
,
"已经推送过消息,不需要再次推送!"
);
this
.
_emit
(
MessageTypes
.
AUDIO_PUBLISH_RESULT
,
{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
"已经推送过消息,不需要再次推送!"
,
"mediaId"
:
needPublishChannelInfo
.
channelId
});
return
{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
"已经推送过消息,不需要再次推送!"
,
"mediaId"
:
needPublishChannelInfo
.
channelId
};
}
else
{
loger
.
warn
(
needPublishChannelInfo
.
channelId
,
"频道已经被占用"
);
this
.
_emit
(
MessageTypes
.
AUDIO_PUBLISH_RESULT
,
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"频道已经被占用!"
,
"mediaId"
:
0
});
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"频道已经被占用!"
};
}
}
let
channelInfo
=
this
.
mediaModule
.
getDefaultChannelInfo
();
channelInfo
.
owner
=
GlobalConfig
.
nodeId
;
channelInfo
.
status
=
ApeConsts
.
CHANNEL_STATUS_OPENING
;
channelInfo
.
channelId
=
needPublishChannelInfo
.
channelId
;
//freeChannel
channelInfo
.
streamId
=
needPublishChannelInfo
.
streamId
;
//按规则拼接的流名称
channelInfo
.
timestamp
=
needPublishChannelInfo
.
timestamp
;
//EngineUtils.creatTimestamp();
channelInfo
.
mediaType
=
ApeConsts
.
MEDIA_TYPE_AUDIO
;
let
channelInfo
=
this
.
mediaModule
.
getDefaultChannelInfo
();
channelInfo
.
owner
=
GlobalConfig
.
nodeId
;
channelInfo
.
status
=
ApeConsts
.
CHANNEL_STATUS_OPENING
;
channelInfo
.
channelId
=
needPublishChannelInfo
.
channelId
;
//freeChannel
channelInfo
.
streamId
=
needPublishChannelInfo
.
streamId
;
//按规则拼接的流名称
channelInfo
.
timestamp
=
needPublishChannelInfo
.
timestamp
;
//EngineUtils.creatTimestamp();
channelInfo
.
mediaType
=
ApeConsts
.
MEDIA_TYPE_AUDIO
;
this
.
sendTableUpdateHandler
(
channelInfo
);
this
.
_emit
(
MessageTypes
.
AUDIO_PUBLISH_RESULT
,{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
"推流成功!"
,
"mediaId"
:
needPublishChannelInfo
.
channelId
});
return
{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
"推流成功!"
,
"mediaId"
:
needPublishChannelInfo
.
channelId
};
this
.
_emit
(
MessageTypes
.
AUDIO_PUBLISH_RESULT
,
{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
"推流成功!"
,
"mediaId"
:
needPublishChannelInfo
.
channelId
});
return
{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
"推流成功!"
,
"mediaId"
:
needPublishChannelInfo
.
channelId
};
}
//停止推流,
stopPublishAudio
(
_param
)
{
loger
.
log
(
'停止推流 ->'
,
_param
);
if
(
!
this
.
mcu
.
connected
){
loger
.
log
(
'停止推流 ->'
,
_param
);
if
(
!
this
.
mcu
.
connected
)
{
loger
.
warn
(
GlobalConfig
.
getCurrentStatus
());
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"已经断开连接"
};
}
//默认为自己的nodeId,_param如果为空,那么默认就是当前自己的nodeId,否则用_param
let
nodeId
=
GlobalConfig
.
nodeId
;
if
(
_param
&&
parseInt
(
_param
.
nodeId
)
>
0
){
nodeId
=
parseInt
(
_param
.
nodeId
);
let
nodeId
=
GlobalConfig
.
nodeId
;
if
(
_param
&&
parseInt
(
_param
.
nodeId
)
>
0
)
{
nodeId
=
parseInt
(
_param
.
nodeId
);
}
//默认为0,如果releaseChannelId 存在就释放releaseChannelId通道
let
releaseChannelId
=
0
;
if
(
_param
&&
parseInt
(
_param
.
mediaId
)
>
0
){
releaseChannelId
=
parseInt
(
_param
.
mediaId
);
let
releaseChannelId
=
0
;
if
(
_param
&&
parseInt
(
_param
.
mediaId
)
>
0
)
{
releaseChannelId
=
parseInt
(
_param
.
mediaId
);
}
//释放channelId 的占用
if
(
releaseChannelId
>
0
)
{
if
(
releaseChannelId
>
0
)
{
//第一种情况,释放nodeId占用的指定mediaId (channelId)
this
.
_releaseChannelForNodeId
(
nodeId
,
releaseChannelId
);
}
else
{
this
.
_releaseChannelForNodeId
(
nodeId
,
releaseChannelId
);
}
else
{
//第二种情况,释放nodeId占用的所有channelId
this
.
_releaseNodeIdAllChannel
(
nodeId
);
}
}
//释放nodeId占用的指定的channelId频道
_releaseChannelForNodeId
(
nodeId
,
channelId
){
loger
.
log
(
nodeId
,
"释放占用的频道-->"
,
channelId
);
let
channelInfo
=
this
.
mediaModule
.
mediaChannels
[
channelId
];
if
(
channelInfo
&&
channelInfo
.
status
==
ApeConsts
.
CHANNEL_STATUS_OPENING
){
if
(
channelInfo
.
fromNodeId
==
nodeId
){
_releaseChannelForNodeId
(
nodeId
,
channelId
)
{
loger
.
log
(
nodeId
,
"释放占用的频道-->"
,
channelId
);
let
channelInfo
=
this
.
mediaModule
.
mediaChannels
[
channelId
];
if
(
channelInfo
&&
channelInfo
.
status
==
ApeConsts
.
CHANNEL_STATUS_OPENING
)
{
if
(
channelInfo
.
fromNodeId
==
nodeId
)
{
let
channelInfo
=
this
.
mediaModule
.
getDefaultChannelInfo
();
channelInfo
.
status
=
ApeConsts
.
CHANNEL_STATUS_RELEASED
;
channelInfo
.
channelId
=
channelId
;
let
channelInfo
=
this
.
mediaModule
.
getDefaultChannelInfo
();
channelInfo
.
status
=
ApeConsts
.
CHANNEL_STATUS_RELEASED
;
channelInfo
.
channelId
=
channelId
;
this
.
sendTableUpdateHandler
(
channelInfo
);
}
else
{
loger
.
warn
(
channelId
,
"不属于nodeId"
,
nodeId
,
"不能释放"
,
channelInfo
);
}
else
{
loger
.
warn
(
channelId
,
"不属于nodeId"
,
nodeId
,
"不能释放"
,
channelInfo
);
}
}
else
{
loger
.
warn
(
nodeId
,
"要释放的频道不存在或者已经释放-->channelId"
,
channelInfo
);
}
else
{
loger
.
warn
(
nodeId
,
"要释放的频道不存在或者已经释放-->channelId"
,
channelInfo
);
}
}
//释放nodeId占用的所有频道
_releaseNodeIdAllChannel
(
nodeId
){
loger
.
log
(
nodeId
,
"_releaseNodeIdAllChannel"
,
this
.
mcu
.
connected
);
if
(
!
this
.
mcu
.
connected
){
_releaseNodeIdAllChannel
(
nodeId
)
{
loger
.
log
(
nodeId
,
"_releaseNodeIdAllChannel"
,
this
.
mcu
.
connected
);
if
(
!
this
.
mcu
.
connected
)
{
clearTimeout
(
this
.
releaseTimeId
);
loger
.
warn
(
GlobalConfig
.
getCurrentStatus
());
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"已经断开连接"
};
...
...
@@ -207,28 +240,29 @@ class AudioApe extends Ape {
let
openingChannelInfo
=
this
.
mediaModule
.
getOpeningMediaChannelForNodeId
(
nodeId
);
if
(
openingChannelInfo
.
channelId
==
0
)
{
loger
.
warn
(
nodeId
,
"没有占用频道不需要处理"
);
loger
.
warn
(
nodeId
,
"没有占用频道不需要处理"
);
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"没有占用channel不需要处理"
};
}
let
channelInfo
=
this
.
mediaModule
.
getDefaultChannelInfo
();
channelInfo
.
status
=
ApeConsts
.
CHANNEL_STATUS_RELEASED
;
channelInfo
.
channelId
=
openingChannelInfo
.
channelId
;
channelInfo
.
nodeId
=
openingChannelInfo
.
fromNodeId
;
channelInfo
.
userRole
=
openingChannelInfo
.
userRole
;
channelInfo
.
userName
=
openingChannelInfo
.
userName
;
channelInfo
.
userId
=
openingChannelInfo
.
userId
;
let
channelInfo
=
this
.
mediaModule
.
getDefaultChannelInfo
();
channelInfo
.
status
=
ApeConsts
.
CHANNEL_STATUS_RELEASED
;
channelInfo
.
channelId
=
openingChannelInfo
.
channelId
;
channelInfo
.
nodeId
=
openingChannelInfo
.
fromNodeId
;
channelInfo
.
userRole
=
openingChannelInfo
.
userRole
;
channelInfo
.
userName
=
openingChannelInfo
.
userName
;
channelInfo
.
userId
=
openingChannelInfo
.
userId
;
this
.
sendTableUpdateHandler
(
channelInfo
);
//递归检查,800毫秒之后执行
this
.
releaseTimeId
=
setTimeout
(
function
(){
loger
.
warn
(
nodeId
,
"检查频道是否占用"
);
this
.
releaseTimeId
=
setTimeout
(
function
()
{
loger
.
warn
(
nodeId
,
"检查频道是否占用"
);
this
.
_releaseNodeIdAllChannel
(
nodeId
);
}.
bind
(
this
),
800
);
}.
bind
(
this
),
800
);
}
sendAudioBroadcastMsg
(
_param
)
{
if
(
!
this
.
mcu
.
connected
)
{
if
(
!
this
.
mcu
.
connected
)
{
loger
.
warn
(
GlobalConfig
.
getCurrentStatus
());
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"已经断开连接"
};
}
...
...
@@ -246,13 +280,13 @@ class AudioApe extends Ape {
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"sendAudioBroadcastMsg,参数错误"
};
}
// to, message
loger
.
log
(
'音频模块广播->'
,
_param
);
loger
.
log
(
'音频模块广播->'
,
_param
);
if
(
_param
.
actionType
!=
null
&&
_param
.
actionType
==
ApeConsts
.
MEDIA_ACTION_OPEN_CAMERA
)
{
//判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启
let
freeChannel
=
this
.
mediaModule
.
getFreeMediaChannel
();
if
(
freeChannel
==
0
)
{
loger
.
warn
(
'不能再打开更多的设备'
,
_param
);
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"不能再打开更多的设备"
,
"mediaChannels"
:
this
.
mediaModule
.
mediaChannels
};
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"不能再打开更多的设备"
,
"mediaChannels"
:
this
.
mediaModule
.
mediaChannels
};
}
}
...
...
@@ -265,15 +299,15 @@ class AudioApe extends Ape {
audioSendPdu
.
toNodeId
=
parseInt
(
_param
.
toNodeId
)
||
0
;
//接收者,0就是所有人
audioSendPdu
.
actionType
=
parseInt
(
_param
.
actionType
)
||
ApeConsts
.
MEDIA_ACTION_DEFAULT
;
let
dataStr
=
''
;
try
{
dataStr
=
JSON
.
stringify
(
_param
.
data
);
}
catch
(
err
){
let
dataStr
=
''
;
try
{
dataStr
=
JSON
.
stringify
(
_param
.
data
);
}
catch
(
err
)
{
loger
.
warn
(
'控制消息->JSON转换失败'
);
dataStr
=
_param
.
data
;
dataStr
=
_param
.
data
;
}
audioSendPdu
.
data
=
this
.
_rCArrayBufferUtil
.
strToUint8Array
(
"h5"
+
dataStr
);
//开头两个字会乱码,需要加上h5两个字符
audioSendPdu
.
data
=
this
.
_rCArrayBufferUtil
.
strToUint8Array
(
"h5"
+
dataStr
);
//开头两个字会乱码,需要加上h5两个字符
if
(
!
audioSendPdu
.
isPublic
&&
0
!=
audioSendPdu
.
toNodeId
)
{
//发送给制定的人
...
...
@@ -290,8 +324,8 @@ class AudioApe extends Ape {
sendTableUpdateHandler
(
_channelInfo
)
{
//loger.log("audio,sendTableUpdateHandler ");
let
updateModelPdu
=
this
.
packPdu
(
_channelInfo
,
_channelInfo
.
channelId
);
if
(
updateModelPdu
==
null
){
loger
.
warn
(
"音频模块更新数据-> 失败->数据无效"
,
_channelInfo
);
if
(
updateModelPdu
==
null
)
{
loger
.
warn
(
"音频模块更新数据-> 失败->数据无效"
,
_channelInfo
);
return
;
}
...
...
@@ -334,113 +368,116 @@ class AudioApe extends Ape {
}
audioReceivePdu
.
data
=
this
.
_rCArrayBufferUtil
.
uint8ArrayToStr
(
audioReceivePdu
.
data
,
2
);
//开头两个字会乱码
let
dataObj
=
{};
try
{
dataObj
=
JSON
.
parse
(
audioReceivePdu
.
data
);
}
catch
(
err
){
let
dataObj
=
{};
try
{
dataObj
=
JSON
.
parse
(
audioReceivePdu
.
data
);
}
catch
(
err
)
{
loger
.
warn
(
'控制消息->JSON转换失败'
);
dataObj
=
audioReceivePdu
.
data
;
dataObj
=
audioReceivePdu
.
data
;
}
audioReceivePdu
.
data
=
dataObj
;
audioReceivePdu
.
data
=
dataObj
;
//判断接收者的id,如果不是0,并且也不是自己的nodeId,那么消息不做处理
if
(
audioReceivePdu
.
toNodeId
!=
0
&&
audioReceivePdu
.
toNodeId
!=
GlobalConfig
.
nodeId
)
{
loger
.
log
(
'音频消息不处理 toNodeId='
,
audioReceivePdu
.
toNodeId
,
"my nodeId="
,
GlobalConfig
.
nodeId
);
}
else
{
loger
.
log
(
'音频控制消息处理 .'
,
audioReceivePdu
);
loger
.
log
(
'音频控制消息处理 .'
,
audioReceivePdu
);
this
.
_emit
(
MessageTypes
.
AUDIO_BROADCAST
,
audioReceivePdu
);
}
}
tableUpdateHandler
(
owner
,
itemIdx
,
itemData
,
seek
)
{
tableUpdateHandler
(
owner
,
itemIdx
,
itemData
,
seek
)
{
let
unpackChannelInfo
=
this
.
unPackPdu
(
owner
,
itemIdx
,
itemData
);
loger
.
log
(
"tableUpdateHandler->channel"
,
itemIdx
,
'status->'
,
unpackChannelInfo
.
status
,
"seek->"
,
seek
);
loger
.
log
(
"tableUpdateHandler->channel"
,
itemIdx
,
'status->'
,
unpackChannelInfo
.
status
,
"seek->"
,
seek
);
//****很重要********
//如果owner的值为0,代表的是这个歌频道已经被释放了(mcu服务端对于占用channel的掉线用户,就是把owner设置为0)
if
(
owner
==
0
){
loger
.
log
(
"释放占用的频道,channel"
,
itemIdx
);
unpackChannelInfo
.
status
=
ApeConsts
.
CHANNEL_STATUS_RELEASED
;
unpackChannelInfo
.
streamId
=
""
;
if
(
owner
==
0
)
{
loger
.
log
(
"释放占用的频道,channel"
,
itemIdx
);
unpackChannelInfo
.
status
=
ApeConsts
.
CHANNEL_STATUS_RELEASED
;
unpackChannelInfo
.
streamId
=
""
;
}
this
.
mediaModule
.
mediaChannels
[
itemIdx
]
=
unpackChannelInfo
;
if
(
unpackChannelInfo
&&
unpackChannelInfo
.
fromNodeId
!=
GlobalConfig
.
nodeId
){
let
receiveChannelInfo
=
{};
receiveChannelInfo
.
mediaId
=
unpackChannelInfo
.
channelId
;
receiveChannelInfo
.
fromNodeId
=
unpackChannelInfo
.
fromNodeId
;
receiveChannelInfo
.
userName
=
unpackChannelInfo
.
userName
||
""
;
receiveChannelInfo
.
userRole
=
unpackChannelInfo
.
userRole
||
ApeConsts
.
normal
;
receiveChannelInfo
.
mediaType
=
unpackChannelInfo
.
mediaType
||
ApeConsts
.
MEDIA_TYPE_DEFAULT
;
receiveChannelInfo
.
screenWidth
=
unpackChannelInfo
.
screenWidth
||
GlobalConfig
.
screenWidth
;
receiveChannelInfo
.
screenHeight
=
unpackChannelInfo
.
screenHeight
||
GlobalConfig
.
screenHeight
;
receiveChannelInfo
.
deviceType
=
unpackChannelInfo
.
deviceType
||
0
;
receiveChannelInfo
.
optionJsonData
=
unpackChannelInfo
.
optionJsonData
||
""
;
if
(
unpackChannelInfo
&&
unpackChannelInfo
.
fromNodeId
!=
GlobalConfig
.
nodeId
)
{
let
receiveChannelInfo
=
{};
receiveChannelInfo
.
mediaId
=
unpackChannelInfo
.
channelId
;
receiveChannelInfo
.
fromNodeId
=
unpackChannelInfo
.
fromNodeId
;
receiveChannelInfo
.
userName
=
unpackChannelInfo
.
userName
||
""
;
receiveChannelInfo
.
userRole
=
unpackChannelInfo
.
userRole
||
ApeConsts
.
normal
;
receiveChannelInfo
.
mediaType
=
unpackChannelInfo
.
mediaType
||
ApeConsts
.
MEDIA_TYPE_DEFAULT
;
receiveChannelInfo
.
screenWidth
=
unpackChannelInfo
.
screenWidth
||
GlobalConfig
.
screenWidth
;
receiveChannelInfo
.
screenHeight
=
unpackChannelInfo
.
screenHeight
||
GlobalConfig
.
screenHeight
;
receiveChannelInfo
.
deviceType
=
unpackChannelInfo
.
deviceType
||
0
;
receiveChannelInfo
.
optionJsonData
=
unpackChannelInfo
.
optionJsonData
||
""
;
//消息不是自己同步的,需要处理
if
(
unpackChannelInfo
.
status
==
ApeConsts
.
CHANNEL_STATUS_OPENING
)
{
if
(
unpackChannelInfo
.
status
==
ApeConsts
.
CHANNEL_STATUS_OPENING
)
{
//正在推流
receiveChannelInfo
.
m3u8Url
=
""
;
receiveChannelInfo
.
rtmpUrl
=
""
;
receiveChannelInfo
.
replay
=
""
;
receiveChannelInfo
.
m3u8Url
=
""
;
receiveChannelInfo
.
rtmpUrl
=
""
;
receiveChannelInfo
.
replay
=
""
;
receiveChannelInfo
.
seek
=
seek
||
0
;
//这个是录制回放时使用的seek
receiveChannelInfo
.
seek
=
seek
||
0
;
//这个是录制回放时使用的seek
let
m3u8Stream
=
this
.
mediaModule
.
getMediaPlayPath
({
"type"
:
"m3u8"
,
"streamId"
:
unpackChannelInfo
.
streamId
});
let
rtmpStream
=
this
.
mediaModule
.
getMediaPlayPath
({
"type"
:
"rtmp"
,
"streamId"
:
unpackChannelInfo
.
streamId
});
let
replay
=
this
.
mediaModule
.
getMediaRecordPlaybackPath
({
"type"
:
"m3u8"
,
"streamId"
:
unpackChannelInfo
.
streamId
});
let
m3u8Stream
=
this
.
mediaModule
.
getMediaPlayPath
({
"type"
:
"m3u8"
,
"streamId"
:
unpackChannelInfo
.
streamId
});
let
rtmpStream
=
this
.
mediaModule
.
getMediaPlayPath
({
"type"
:
"rtmp"
,
"streamId"
:
unpackChannelInfo
.
streamId
});
let
replay
=
this
.
mediaModule
.
getMediaRecordPlaybackPath
({
"type"
:
"m3u8"
,
"streamId"
:
unpackChannelInfo
.
streamId
});
if
(
m3u8Stream
.
code
==
0
){
receiveChannelInfo
.
m3u8Url
=
m3u8Stream
.
playUrl
;
if
(
m3u8Stream
.
code
==
0
)
{
receiveChannelInfo
.
m3u8Url
=
m3u8Stream
.
playUrl
;
}
if
(
rtmpStream
.
code
==
0
){
receiveChannelInfo
.
rtmpUrl
=
rtmpStream
.
playUrl
;
if
(
rtmpStream
.
code
==
0
)
{
receiveChannelInfo
.
rtmpUrl
=
rtmpStream
.
playUrl
;
}
if
(
replay
.
code
==
0
){
receiveChannelInfo
.
replay
=
replay
.
playUrl
;
if
(
replay
.
code
==
0
)
{
receiveChannelInfo
.
replay
=
replay
.
playUrl
;
}
loger
.
log
(
"AUDIO_PLAY->"
,
receiveChannelInfo
);
loger
.
log
(
"AUDIO_PLAY->"
,
receiveChannelInfo
);
//广播播放视频的消息
this
.
_emit
(
MessageTypes
.
AUDIO_PLAY
,
receiveChannelInfo
);
}
else
{
loger
.
log
(
"AUDIO_STOP->"
,
receiveChannelInfo
);
}
else
{
loger
.
log
(
"AUDIO_STOP->"
,
receiveChannelInfo
);
//流已经停止
this
.
_emit
(
MessageTypes
.
AUDIO_STOP
,
receiveChannelInfo
);
}
}
else
{
}
else
{
loger
.
warn
(
"消息是自己发送的或者是消息无效,不需要处理,消息内容如下:"
);
loger
.
log
(
unpackChannelInfo
);
if
(
unpackChannelInfo
.
status
==
ApeConsts
.
CHANNEL_STATUS_OPENING
){
GlobalConfig
.
openMicrophones
=
EngineUtils
.
creatTimestamp
();
GlobalConfig
.
openCamera
=
0
;
}
else
{
GlobalConfig
.
openCamera
=
0
;
GlobalConfig
.
openMicrophones
=
0
;
}
this
.
_emit
(
MessageTypes
.
USER_DEVICE_STATUS_CHAANGE
,{
nodeId
:
GlobalConfig
.
nodeId
,
userRole
:
GlobalConfig
.
userRole
,
userName
:
GlobalConfig
.
userName
,
userId
:
GlobalConfig
.
userId
,
openCamera
:
GlobalConfig
.
openCamera
,
openMicrophones
:
GlobalConfig
.
openMicrophones
if
(
unpackChannelInfo
.
status
==
ApeConsts
.
CHANNEL_STATUS_OPENING
)
{
GlobalConfig
.
openMicrophones
=
EngineUtils
.
creatTimestamp
();
GlobalConfig
.
openCamera
=
0
;
}
else
{
GlobalConfig
.
openCamera
=
0
;
GlobalConfig
.
openMicrophones
=
0
;
}
this
.
_emit
(
MessageTypes
.
USER_DEVICE_STATUS_CHAANGE
,
{
nodeId
:
GlobalConfig
.
nodeId
,
userRole
:
GlobalConfig
.
userRole
,
userName
:
GlobalConfig
.
userName
,
userId
:
GlobalConfig
.
userId
,
openCamera
:
GlobalConfig
.
openCamera
,
openMicrophones
:
GlobalConfig
.
openMicrophones
});
}
MediaModule
.
allMediaChannelsList
[
itemIdx
]
=
unpackChannelInfo
;
console
.
log
(
'MediaModule.allMediaChannelsList'
,
MediaModule
.
allMediaChannelsList
);
MediaModule
.
allMediaChannelsList
[
itemIdx
]
=
unpackChannelInfo
;
console
.
log
(
'MediaModule.allMediaChannelsList'
,
MediaModule
.
allMediaChannelsList
);
this
.
_emit
(
MessageTypes
.
AUDIO_UPDATE
,
unpackChannelInfo
);
}
//更新媒体文件模块的录制信息,每次开启录制的时候需要把当前媒体文件的信息更新一次
updaterRecordApeStatus
(
_param
){
console
.
warn
(
"录制状态发送改变->更新当前的状态->"
,
this
.
mediaModule
.
mediaChannels
);
for
(
let
i
in
this
.
mediaModule
.
mediaChannels
){
let
channelInfo
=
this
.
mediaModule
.
mediaChannels
[
i
];
if
(
channelInfo
){
if
(
channelInfo
.
status
==
ApeConsts
.
CHANNEL_STATUS_RELEASED
){
channelInfo
.
owner
=
0
;
}
else
{
channelInfo
.
owner
=
channelInfo
.
fromNodeId
;
updaterRecordApeStatus
(
_param
)
{
console
.
warn
(
"录制状态发送改变->更新当前的状态->"
,
this
.
mediaModule
.
mediaChannels
);
for
(
let
i
in
this
.
mediaModule
.
mediaChannels
)
{
let
channelInfo
=
this
.
mediaModule
.
mediaChannels
[
i
];
if
(
channelInfo
)
{
if
(
channelInfo
.
status
==
ApeConsts
.
CHANNEL_STATUS_RELEASED
)
{
channelInfo
.
owner
=
0
;
}
else
{
channelInfo
.
owner
=
channelInfo
.
fromNodeId
;
}
this
.
sendTableUpdateHandler
(
channelInfo
);
}
...
...
@@ -458,23 +495,23 @@ class AudioApe extends Ape {
//判断type类型,根据type设置不同的参数
let
packPduModel
=
new
pdu
[
'RCAudioChannelInfoPdu'
];
packPduModel
.
status
=
_param
.
status
||
ApeConsts
.
CHANNEL_STATUS_RELEASED
;
packPduModel
.
status
=
_param
.
status
||
ApeConsts
.
CHANNEL_STATUS_RELEASED
;
packPduModel
.
channelId
=
_itemIdx
;
packPduModel
.
streamId
=
_param
.
streamId
||
""
;
packPduModel
.
siteId
=
_param
.
siteId
||
GlobalConfig
.
siteId
;
//GlobalConfig.siteId;
packPduModel
.
classId
=
parseInt
(
_param
.
classId
)
||
parseInt
(
GlobalConfig
.
classId
);
packPduModel
.
userId
=
_param
.
userId
||
"0"
;
packPduModel
.
mediaType
=
_param
.
mediaType
||
ApeConsts
.
MEDIA_TYPE_AUDIO
;
packPduModel
.
timestamp
=
_param
.
timestamp
||
EngineUtils
.
creatTimestamp
();
packPduModel
.
fromNodeId
=
_param
.
nodeId
||
GlobalConfig
.
nodeId
;
packPduModel
.
userName
=
_param
.
userName
||
GlobalConfig
.
userName
||
""
;
packPduModel
.
streamId
=
_param
.
streamId
||
""
;
packPduModel
.
siteId
=
_param
.
siteId
||
GlobalConfig
.
siteId
;
//GlobalConfig.siteId;
packPduModel
.
classId
=
parseInt
(
_param
.
classId
)
||
parseInt
(
GlobalConfig
.
classId
);
packPduModel
.
userId
=
_param
.
userId
||
"0"
;
packPduModel
.
mediaType
=
_param
.
mediaType
||
ApeConsts
.
MEDIA_TYPE_AUDIO
;
packPduModel
.
timestamp
=
_param
.
timestamp
||
EngineUtils
.
creatTimestamp
();
packPduModel
.
fromNodeId
=
_param
.
nodeId
||
GlobalConfig
.
nodeId
;
packPduModel
.
userName
=
_param
.
userName
||
GlobalConfig
.
userName
||
""
;
packPduModel
.
toNodeId
=
0
;
packPduModel
.
userRole
=
_param
.
userRole
||
GlobalConfig
.
userRole
;
packPduModel
.
screenWidth
=
_param
.
screenWidth
||
GlobalConfig
.
screenWidth
;
packPduModel
.
screenHeight
=
_param
.
screenHeight
||
GlobalConfig
.
screenHeight
;
packPduModel
.
deviceType
=
_param
.
deviceType
||
GlobalConfig
.
deviceType
;
packPduModel
.
optionJsonData
=
_param
.
optionJsonData
||
GlobalConfig
.
optionJsonData
;
loger
.
log
(
"packPdu->"
,
packPduModel
);
packPduModel
.
userRole
=
_param
.
userRole
||
GlobalConfig
.
userRole
;
packPduModel
.
screenWidth
=
_param
.
screenWidth
||
GlobalConfig
.
screenWidth
;
packPduModel
.
screenHeight
=
_param
.
screenHeight
||
GlobalConfig
.
screenHeight
;
packPduModel
.
deviceType
=
_param
.
deviceType
||
GlobalConfig
.
deviceType
;
packPduModel
.
optionJsonData
=
GlobalConfig
.
optionJsonData
;
loger
.
log
(
"packPdu->"
,
packPduModel
);
return
packPduModel
;
}
...
...
@@ -485,7 +522,7 @@ class AudioApe extends Ape {
}
try
{
let
packChannelInfo
=
pdu
[
'RCAudioChannelInfoPdu'
].
decode
(
itemData
);
loger
.
log
(
"unPackPdu->"
,
packChannelInfo
);
loger
.
log
(
"unPackPdu->"
,
packChannelInfo
);
return
packChannelInfo
;
}
catch
(
err
)
{
loger
.
log
(
"unPackPdu error->itemIdx="
+
itemIdx
+
" err:"
+
err
.
message
);
...
...
src/apes/VideoApe.js
查看文件 @
d333c31
...
...
@@ -21,18 +21,18 @@ class VideoApe extends Ape {
ApeConsts
.
VIDEO_SESSION_TAG
);
this
.
mediaModule
=
new
MediaModule
();
this
.
mediaModule
.
MEDIA_OBJ_TABLE_ID
=
ApeConsts
.
VIDEO_OBJ_TABLE_ID
;
this
.
mediaModule
.
mediaChannels
=
{};
this
.
mediaModule
.
mediaType
=
ApeConsts
.
MEDIA_TYPE_VIDEO
;
this
.
shareApe
=
new
ShareApe
();
this
.
shareApe
.
on
(
MessageTypes
.
PUBLISH_SCREEN_SHARE_SUCCESS
,
this
.
onPublishScreenShareSuccess
.
bind
(
this
));
this
.
shareApe
.
on
(
MessageTypes
.
PUBLISH_SCREEN_SHARE_FAILE
,
this
.
onPublishScreenShareFaile
.
bind
(
this
));
this
.
shareApe
.
on
(
MessageTypes
.
PUBLISH_SCREEN_SHARE_CLOSE
,
this
.
onPublishScreenShareClose
.
bind
(
this
));
this
.
shareApe
.
on
(
MessageTypes
.
PUBLISH_SCREEN_SHARE_DISCONNECT
,
this
.
onPublishScreenShareDisconnect
.
bind
(
this
));
this
.
shareApe
.
on
(
MessageTypes
.
PUBLISH_SCREEN_SHARE_CONNECTED
,
this
.
onPublishScreenShareConnected
.
bind
(
this
));
this
.
shareApe
.
on
(
MessageTypes
.
PUBLISH_SCREEN_MOVIE_INFO_CHANGE
,
this
.
onPublishScreenMovieInfoChange
.
bind
(
this
));
this
.
shareApe
.
on
(
MessageTypes
.
PUBLISH_SCREEN_VIDEO_INFO_CHANGE
,
this
.
onPublishScreenVideoInfoChange
.
bind
(
this
));
this
.
mediaModule
=
new
MediaModule
();
this
.
mediaModule
.
MEDIA_OBJ_TABLE_ID
=
ApeConsts
.
VIDEO_OBJ_TABLE_ID
;
this
.
mediaModule
.
mediaChannels
=
{};
this
.
mediaModule
.
mediaType
=
ApeConsts
.
MEDIA_TYPE_VIDEO
;
this
.
shareApe
=
new
ShareApe
();
this
.
shareApe
.
on
(
MessageTypes
.
PUBLISH_SCREEN_SHARE_SUCCESS
,
this
.
onPublishScreenShareSuccess
.
bind
(
this
));
this
.
shareApe
.
on
(
MessageTypes
.
PUBLISH_SCREEN_SHARE_FAILE
,
this
.
onPublishScreenShareFaile
.
bind
(
this
));
this
.
shareApe
.
on
(
MessageTypes
.
PUBLISH_SCREEN_SHARE_CLOSE
,
this
.
onPublishScreenShareClose
.
bind
(
this
));
this
.
shareApe
.
on
(
MessageTypes
.
PUBLISH_SCREEN_SHARE_DISCONNECT
,
this
.
onPublishScreenShareDisconnect
.
bind
(
this
));
this
.
shareApe
.
on
(
MessageTypes
.
PUBLISH_SCREEN_SHARE_CONNECTED
,
this
.
onPublishScreenShareConnected
.
bind
(
this
));
this
.
shareApe
.
on
(
MessageTypes
.
PUBLISH_SCREEN_MOVIE_INFO_CHANGE
,
this
.
onPublishScreenMovieInfoChange
.
bind
(
this
));
this
.
shareApe
.
on
(
MessageTypes
.
PUBLISH_SCREEN_VIDEO_INFO_CHANGE
,
this
.
onPublishScreenVideoInfoChange
.
bind
(
this
));
// Ape Models
this
.
registerKey
(
this
.
_session_id
,
this
.
_session_name
,
this
.
_session_tag
,
new
ArrayBuffer
);
...
...
@@ -41,10 +41,11 @@ class VideoApe extends Ape {
// videoApe 监听视频控制消息,用户之间的消息传递
this
.
on
(
pdu
.
RCPDU_SEND_VIDEO_DATA_REQUEST
,
this
.
receiveVideoCommandHandler
.
bind
(
this
));
}
//ape加入成功
onJoinChannelHandlerSuccess
()
{
onJoinChannelHandlerSuccess
()
{
//这个设置很重要,因为只有Sass流程完成之后,APE才能取得GlobalConfig中的数据
this
.
mediaModule
.
maxMediaChannel
=
GlobalConfig
.
maxVideoChannels
;
this
.
mediaModule
.
maxMediaChannel
=
GlobalConfig
.
maxVideoChannels
;
}
/////////////发送数据操作////////////////////////////////////////////
...
...
@@ -57,66 +58,76 @@ class VideoApe extends Ape {
//获取推流地址
getPublishVideoPath
(
_param
)
{
loger
.
log
(
'获取推流地址->'
);
if
(
!
this
.
mcu
.
connected
)
{
if
(
!
this
.
mcu
.
connected
)
{
loger
.
warn
(
GlobalConfig
.
getCurrentStatus
());
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"已经断开连接"
};
}
//监课比较特殊,不占用课堂内的音视频路数,额外创建
if
(
GlobalConfig
.
userRole
==
ApeConsts
.
invisible
){
let
result
=
this
.
mediaModule
.
getMediaPublishPathForInVisible
(
_param
);
this
.
_emit
(
MessageTypes
.
VIDEO_GET_PUBLISH_PATH
,
result
);
if
(
GlobalConfig
.
userRole
==
ApeConsts
.
invisible
)
{
let
result
=
this
.
mediaModule
.
getMediaPublishPathForInVisible
(
_param
);
this
.
_emit
(
MessageTypes
.
VIDEO_GET_PUBLISH_PATH
,
result
);
return
result
;
}
//非监课的身份,需要判断是否可以继续推流
//需要判断当前已经使用的流路数
let
openChannel
=
0
;
let
allChannels
=
MediaModule
.
allMediaChannelsList
;
for
(
let
i
in
allChannels
){
let
channel
=
allChannels
[
i
];
if
(
channel
&&
channel
.
status
==
ApeConsts
.
CHANNEL_STATUS_OPENING
&&
channel
.
userRole
!=
ApeConsts
.
invisible
){
let
openChannel
=
0
;
let
allChannels
=
MediaModule
.
allMediaChannelsList
;
for
(
let
i
in
allChannels
)
{
let
channel
=
allChannels
[
i
];
if
(
channel
&&
channel
.
status
==
ApeConsts
.
CHANNEL_STATUS_OPENING
&&
channel
.
userRole
!=
ApeConsts
.
invisible
)
{
//正在开启的才计数,监课开启的不计算在内
openChannel
++
;
}
}
//如果已经开启的数量大于等于最大允许开启的数量,不允许再推流
if
(
openChannel
>=
GlobalConfig
.
maxMediaChannels
){
loger
.
warn
(
'不能再打开设备->当前开启的设备数量->'
,
openChannel
);
if
(
openChannel
>=
GlobalConfig
.
maxMediaChannels
)
{
loger
.
warn
(
'不能再打开设备->当前开启的设备数量->'
,
openChannel
);
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"不能再打开设备,当前开启的设备数量"
};
}
let
result
=
this
.
mediaModule
.
getMediaPublishPath
(
_param
);
this
.
_emit
(
MessageTypes
.
VIDEO_GET_PUBLISH_PATH
,
result
);
let
result
=
this
.
mediaModule
.
getMediaPublishPath
(
_param
);
this
.
_emit
(
MessageTypes
.
VIDEO_GET_PUBLISH_PATH
,
result
);
return
result
;
}
//获取当前所有频道信息
getAllChannelInfo
(
_param
)
{
getAllChannelInfo
(
_param
)
{
loger
.
log
(
'获取当前所有频道信息->'
);
return
this
.
mediaModule
.
getAllMediaChannelInfo
();
}
//推流
publishVideo
(
_param
)
{
if
(
!
this
.
mcu
.
connected
)
{
if
(
!
this
.
mcu
.
connected
)
{
loger
.
warn
(
GlobalConfig
.
getCurrentStatus
());
this
.
_emit
(
MessageTypes
.
VIDEO_PUBLISH_RESULT
,{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"已经断开连接!"
,
"mediaId"
:
0
});
this
.
_emit
(
MessageTypes
.
VIDEO_PUBLISH_RESULT
,
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"已经断开连接!"
,
"mediaId"
:
0
});
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"已经断开连接"
};
}
if
(
_param
==
null
||
_param
.
publishUrl
==
null
)
{
if
(
_param
==
null
||
_param
.
publishUrl
==
null
)
{
loger
.
warn
(
'推流->参数错误'
,
_param
);
this
.
_emit
(
MessageTypes
.
MCU_ERROR
,
MessageTypes
.
ERR_APE_INTERFACE_PARAM_WRONG
);
this
.
_emit
(
MessageTypes
.
VIDEO_PUBLISH_RESULT
,{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"参数错误!"
,
"mediaId"
:
0
});
this
.
_emit
(
MessageTypes
.
VIDEO_PUBLISH_RESULT
,
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"参数错误!"
,
"mediaId"
:
0
});
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"参数错误"
};
}
//获取可选参数,转换为JSON字符串
try
{
GlobalConfig
.
optionJsonData
=
JSON
.
stringify
(
_param
.
optionJsonData
)
||
""
}
catch
(
err
)
{
GlobalConfig
.
optionJsonData
=
""
;
}
//根据推流的地址获取对应的频道信息
let
needPublishChannelInfo
=
this
.
mediaModule
.
getNeedPublishMediaChannel
(
_param
.
publishUrl
);
if
(
needPublishChannelInfo
==
null
){
let
needPublishChannelInfo
=
this
.
mediaModule
.
getNeedPublishMediaChannel
(
_param
.
publishUrl
);
if
(
needPublishChannelInfo
==
null
)
{
loger
.
warn
(
'推流->推流数据已经无效'
,
_param
);
this
.
_emit
(
MessageTypes
.
VIDEO_PUBLISH_RESULT
,{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"推流数据已经无效!"
,
"mediaId"
:
0
});
this
.
_emit
(
MessageTypes
.
VIDEO_PUBLISH_RESULT
,
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"推流数据已经无效!"
,
"mediaId"
:
0
});
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"推流数据已经无效"
};
}
...
...
@@ -124,62 +135,82 @@ class VideoApe extends Ape {
let
freeChannel
=
this
.
mediaModule
.
getFreeMediaChannel
();
if
(
freeChannel
==
0
)
{
loger
.
warn
(
"推流->不能再打开更多的设备 "
);
this
.
_emit
(
MessageTypes
.
VIDEO_PUBLISH_RESULT
,{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"不能再打开更多的设备!"
,
"mediaId"
:
0
});
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"不能再打开更多的设备"
,
"mediaChannels"
:
this
.
mediaModule
.
mediaChannels
};
this
.
_emit
(
MessageTypes
.
VIDEO_PUBLISH_RESULT
,
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"不能再打开更多的设备!"
,
"mediaId"
:
0
});
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"不能再打开更多的设备"
,
"mediaChannels"
:
this
.
mediaModule
.
mediaChannels
};
}
//判断当前的频道是否已经占用
if
(
this
.
mediaModule
.
checkChannelIsOpening
(
needPublishChannelInfo
.
channelId
)){
if
(
needPublishChannelInfo
.
nodeId
==
GlobalConfig
.
nodeId
){
loger
.
warn
(
needPublishChannelInfo
.
channelId
,
"已经推送过消息,不需要再次推送"
);
this
.
_emit
(
MessageTypes
.
VIDEO_PUBLISH_RESULT
,{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
"已经推送过消息,不需要再次推送!"
,
"mediaId"
:
needPublishChannelInfo
.
channelId
});
return
{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
"已经推送过消息,不需要再次推送!"
,
"mediaId"
:
needPublishChannelInfo
.
channelId
};
}
else
{
loger
.
warn
(
needPublishChannelInfo
.
channelId
,
"频道已经被占用"
);
this
.
_emit
(
MessageTypes
.
VIDEO_PUBLISH_RESULT
,{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"频道已经被占用!"
,
"mediaId"
:
0
});
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"频道已经被占用!"
,
"mediaChannels"
:
this
.
mediaModule
.
mediaChannels
};
}
}
let
channelInfo
=
this
.
mediaModule
.
getDefaultChannelInfo
();
channelInfo
.
owner
=
GlobalConfig
.
nodeId
;
channelInfo
.
status
=
ApeConsts
.
CHANNEL_STATUS_OPENING
;
channelInfo
.
channelId
=
needPublishChannelInfo
.
channelId
;
channelInfo
.
streamId
=
needPublishChannelInfo
.
streamId
;
//按规则拼接的流名称
channelInfo
.
timestamp
=
needPublishChannelInfo
.
timestamp
;
//时间戳
channelInfo
.
mediaType
=
ApeConsts
.
MEDIA_TYPE_VIDEO
;
if
(
this
.
mediaModule
.
checkChannelIsOpening
(
needPublishChannelInfo
.
channelId
))
{
if
(
needPublishChannelInfo
.
nodeId
==
GlobalConfig
.
nodeId
)
{
loger
.
warn
(
needPublishChannelInfo
.
channelId
,
"已经推送过消息,不需要再次推送"
);
this
.
_emit
(
MessageTypes
.
VIDEO_PUBLISH_RESULT
,
{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
"已经推送过消息,不需要再次推送!"
,
"mediaId"
:
needPublishChannelInfo
.
channelId
});
return
{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
"已经推送过消息,不需要再次推送!"
,
"mediaId"
:
needPublishChannelInfo
.
channelId
};
}
else
{
loger
.
warn
(
needPublishChannelInfo
.
channelId
,
"频道已经被占用"
);
this
.
_emit
(
MessageTypes
.
VIDEO_PUBLISH_RESULT
,
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"频道已经被占用!"
,
"mediaId"
:
0
});
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"频道已经被占用!"
,
"mediaChannels"
:
this
.
mediaModule
.
mediaChannels
};
}
}
let
channelInfo
=
this
.
mediaModule
.
getDefaultChannelInfo
();
channelInfo
.
owner
=
GlobalConfig
.
nodeId
;
channelInfo
.
status
=
ApeConsts
.
CHANNEL_STATUS_OPENING
;
channelInfo
.
channelId
=
needPublishChannelInfo
.
channelId
;
channelInfo
.
streamId
=
needPublishChannelInfo
.
streamId
;
//按规则拼接的流名称
channelInfo
.
timestamp
=
needPublishChannelInfo
.
timestamp
;
//时间戳
channelInfo
.
mediaType
=
ApeConsts
.
MEDIA_TYPE_VIDEO
;
this
.
sendTableUpdateHandler
(
channelInfo
);
this
.
_emit
(
MessageTypes
.
VIDEO_PUBLISH_RESULT
,{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
"推流成功!"
,
"mediaId"
:
needPublishChannelInfo
.
channelId
});
return
{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
"推流成功!"
,
"mediaId"
:
needPublishChannelInfo
.
channelId
};
this
.
_emit
(
MessageTypes
.
VIDEO_PUBLISH_RESULT
,
{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
"推流成功!"
,
"mediaId"
:
needPublishChannelInfo
.
channelId
});
return
{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
"推流成功!"
,
"mediaId"
:
needPublishChannelInfo
.
channelId
};
}
//停止推流,
stopPublishVideo
(
_param
)
{
loger
.
log
(
'停止推流->'
,
_param
);
if
(
!
this
.
mcu
.
connected
){
loger
.
log
(
'停止推流->'
,
_param
);
if
(
!
this
.
mcu
.
connected
)
{
loger
.
warn
(
GlobalConfig
.
getCurrentStatus
());
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"已经断开连接"
};
}
//默认为自己的nodeId,_param如果为空,那么默认就是当前自己的nodeId,否则用_param
let
nodeId
=
GlobalConfig
.
nodeId
;
if
(
_param
&&
parseInt
(
_param
.
nodeId
)
>
0
){
nodeId
=
parseInt
(
_param
.
nodeId
);
let
nodeId
=
GlobalConfig
.
nodeId
;
if
(
_param
&&
parseInt
(
_param
.
nodeId
)
>
0
)
{
nodeId
=
parseInt
(
_param
.
nodeId
);
}
//默认为0,如果releaseChannelId 存在就释放releaseChannelId通道
let
releaseChannelId
=
0
;
if
(
_param
&&
parseInt
(
_param
.
mediaId
)
>
0
){
releaseChannelId
=
parseInt
(
_param
.
mediaId
);
let
releaseChannelId
=
0
;
if
(
_param
&&
parseInt
(
_param
.
mediaId
)
>
0
)
{
releaseChannelId
=
parseInt
(
_param
.
mediaId
);
}
//释放channelId 的占用
if
(
releaseChannelId
>
0
)
{
if
(
releaseChannelId
>
0
)
{
//第一种情况,释放nodeId占用的指定mediaId (channelId)
this
.
_releaseChannelForNodeId
(
nodeId
,
releaseChannelId
);
}
else
{
this
.
_releaseChannelForNodeId
(
nodeId
,
releaseChannelId
);
}
else
{
//第二种情况,释放nodeId占用的所有channelId
this
.
_releaseNodeIdAllChannel
(
nodeId
);
}
...
...
@@ -188,74 +219,85 @@ class VideoApe extends Ape {
//==========================屏幕共享=========================================================================
//屏幕共享连接打开
onPublishScreenShareFaile
()
{
onPublishScreenShareFaile
()
{
loger
.
log
(
'屏幕共享推流失败->'
);
this
.
_emit
(
MessageTypes
.
PUBLISH_SCREEN_SHARE_FAILE
);
}
//屏幕共享连接关闭
onPublishScreenShareClose
()
{
onPublishScreenShareClose
()
{
loger
.
log
(
'屏幕共享推流关闭->'
);
this
.
_emit
(
MessageTypes
.
PUBLISH_SCREEN_SHARE_CLOSE
);
}
//屏幕共享连接失败
onPublishScreenShareDisconnect
()
{
onPublishScreenShareDisconnect
()
{
loger
.
log
(
'屏幕共享服务器连接失败->'
);
this
.
_emit
(
MessageTypes
.
PUBLISH_SCREEN_SHARE_DISCONNECT
);
}
//屏幕共享连接失败
onPublishScreenShareConnected
()
{
onPublishScreenShareConnected
()
{
loger
.
log
(
'屏幕共享服务器连接成功->'
);
this
.
_emit
(
MessageTypes
.
PUBLISH_SCREEN_SHARE_CONNECTED
);
}
onPublishScreenMovieInfoChange
(
data
){
onPublishScreenMovieInfoChange
(
data
)
{
loger
.
log
(
'屏幕共享MOVIE信息发生改变->'
);
this
.
_emit
(
MessageTypes
.
PUBLISH_SCREEN_MOVIE_INFO_CHANGE
,
data
);
this
.
_emit
(
MessageTypes
.
PUBLISH_SCREEN_MOVIE_INFO_CHANGE
,
data
);
}
onPublishScreenVideoInfoChange
(
data
){
onPublishScreenVideoInfoChange
(
data
)
{
loger
.
log
(
'屏幕共享视频信息发生改变->'
);
this
.
_emit
(
MessageTypes
.
PUBLISH_SCREEN_VIDEO_INFO_CHANGE
,
data
);
this
.
_emit
(
MessageTypes
.
PUBLISH_SCREEN_VIDEO_INFO_CHANGE
,
data
);
}
//监听屏幕共享发布成功
onPublishScreenShareSuccess
()
{
onPublishScreenShareSuccess
()
{
loger
.
log
(
'屏幕共享推流成功之后才能更新同步消息->'
);
//屏幕共享推流成功之后才能更新同步消息
let
channelInfo
=
this
.
shareApe
.
getPublishChannelInfo
();
let
channelInfo
=
this
.
shareApe
.
getPublishChannelInfo
();
this
.
sendTableUpdateHandler
(
channelInfo
);
this
.
_emit
(
MessageTypes
.
PUBLISH_SCREEN_SHARE_SUCCESS
,{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
"桌面共享推流!"
,
"mediaId"
:
channelInfo
.
channelId
});
return
{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
"桌面共享推流!"
,
"mediaId"
:
channelInfo
.
channelId
};
this
.
_emit
(
MessageTypes
.
PUBLISH_SCREEN_SHARE_SUCCESS
,
{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
"桌面共享推流!"
,
"mediaId"
:
channelInfo
.
channelId
});
return
{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
"桌面共享推流!"
,
"mediaId"
:
channelInfo
.
channelId
};
}
//桌面共享推流
publishScreenShare
(
_param
)
{
if
(
!
this
.
mcu
.
connected
)
{
if
(
!
this
.
mcu
.
connected
)
{
loger
.
warn
(
GlobalConfig
.
getCurrentStatus
());
this
.
_emit
(
MessageTypes
.
VIDEO_PUBLISH_RESULT
,{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"已经断开连接!"
,
"mediaId"
:
0
});
this
.
_emit
(
MessageTypes
.
VIDEO_PUBLISH_RESULT
,
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"已经断开连接!"
,
"mediaId"
:
0
});
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"已经断开连接"
};
}
let
publishType
=
'flash'
;
if
(
_param
&&
_param
.
type
==
'live'
){
publishType
=
'live'
;
let
publishType
=
'flash'
;
if
(
_param
&&
_param
.
type
==
'live'
)
{
publishType
=
'live'
;
}
//老师能开启屏幕共享
if
(
GlobalConfig
.
isHost
)
{
if
(
GlobalConfig
.
isHost
)
{
//获取屏幕共享推流的地址
let
shareResult
=
this
.
mediaModule
.
getMediaPublishPathForScreenShare
(
this
.
shareApe
.
channelId
,
publishType
);
shareResult
.
ip
=
_param
.
ip
||
""
;
//外部可以设置屏幕共享的IP
shareResult
.
port
=
_param
.
port
||
""
;
//外部可以设置屏幕共享的端口
shareResult
.
ip
=
_param
.
ip
||
""
;
//外部可以设置屏幕共享的IP
shareResult
.
port
=
_param
.
port
||
""
;
//外部可以设置屏幕共享的端口
this
.
shareApe
.
publish
(
shareResult
);
}
}
//停止桌面共享推流
stopPublishScreenShare
(
_param
)
{
loger
.
log
(
'停止桌面共享推流->'
,
_param
);
if
(
!
this
.
mcu
.
connected
){
loger
.
log
(
'停止桌面共享推流->'
,
_param
);
if
(
!
this
.
mcu
.
connected
)
{
loger
.
warn
(
GlobalConfig
.
getCurrentStatus
());
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"已经断开连接"
};
}
//只有老师能停止屏幕共享
if
(
GlobalConfig
.
isHost
){
let
channelInfo
=
this
.
shareApe
.
getDefaultChannelInfo
();
channelInfo
.
status
=
ApeConsts
.
CHANNEL_STATUS_RELEASED
;
if
(
GlobalConfig
.
isHost
)
{
let
channelInfo
=
this
.
shareApe
.
getDefaultChannelInfo
();
channelInfo
.
status
=
ApeConsts
.
CHANNEL_STATUS_RELEASED
;
this
.
sendTableUpdateHandler
(
channelInfo
);
this
.
shareApe
.
stopPublish
();
...
...
@@ -266,56 +308,57 @@ class VideoApe extends Ape {
//=============================屏幕共享 end=================================================
//释放nodeId占用的指定的channelId频道
_releaseChannelForNodeId
(
nodeId
,
channelId
){
loger
.
log
(
nodeId
,
"_releaseChannelForNodeId-->channelId"
,
channelId
);
let
channelInfo
=
this
.
mediaModule
.
mediaChannels
[
channelId
];
if
(
channelInfo
&&
channelInfo
.
status
==
ApeConsts
.
CHANNEL_STATUS_OPENING
){
if
(
channelInfo
.
fromNodeId
==
nodeId
){
_releaseChannelForNodeId
(
nodeId
,
channelId
)
{
loger
.
log
(
nodeId
,
"_releaseChannelForNodeId-->channelId"
,
channelId
);
let
channelInfo
=
this
.
mediaModule
.
mediaChannels
[
channelId
];
if
(
channelInfo
&&
channelInfo
.
status
==
ApeConsts
.
CHANNEL_STATUS_OPENING
)
{
if
(
channelInfo
.
fromNodeId
==
nodeId
)
{
let
channelInfo
=
this
.
mediaModule
.
getDefaultChannelInfo
();
channelInfo
.
status
=
ApeConsts
.
CHANNEL_STATUS_RELEASED
;
channelInfo
.
channelId
=
channelId
;
let
channelInfo
=
this
.
mediaModule
.
getDefaultChannelInfo
();
channelInfo
.
status
=
ApeConsts
.
CHANNEL_STATUS_RELEASED
;
channelInfo
.
channelId
=
channelId
;
this
.
sendTableUpdateHandler
(
channelInfo
);
}
else
{
loger
.
warn
(
channelId
,
"不属于nodeId"
,
nodeId
,
"不能释放"
,
channelInfo
);
}
else
{
loger
.
warn
(
channelId
,
"不属于nodeId"
,
nodeId
,
"不能释放"
,
channelInfo
);
}
}
else
{
loger
.
warn
(
nodeId
,
"要释放的channel不存在或者已经释放-->channelId"
,
channelInfo
);
}
else
{
loger
.
warn
(
nodeId
,
"要释放的channel不存在或者已经释放-->channelId"
,
channelInfo
);
}
}
//释放nodeId占用的所有频道
_releaseNodeIdAllChannel
(
nodeId
){
if
(
!
this
.
mcu
.
connected
){
_releaseNodeIdAllChannel
(
nodeId
)
{
if
(
!
this
.
mcu
.
connected
)
{
clearTimeout
(
this
.
releaseTimeId
);
loger
.
warn
(
GlobalConfig
.
getCurrentStatus
());
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"已经断开连接"
};
}
loger
.
log
(
"释放nodeId占用的所有频道->"
,
nodeId
);
loger
.
log
(
"释放nodeId占用的所有频道->"
,
nodeId
);
let
openingChannelInfo
=
this
.
mediaModule
.
getOpeningMediaChannelForNodeId
(
nodeId
);
if
(
openingChannelInfo
.
channelId
==
0
)
{
loger
.
warn
(
nodeId
,
"没有占用channel不需要处理"
);
if
(
openingChannelInfo
.
channelId
==
0
)
{
loger
.
warn
(
nodeId
,
"没有占用channel不需要处理"
);
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"没有占用channel不需要处理"
};
}
let
channelInfo
=
this
.
mediaModule
.
getDefaultChannelInfo
();
channelInfo
.
status
=
ApeConsts
.
CHANNEL_STATUS_RELEASED
;
channelInfo
.
channelId
=
openingChannelInfo
.
channelId
;
channelInfo
.
nodeId
=
openingChannelInfo
.
fromNodeId
;
//发送消息的人员nodeId
channelInfo
.
userRole
=
openingChannelInfo
.
userRole
;
channelInfo
.
userName
=
openingChannelInfo
.
userName
;
channelInfo
.
userId
=
openingChannelInfo
.
userId
;
let
channelInfo
=
this
.
mediaModule
.
getDefaultChannelInfo
();
channelInfo
.
status
=
ApeConsts
.
CHANNEL_STATUS_RELEASED
;
channelInfo
.
channelId
=
openingChannelInfo
.
channelId
;
channelInfo
.
nodeId
=
openingChannelInfo
.
fromNodeId
;
//发送消息的人员nodeId
channelInfo
.
userRole
=
openingChannelInfo
.
userRole
;
channelInfo
.
userName
=
openingChannelInfo
.
userName
;
channelInfo
.
userId
=
openingChannelInfo
.
userId
;
this
.
sendTableUpdateHandler
(
channelInfo
);
//递归检查,800毫秒之后执行
this
.
releaseTimeId
=
setTimeout
(
function
(){
loger
.
warn
(
nodeId
,
"检查频道是否占用"
);
this
.
releaseTimeId
=
setTimeout
(
function
()
{
loger
.
warn
(
nodeId
,
"检查频道是否占用"
);
this
.
_releaseNodeIdAllChannel
(
nodeId
);
}.
bind
(
this
),
800
);
}.
bind
(
this
),
800
);
}
sendVideoBroadcastMsg
(
_param
)
{
if
(
!
this
.
mcu
.
connected
)
{
if
(
!
this
.
mcu
.
connected
)
{
loger
.
warn
(
GlobalConfig
.
getCurrentStatus
());
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"已经断开连接"
};
}
...
...
@@ -341,7 +384,7 @@ class VideoApe extends Ape {
let
freeChannel
=
this
.
mediaModule
.
getFreeMediaChannel
();
if
(
freeChannel
==
0
)
{
loger
.
warn
(
'视频模块广播消息->不能再打开更多的设备'
,
_param
);
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"不能再打开更多的设备"
,
"mediaChannels"
:
this
.
mediaModule
.
mediaChannels
};
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"不能再打开更多的设备"
,
"mediaChannels"
:
this
.
mediaModule
.
mediaChannels
};
}
}
...
...
@@ -353,12 +396,12 @@ class VideoApe extends Ape {
videoSendPdu
.
toNodeId
=
parseInt
(
_param
.
toNodeId
)
||
0
;
//接收者,0就是所有人
videoSendPdu
.
actionType
=
parseInt
(
_param
.
actionType
)
||
ApeConsts
.
MEDIA_ACTION_DEFAULT
;
let
dataStr
=
''
;
try
{
dataStr
=
JSON
.
stringify
(
_param
.
data
);
}
catch
(
err
){
let
dataStr
=
''
;
try
{
dataStr
=
JSON
.
stringify
(
_param
.
data
);
}
catch
(
err
)
{
loger
.
warn
(
'控制消息->JSON转换失败'
);
dataStr
=
_param
.
data
;
dataStr
=
_param
.
data
;
}
videoSendPdu
.
data
=
this
.
_rCArrayBufferUtil
.
strToUint8Array
(
"h5"
+
dataStr
);
//开头两个字会乱码
...
...
@@ -371,12 +414,13 @@ class VideoApe extends Ape {
}
return
{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
""
};
}
//发送到mcu同步(更新数据)
sendTableUpdateHandler
(
_channelInfo
)
{
//loger.log("video===sendTableUpdateHandler ");
let
updateModelPdu
=
this
.
packPdu
(
_channelInfo
,
_channelInfo
.
channelId
);
//let updateModelPdu=this.packPdu({},ApeConsts.VIDEO_OBJ_TABLE_ID+2);
if
(
updateModelPdu
==
null
)
{
if
(
updateModelPdu
==
null
)
{
loger
.
warn
(
"sendTableUpdateHandler error,updateModelPdu=null"
);
return
;
}
...
...
@@ -420,115 +464,117 @@ class VideoApe extends Ape {
}
videoReceivePdu
.
data
=
this
.
_rCArrayBufferUtil
.
uint8ArrayToStr
(
videoReceivePdu
.
data
,
2
);
//开头两个字会乱码
let
dataObj
=
{};
try
{
dataObj
=
JSON
.
parse
(
videoReceivePdu
.
data
);
}
catch
(
err
){
let
dataObj
=
{};
try
{
dataObj
=
JSON
.
parse
(
videoReceivePdu
.
data
);
}
catch
(
err
)
{
loger
.
warn
(
'控制消息->JSON转换失败'
);
dataObj
=
videoReceivePdu
.
data
;
dataObj
=
videoReceivePdu
.
data
;
}
videoReceivePdu
.
data
=
dataObj
;
videoReceivePdu
.
data
=
dataObj
;
//判断接收者的id,如果不是0,并且也不是自己的nodeId,那么消息不做处理
if
(
videoReceivePdu
.
toNodeId
!=
0
&&
videoReceivePdu
.
toNodeId
!=
GlobalConfig
.
nodeId
)
{
loger
.
log
(
'视频消息不处理 toNodeId='
,
videoReceivePdu
.
toNodeId
,
"my nodeId="
,
GlobalConfig
.
nodeId
);
}
else
{
loger
.
log
(
'视频控制消息处理 .'
,
videoReceivePdu
);
loger
.
log
(
'视频控制消息处理 .'
,
videoReceivePdu
);
this
.
_emit
(
MessageTypes
.
VIDEO_BROADCAST
,
videoReceivePdu
);
}
}
tableUpdateHandler
(
owner
,
itemIdx
,
itemData
,
seek
)
{
tableUpdateHandler
(
owner
,
itemIdx
,
itemData
,
seek
)
{
let
unpackChannelInfo
=
this
.
unPackPdu
(
owner
,
itemIdx
,
itemData
);
loger
.
log
(
"tableUpdateHandler->channel"
,
itemIdx
,
'mediaType'
,
unpackChannelInfo
.
mediaType
,
'status->'
,
unpackChannelInfo
.
status
,
"seek->"
,
seek
);
loger
.
log
(
"tableUpdateHandler->channel"
,
itemIdx
,
'mediaType'
,
unpackChannelInfo
.
mediaType
,
'status->'
,
unpackChannelInfo
.
status
,
"seek->"
,
seek
);
//****很重要********
//如果owner的值为0,代表的是这个歌频道已经被释放了(mcu服务端对于占用channel的掉线用户,就是把owner设置为0)
if
(
owner
==
0
){
loger
.
log
(
"释放占用的频道,channel"
,
itemIdx
);
unpackChannelInfo
.
status
=
ApeConsts
.
CHANNEL_STATUS_RELEASED
;
unpackChannelInfo
.
streamId
=
""
;
if
(
owner
==
0
)
{
loger
.
log
(
"释放占用的频道,channel"
,
itemIdx
);
unpackChannelInfo
.
status
=
ApeConsts
.
CHANNEL_STATUS_RELEASED
;
unpackChannelInfo
.
streamId
=
""
;
}
//屏幕共享的流不保存
if
(
unpackChannelInfo
.
mediaType
!=
ApeConsts
.
MEDIA_TYPE_SHARE
&&
unpackChannelInfo
.
channelId
>
0
)
{
if
(
unpackChannelInfo
.
mediaType
!=
ApeConsts
.
MEDIA_TYPE_SHARE
&&
unpackChannelInfo
.
channelId
>
0
)
{
this
.
mediaModule
.
mediaChannels
[
itemIdx
]
=
unpackChannelInfo
;
}
if
(
unpackChannelInfo
&&
unpackChannelInfo
.
fromNodeId
!=
GlobalConfig
.
nodeId
){
let
receiveChannelInfo
=
{};
receiveChannelInfo
.
mediaId
=
unpackChannelInfo
.
channelId
;
receiveChannelInfo
.
fromNodeId
=
unpackChannelInfo
.
fromNodeId
;
receiveChannelInfo
.
userName
=
unpackChannelInfo
.
userName
||
""
;
receiveChannelInfo
.
userRole
=
unpackChannelInfo
.
userRole
||
ApeConsts
.
normal
;
receiveChannelInfo
.
mediaType
=
unpackChannelInfo
.
mediaType
||
ApeConsts
.
MEDIA_TYPE_DEFAULT
;
receiveChannelInfo
.
screenWidth
=
unpackChannelInfo
.
screenWidth
||
GlobalConfig
.
screenWidth
;
receiveChannelInfo
.
screenHeight
=
unpackChannelInfo
.
screenHeight
||
GlobalConfig
.
screenHeight
;
receiveChannelInfo
.
deviceType
=
unpackChannelInfo
.
deviceType
||
0
;
receiveChannelInfo
.
optionJsonData
=
unpackChannelInfo
.
optionJsonData
||
""
;
if
(
unpackChannelInfo
&&
unpackChannelInfo
.
fromNodeId
!=
GlobalConfig
.
nodeId
)
{
let
receiveChannelInfo
=
{};
receiveChannelInfo
.
mediaId
=
unpackChannelInfo
.
channelId
;
receiveChannelInfo
.
fromNodeId
=
unpackChannelInfo
.
fromNodeId
;
receiveChannelInfo
.
userName
=
unpackChannelInfo
.
userName
||
""
;
receiveChannelInfo
.
userRole
=
unpackChannelInfo
.
userRole
||
ApeConsts
.
normal
;
receiveChannelInfo
.
mediaType
=
unpackChannelInfo
.
mediaType
||
ApeConsts
.
MEDIA_TYPE_DEFAULT
;
receiveChannelInfo
.
screenWidth
=
unpackChannelInfo
.
screenWidth
||
GlobalConfig
.
screenWidth
;
receiveChannelInfo
.
screenHeight
=
unpackChannelInfo
.
screenHeight
||
GlobalConfig
.
screenHeight
;
receiveChannelInfo
.
deviceType
=
unpackChannelInfo
.
deviceType
||
0
;
receiveChannelInfo
.
optionJsonData
=
unpackChannelInfo
.
optionJsonData
||
""
;
//消息不是自己同步的,需要处理
if
(
unpackChannelInfo
.
status
==
ApeConsts
.
CHANNEL_STATUS_OPENING
)
{
if
(
unpackChannelInfo
.
status
==
ApeConsts
.
CHANNEL_STATUS_OPENING
)
{
//正在推流
receiveChannelInfo
.
m3u8Url
=
""
;
receiveChannelInfo
.
rtmpUrl
=
""
;
receiveChannelInfo
.
replay
=
""
;
receiveChannelInfo
.
m3u8Url
=
""
;
receiveChannelInfo
.
rtmpUrl
=
""
;
receiveChannelInfo
.
replay
=
""
;
receiveChannelInfo
.
seek
=
seek
||
0
;
//这个是录制回放时使用的seek
receiveChannelInfo
.
seek
=
seek
||
0
;
//这个是录制回放时使用的seek
let
m3u8Stream
=
this
.
mediaModule
.
getMediaPlayPath
({
"type"
:
"m3u8"
,
"streamId"
:
unpackChannelInfo
.
streamId
});
let
rtmpStream
=
this
.
mediaModule
.
getMediaPlayPath
({
"type"
:
"rtmp"
,
"streamId"
:
unpackChannelInfo
.
streamId
});
let
replay
=
this
.
mediaModule
.
getMediaRecordPlaybackPath
({
"type"
:
"m3u8"
,
"streamId"
:
unpackChannelInfo
.
streamId
});
let
m3u8Stream
=
this
.
mediaModule
.
getMediaPlayPath
({
"type"
:
"m3u8"
,
"streamId"
:
unpackChannelInfo
.
streamId
});
let
rtmpStream
=
this
.
mediaModule
.
getMediaPlayPath
({
"type"
:
"rtmp"
,
"streamId"
:
unpackChannelInfo
.
streamId
});
let
replay
=
this
.
mediaModule
.
getMediaRecordPlaybackPath
({
"type"
:
"m3u8"
,
"streamId"
:
unpackChannelInfo
.
streamId
});
if
(
m3u8Stream
.
code
==
0
){
receiveChannelInfo
.
m3u8Url
=
m3u8Stream
.
playUrl
;
if
(
m3u8Stream
.
code
==
0
)
{
receiveChannelInfo
.
m3u8Url
=
m3u8Stream
.
playUrl
;
}
if
(
rtmpStream
.
code
==
0
){
receiveChannelInfo
.
rtmpUrl
=
rtmpStream
.
playUrl
;
if
(
rtmpStream
.
code
==
0
)
{
receiveChannelInfo
.
rtmpUrl
=
rtmpStream
.
playUrl
;
}
if
(
replay
.
code
==
0
){
receiveChannelInfo
.
replay
=
replay
.
playUrl
;
if
(
replay
.
code
==
0
)
{
receiveChannelInfo
.
replay
=
replay
.
playUrl
;
}
if
(
unpackChannelInfo
.
mediaType
!=
ApeConsts
.
MEDIA_TYPE_SHARE
)
{
if
(
unpackChannelInfo
.
mediaType
!=
ApeConsts
.
MEDIA_TYPE_SHARE
)
{
//广播播放视频的消息
loger
.
log
(
"VIDEO_PLAY"
,
receiveChannelInfo
);
loger
.
log
(
"VIDEO_PLAY"
,
receiveChannelInfo
);
this
.
_emit
(
MessageTypes
.
VIDEO_PLAY
,
receiveChannelInfo
);
}
else
{
}
else
{
//播放屏幕共享
loger
.
log
(
"SCREEN_SHARE_PLAY"
,
receiveChannelInfo
);
loger
.
log
(
"SCREEN_SHARE_PLAY"
,
receiveChannelInfo
);
this
.
_emit
(
MessageTypes
.
SCREEN_SHARE_PLAY
,
receiveChannelInfo
);
}
}
else
{
if
(
unpackChannelInfo
.
mediaType
!=
ApeConsts
.
MEDIA_TYPE_SHARE
){
}
else
{
if
(
unpackChannelInfo
.
mediaType
!=
ApeConsts
.
MEDIA_TYPE_SHARE
)
{
//停止播放视频
loger
.
log
(
"VIDEO_STOP"
,
receiveChannelInfo
);
loger
.
log
(
"VIDEO_STOP"
,
receiveChannelInfo
);
this
.
_emit
(
MessageTypes
.
VIDEO_STOP
,
receiveChannelInfo
);
}
else
{
}
else
{
//停止播放屏幕共享
if
(
unpackChannelInfo
.
channelId
!=
0
)
{
if
(
unpackChannelInfo
.
channelId
!=
0
)
{
loger
.
log
(
"SCREEN_SHARE_STOP"
,
receiveChannelInfo
);
this
.
_emit
(
MessageTypes
.
SCREEN_SHARE_STOP
,
receiveChannelInfo
);
}
else
{
}
else
{
loger
.
log
(
"停止播放视频->channelId=0->不合法的id"
,
receiveChannelInfo
);
}
}
}
}
else
{
}
else
{
loger
.
warn
(
"视频消息是自己发送的或者是视频消息无效,不需要处理,消息内容如下:"
);
loger
.
log
(
unpackChannelInfo
);
if
(
unpackChannelInfo
.
status
==
ApeConsts
.
CHANNEL_STATUS_OPENING
){
GlobalConfig
.
openCamera
=
EngineUtils
.
creatTimestamp
();
GlobalConfig
.
openMicrophones
=
GlobalConfig
.
openCamera
;
}
else
{
GlobalConfig
.
openCamera
=
0
;
GlobalConfig
.
openMicrophones
=
0
;
if
(
unpackChannelInfo
.
status
==
ApeConsts
.
CHANNEL_STATUS_OPENING
)
{
GlobalConfig
.
openCamera
=
EngineUtils
.
creatTimestamp
();
GlobalConfig
.
openMicrophones
=
GlobalConfig
.
openCamera
;
}
else
{
GlobalConfig
.
openCamera
=
0
;
GlobalConfig
.
openMicrophones
=
0
;
}
//更新用户的摄像头和麦克风状态
if
(
unpackChannelInfo
.
mediaType
!=
ApeConsts
.
MEDIA_TYPE_SHARE
)
{
if
(
unpackChannelInfo
.
mediaType
!=
ApeConsts
.
MEDIA_TYPE_SHARE
)
{
//非屏幕共享的情况下才更新状态
this
.
_emit
(
MessageTypes
.
USER_DEVICE_STATUS_CHAANGE
,
{
nodeId
:
GlobalConfig
.
nodeId
,
...
...
@@ -542,24 +588,25 @@ class VideoApe extends Ape {
}
if
(
unpackChannelInfo
.
mediaType
!=
ApeConsts
.
MEDIA_TYPE_SHARE
)
{
if
(
unpackChannelInfo
.
mediaType
!=
ApeConsts
.
MEDIA_TYPE_SHARE
)
{
//非屏幕共享情况的处理
MediaModule
.
allMediaChannelsList
[
itemIdx
]
=
unpackChannelInfo
;
console
.
log
(
'MediaModule.allMediaChannelsList'
,
MediaModule
.
allMediaChannelsList
);
MediaModule
.
allMediaChannelsList
[
itemIdx
]
=
unpackChannelInfo
;
console
.
log
(
'MediaModule.allMediaChannelsList'
,
MediaModule
.
allMediaChannelsList
);
this
.
_emit
(
MessageTypes
.
VIDEO_UPDATE
,
unpackChannelInfo
);
}
}
//更新媒体文件模块的录制信息,每次开启录制的时候需要把当前媒体文件的信息更新一次
updaterRecordApeStatus
(
_param
){
console
.
warn
(
"录制状态发送改变->更新当前的状态->"
,
this
.
mediaModule
.
mediaChannels
);
for
(
let
i
in
this
.
mediaModule
.
mediaChannels
){
let
channelInfo
=
this
.
mediaModule
.
mediaChannels
[
i
];
if
(
channelInfo
){
if
(
channelInfo
.
status
==
ApeConsts
.
CHANNEL_STATUS_RELEASED
){
channelInfo
.
owner
=
0
;
}
else
{
channelInfo
.
owner
=
channelInfo
.
fromNodeId
;
updaterRecordApeStatus
(
_param
)
{
console
.
warn
(
"录制状态发送改变->更新当前的状态->"
,
this
.
mediaModule
.
mediaChannels
);
for
(
let
i
in
this
.
mediaModule
.
mediaChannels
)
{
let
channelInfo
=
this
.
mediaModule
.
mediaChannels
[
i
];
if
(
channelInfo
)
{
if
(
channelInfo
.
status
==
ApeConsts
.
CHANNEL_STATUS_RELEASED
)
{
channelInfo
.
owner
=
0
;
}
else
{
channelInfo
.
owner
=
channelInfo
.
fromNodeId
;
}
this
.
sendTableUpdateHandler
(
channelInfo
);
}
...
...
@@ -567,9 +614,9 @@ class VideoApe extends Ape {
}
//清除当前模块的数据
clearData
()
{
clearData
()
{
loger
.
log
(
"clearData->"
);
MediaModule
.
allMediaChannelsList
=
{};
MediaModule
.
allMediaChannelsList
=
{};
}
///////数据的封包和解包/////////////////////////////////////////
...
...
@@ -582,28 +629,28 @@ class VideoApe extends Ape {
//判断type类型,根据type设置不同的参数
let
packPduModel
=
new
pdu
[
'RCVideoChannelInfoPdu'
];
packPduModel
.
status
=
_param
.
status
||
ApeConsts
.
CHANNEL_STATUS_RELEASED
;
packPduModel
.
status
=
_param
.
status
||
ApeConsts
.
CHANNEL_STATUS_RELEASED
;
packPduModel
.
channelId
=
_itemIdx
;
packPduModel
.
streamId
=
_param
.
streamId
||
""
;
packPduModel
.
siteId
=
_param
.
siteId
||
GlobalConfig
.
siteId
;
//GlobalConfig.siteId;
packPduModel
.
classId
=
parseInt
(
_param
.
classId
)
||
parseInt
(
GlobalConfig
.
classId
);
packPduModel
.
userId
=
_param
.
userId
||
"0"
;
packPduModel
.
mediaType
=
_param
.
mediaType
||
ApeConsts
.
MEDIA_TYPE_VIDEO
;
packPduModel
.
timestamp
=
_param
.
timestamp
||
0
;
packPduModel
.
fromNodeId
=
_param
.
nodeId
||
GlobalConfig
.
nodeId
;
packPduModel
.
userName
=
_param
.
userName
||
GlobalConfig
.
userName
;
packPduModel
.
streamId
=
_param
.
streamId
||
""
;
packPduModel
.
siteId
=
_param
.
siteId
||
GlobalConfig
.
siteId
;
//GlobalConfig.siteId;
packPduModel
.
classId
=
parseInt
(
_param
.
classId
)
||
parseInt
(
GlobalConfig
.
classId
);
packPduModel
.
userId
=
_param
.
userId
||
"0"
;
packPduModel
.
mediaType
=
_param
.
mediaType
||
ApeConsts
.
MEDIA_TYPE_VIDEO
;
packPduModel
.
timestamp
=
_param
.
timestamp
||
0
;
packPduModel
.
fromNodeId
=
_param
.
nodeId
||
GlobalConfig
.
nodeId
;
packPduModel
.
userName
=
_param
.
userName
||
GlobalConfig
.
userName
;
packPduModel
.
toNodeId
=
0
;
packPduModel
.
userRole
=
_param
.
userRole
||
GlobalConfig
.
userRole
;
packPduModel
.
screenWidth
=
_param
.
screenWidth
||
GlobalConfig
.
screenWidth
;
packPduModel
.
screenHeight
=
_param
.
screenHeight
||
GlobalConfig
.
screenHeight
;
packPduModel
.
deviceType
=
_param
.
deviceType
||
GlobalConfig
.
deviceType
;
packPduModel
.
optionJsonData
=
_param
.
optionJsonData
||
GlobalConfig
.
optionJsonData
;
loger
.
log
(
'packPdu->'
,
packPduModel
);
packPduModel
.
userRole
=
_param
.
userRole
||
GlobalConfig
.
userRole
;
packPduModel
.
screenWidth
=
_param
.
screenWidth
||
GlobalConfig
.
screenWidth
;
packPduModel
.
screenHeight
=
_param
.
screenHeight
||
GlobalConfig
.
screenHeight
;
packPduModel
.
deviceType
=
_param
.
deviceType
||
GlobalConfig
.
deviceType
;
packPduModel
.
optionJsonData
=
GlobalConfig
.
optionJsonData
;
loger
.
log
(
'packPdu->'
,
packPduModel
);
return
packPduModel
;
}
unPackPdu
(
owner
,
itemIdx
,
itemData
)
{
loger
.
log
(
"unPackPdu->owner:"
,
owner
,
"itemIdx->"
,
itemIdx
);
loger
.
log
(
"unPackPdu->owner:"
,
owner
,
"itemIdx->"
,
itemIdx
);
if
(
owner
==
null
||
itemIdx
==
null
||
itemData
==
null
)
{
this
.
_emit
(
MessageTypes
.
MCU_ERROR
,
MessageTypes
.
ERR_APE_INTERFACE_PARAM_WRONG
);
return
null
;
...
...
请
注册
或
登录
后发表评论