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
李勇
9 years ago
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
c47b2bcade432dedead944e4f9ce3d4f03c69ff6
c47b2bca
1 parent
9845310e
master
...
20170922-1
20171019-1
20171120-1w
dev
letv-20170426
ly20170622
ly20170622-2
ly20170622-3
ly20170627-2
ly20170706-1
ly20170708-2
ly20170708-3
ly20170710-1
ly20170717-1
ly20170719-1
ly20170723-1
ly20170724-2
ly20170726-1
ly20170731-1
ly20170731-2
ly20170801-2
ly20170802-1
ly20170818-1
ly20170818-2
ly20170820-1
ly20170821-1
ly20170824-1
ly20170829-1
ly20170925-1
ly20170926-1
ly20170927-1
ly20170929-1
ly20171011-1
ly20171013-1
ly20171013-2
ly20171016-1
ly20171021-1
ly20171023-1
ly20171024-1w
ly20171025-1w
ly20171026-1w
ly20171027-1w
ly20171030-1
ly20171030-2w
ly20171107-1
ly20171110-1w
ly20171113-1w
ly20171204-1w
ly20171208-1w
ly20171211-1w
ly20171211-2w
ly20171214-1w
mcuClientBranch
mcuClientBranch20170228
webRtc-dev
1.7.0
v2.38.13.20171216
v2.38.11.20171214
v2.38.3.201712011
v2.38.1.201712011
v2.36.11.20171204
v2.36.8.20171206
v2.36.4.20171201
v2.35.11.20171130
v2.34.16.20171128
v2.34.5.20171127
v2.33.6.20171123
v2.32.1.20171123
v2.31.12.20171122
v2.31.10.20171122
v2.30.5.20171117
v2.30.2.20171117
v2.29.5.20171114
v2.28.1.20171110
v2.27.11.20171109
v2.26.9.20171107
v2.26.6.20171103
v2.26.2.20171102
v2.25.7.20171031
v2.25.6.20171031
v2.25.0.20171030
v2.24.2.20171030
v2.23.0.20171030
v2.22.7.20171026
v2.20.5.20171023
v2.20.0.20171021
v2.19.8.20171020
v2.18.14.20171020
v2.18.10.20171019
v2.17.11.20171014
v2.16.8.20171012
v2.16.5.20171012
v2.15.5.20171001
v2.15.3.20170929
v2.14.5.20170927
v2.13.5.20170927
v2.12.14.20170927
v2.12.8.20170926
v2.12.6.20170925
v2.11.13.20170925
v2.10.7.20170921
v2.10.6.20170921
v2.10.5.20170920
v2.10.4.20170920
v2.9.3.20170919
v2.8.17.20170918
v2.8.8.20170917
v2.8.2.20170916
v2.6.2.20170915
v2.5.12.20170915
v2.5.6.20170914
v2.5.5.20170914
v2.4.4.20170908
v2.4.2.20170908
v2.4.0.20170907
v2.3.6.20170907
v2.2.16.20170905
v2.1.22.20170904
v1.84.0.20170912
v1.83.2.20170831
v1.82.11.20170829
v1.81.19.20170828
v1.80.2.20170824
v1.79.6.20170822
v1.79.5.20170821
v1.79.4.20170821
v1.79.3.20170821
v1.78.4.20170820
v1.77.4.20170819
v1.76.2.20170818
v1.75.0.20170815
v1.74.0.20170814
v1.73.2.20170814
v1.73.1.20170814
v1.71.0.20170813
v1.70.5.20170812
v1.68.2.20170812
v1.66.1.20170809
v1.65.25.20170808
v1.65.24.20170806
v1.63.1.20170731
v1.62.3.20170731
v1.61.0.20170729
v1.60.0.20170729
v1.59.0.20170729
v1.58.0.20170729
v1.57.0.20170727
v1.56.1.20170727
v1.56.0.20170727
v1.52.1.20170726
v1.51.0.20170724
v1.50.7.20170724
v1.49.1.20170724
v1.48.2.20170723
v1.46.1.20170722
v1.45.1.20170717
v1.43.1.20170711
v1.42.1.20170708
v1.41.0.20170708
v1.40.0.20170706
v1.39.2.20170706
v1.39.1.20170705
v1.38.4.20170629
v1.37.5.20170627
v1.37.2.20170622
v1.36.7.20170620
v1.36.4.20170620
v1.36.1.20170619
v1.35.4.20170619
v1.34.2.20170615
v1.33.2.20170615
v1.32.1.20170614
v1.31.11.20170613
v1.30.20.20170607
v1.30.7.20170606
v1.30.6.20170606
v1.30.5.20170605
v1.30.3.20170602
v1.29.8.20170601
v1.28.0.201705031
v1.27.16.201705027
v1.27.14.201705027
v1.27.10.201705026
v1.25.2.201705025
v1.23.5.201705023
v1.23.4.201705018
v1.21.1.201705017
v1.20.1.201705015
v1.19.1.201705012
v1.19.0.201705011
v1.18.0.201705010
v1.16.1.201705010
v1.15.2.20170507
v1.14.1.20170505
v1.13.0.20170504
v1.11.3.20170504
v1.10.2.20170428
v1.10.0.20170427
v1.9.20.20170426
v1.9.19.20170425
v1.9.18.20170425
v1.9.17.20170421
v1.9.16.20170420
v1.9.15.20170420
v1.9.11.20170419
v1.9.6.20170418
v1.9.4.20170417
v.1.9.2.20170413
v.1.9.0.20170411
v.1.8.22.20170411
v.1.8.19.20170411
v.1.8.16.20170410
v.1.8.13.20170409
v.1.8.10.20170407
v.1.8.9.20170407
v1.8.8.20170406
v.1.8.7.20170405-1
v.1.8.6.20170401-2
v.1.8.5.20170331-1
v.1.8.3.20170329-4
v1.8.1.20170321
mcuClient20170302
mcuClient_v1.8.0.20170314
修复音视频channel占用问题
1.调整视频模块,把视频和音频模块共用的功能单独分离出来
隐藏空白字符变更
内嵌
并排对比
正在显示
4 个修改的文件
包含
32 行增加
和
144 行删除
src/EngineEntrance.js
src/McuClientEngine.js
src/apes/ConferApe.js
src/apes/VideoApe.js
src/EngineEntrance.js
查看文件 @
c47b2bc
...
...
@@ -91,7 +91,7 @@ export default class MessageEntrance extends Emiter {
_audio_ape
=
new
AudioApe
();
_audio_ape
.
on
(
'*'
,
(
type
,
data
)
=>
this
.
_emit
(
type
,
data
));
_audio_ape
.
on
(
MessageTypes
.
AUDIO_UPDATE
,
this
.
vide
oUpdate
.
bind
(
this
));
_audio_ape
.
on
(
MessageTypes
.
AUDIO_UPDATE
,
this
.
audi
oUpdate
.
bind
(
this
));
_whiteboard_ape
=
new
WhiteBoardApe
();
_whiteboard_ape
.
on
(
'*'
,
(
type
,
data
)
=>
this
.
_emit
(
type
,
data
));
...
...
@@ -198,7 +198,7 @@ export default class MessageEntrance extends Emiter {
_video_ape
.
stopPublishVideo
(
_data
);
}
if
(
_audio_ape
){
_
vide
o_ape
.
stopPublishAudio
(
_data
);
_
audi
o_ape
.
stopPublishAudio
(
_data
);
}
}
}
...
...
@@ -206,15 +206,15 @@ export default class MessageEntrance extends Emiter {
//当前会议中视频或音频占用channel的nodeId ,在人员列表中不存在,这种情况是占用channel的人员掉线或离开的时候没有释放channel
//的占用状态导致,对于这种情况,需要释放掉
_onClassNonentityRoster
(
_param
){
if
(
_param
==
null
||
_param
.
fromN
odeId
==
null
){
if
(
_param
==
null
||
_param
.
n
odeId
==
null
){
loger
.
warn
(
"onClassNonentityRoster.参数错误"
)
return
;
}
if
(
_video_ape
){
_video_ape
.
stopPublishVideo
({
"nodeId"
:
_param
.
fromN
odeId
});
_video_ape
.
stopPublishVideo
({
"nodeId"
:
_param
.
n
odeId
});
}
if
(
_audio_ape
){
_audio_ape
.
stopPublishAudio
({
"nodeId"
:
_param
.
fromN
odeId
});
_audio_ape
.
stopPublishAudio
({
"nodeId"
:
_param
.
n
odeId
});
}
}
...
...
@@ -738,7 +738,7 @@ export default class MessageEntrance extends Emiter {
//AudioApe
audioUpdate
(
_data
){
//
视
频同步的消息发送改变,需要通知ferApe模块中的用户更新状态
//
音
频同步的消息发送改变,需要通知ferApe模块中的用户更新状态
if
(
_confer_ape
){
_confer_ape
.
updaterRosterStatus
(
_data
);
}
...
...
src/McuClientEngine.js
查看文件 @
c47b2bc
//对外暴露的对象
import
EngineEntrance
from
'EngineEntrance'
;
import
MessageTypes
from
'MessageTypes'
;
const
MCU_CLIENT
=
new
EngineEntrance
();
const
MCU_CLIENT
=
new
EngineEntrance
();
//入口文件
export
function
createMcuClient
()
{
return
MCU_CLIENT
;
}
//监听是事件名和异常定义
export
{
MessageTypes
};
...
...
src/apes/ConferApe.js
查看文件 @
c47b2bc
...
...
@@ -454,7 +454,7 @@ class ConferApe extends Ape {
//视频模块发生更新,人员状态需要更新
updaterRosterStatus
(
_param
){
if
(
_param
){
loger
.
log
(
"
视频
模块发生更新,人员状态需要更新,fromNodeId->"
,
_param
.
fromNodeId
);
loger
.
log
(
"
媒体
模块发生更新,人员状态需要更新,fromNodeId->"
,
_param
.
fromNodeId
);
loger
.
log
(
_param
.
status
,
_param
.
fromNodeId
,
this
.
rosters
[
_param
.
fromNodeId
]);
//console.log(_param.fromNodeId);
//如果是自己。改变自己的状态同步到MCU
...
...
@@ -465,8 +465,8 @@ class ConferApe extends Ape {
//如果视频消息中channel的占用人 fromNodeId在人员列表中不存在,需要释放这channel,因为这个有可能是之前没释放成功的
if
(
_param
.
status
==
ApeConsts
.
CHANNEL_STATUS_OPENING
&&
this
.
rosters
[
_param
.
fromNodeId
]
==
null
){
loger
.
log
(
"视频模块被占用,占有人已经不存在课堂中,释放Channel,_param->"
,
_param
);
this
.
_emit
(
MessageTypes
.
CLASS_NONENTITY_ROSTER
,
_param
.
fromNodeId
);
loger
.
log
(
"媒体模块被占用,占有人已经不存在课堂中,释放Channel,_param->"
,
_param
);
this
.
_emit
(
MessageTypes
.
CLASS_NONENTITY_ROSTER
,{
"nodeId"
:
_param
.
fromNodeId
});
}
}
}
...
...
src/apes/VideoApe.js
查看文件 @
c47b2bc
// //////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2016-present All Rights Reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// http://www.apache.org/licenses/LICENSE-2.0
//
// Github Home: https://github.com/AlexWang1987
// Author: AlexWang
// Date: 2016-08-23 18:07:28
// QQ Email: 1669499355@qq.com
// Last Modified time: 2016-09-06 11:13:59
// Description: LiveClass-VideoApe
//
//视频模块
// //////////////////////////////////////////////////////////////////////////////
import
Ape
from
'./Ape'
;
...
...
@@ -20,6 +9,7 @@ import Loger from 'Loger';
import
MessageTypes
from
'MessageTypes'
;
import
GlobalConfig
from
'GlobalConfig'
;
import
EngineUtils
from
'EngineUtils'
;
import
MediaModule
from
"./MediaModule"
;
let
loger
=
Loger
.
getLoger
(
'VideoApe'
);
...
...
@@ -31,8 +21,9 @@ class VideoApe extends Ape {
ApeConsts
.
VIDEO_SESSION_TAG
);
//Attributes
this
.
videoChannels
=
{};
this
.
mediaModule
=
new
MediaModule
();
this
.
mediaModule
.
MEDIA_OBJ_TABLE_ID
=
ApeConsts
.
VIDEO_OBJ_TABLE_ID
;
this
.
mediaModule
.
mediaChannels
=
{};
// Ape Models
this
.
registerKey
(
this
.
_session_id
,
this
.
_session_name
,
this
.
_session_tag
,
new
ArrayBuffer
);
...
...
@@ -41,84 +32,23 @@ class VideoApe extends Ape {
// videoApe 监听视频控制消息,用户之间的消息传递
this
.
on
(
pdu
.
RCPDU_VIDEO_SEND_DATA_REQUEST
,
this
.
receiveVideoCommandHandler
.
bind
(
this
));
}
//ape加入成功
onJoinChannelHandlerSuccess
(){
//这个设置很重要,因为只有Sass流程完成之后,APE才能取得GlobalConfig中的数据
this
.
mediaModule
.
maxMediaChannel
=
GlobalConfig
.
maxVideoChannels
;
}
/////////////发送数据操作////////////////////////////////////////////
//获取播流地址
getPlayVideoPath
(
_param
)
{
loger
.
log
(
'getPlayVideoPath'
);
if
(
_param
==
null
||
_param
.
siteId
==
null
||
_param
.
classId
==
null
||
_param
.
userId
==
null
||
_param
.
channelId
==
null
||
_param
.
timestamp
==
null
)
{
loger
.
warn
(
'getPlayVideoPath,参数错误'
,
_param
);
this
.
_emit
(
MessageTypes
.
MCU_ERROR
,
MessageTypes
.
ERR_APE_INTERFACE_PARAM_WRONG
);
return
{
"code"
:
1
,
"data"
:
""
};
}
let
path
=
""
;
let
port
=
""
;
if
(
_param
.
type
==
"m3u8"
)
{
//M3U8
//http://123.56.73.119:6001/hls/h5dev_403074980_0_983041_1487663265/index.m3u8
port
=
(
GlobalConfig
.
RSServerPort
==
""
||
GlobalConfig
.
RSServerPort
==
null
)
?
""
:
":"
+
GlobalConfig
.
RSServerPort
;
path
=
"http://"
+
GlobalConfig
.
RSServerIP
+
port
+
"/live/"
+
_param
.
siteId
+
"_"
+
_param
.
classId
+
"_"
+
_param
.
userId
+
"_"
+
_param
.
channelId
+
"_"
+
_param
.
timestamp
+
"/index.m3u8"
;
}
else
{
port
=
(
GlobalConfig
.
MSServerPort
==
""
||
GlobalConfig
.
MSServerPort
==
null
)
?
""
:
":"
+
GlobalConfig
.
MSServerPort
;
path
=
"rtmp://"
+
GlobalConfig
.
MSServerIP
+
port
+
"/live/"
+
_param
.
siteId
+
"_"
+
_param
.
classId
+
"_"
+
_param
.
userId
+
"_"
+
_param
.
channelId
+
"_"
+
_param
.
timestamp
;
}
return
{
"code"
:
0
,
"data"
:
path
};
return
this
.
mediaModule
.
getMediaPlayPath
(
_param
);
}
//获取推流地址
getPublishVideoPath
(
_param
)
{
loger
.
log
(
'getPublishVideoPath'
);
//判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启
let
freeChannel
=
this
.
getFreeVideoChannel
();
if
(
freeChannel
==
0
)
{
return
{
"code"
:
1
,
"data"
:
"不能再打开更多的设备"
};
}
//默认方式推流
let
pubType
=
"live"
;
//flash推流
if
(
_param
&&
_param
.
type
==
"flash"
){
pubType
=
"flash"
;
}
//端口,有端口就显示 ":xxx",没有端口就是""
let
port
=
(
GlobalConfig
.
MSServerPort
==
""
||
GlobalConfig
.
MSServerPort
==
null
)
?
""
:
":"
+
GlobalConfig
.
MSServerPort
;
//时间戳
let
timestamp
=
EngineUtils
.
creatTimestamp
();
//生成推流地址和推流数据(同步数据的时候用)
let
publishUrl
=
"rtmp://"
+
GlobalConfig
.
MSServerIP
+
port
+
"/"
+
pubType
+
"/"
+
GlobalConfig
.
siteId
+
"_"
+
GlobalConfig
.
classId
+
"_"
+
GlobalConfig
.
userId
+
"_"
+
freeChannel
+
"_"
+
timestamp
;
return
{
"code"
:
0
,
"data"
:
{
"siteId"
:
GlobalConfig
.
siteId
,
"classId"
:
GlobalConfig
.
classId
,
"userId"
:
GlobalConfig
.
userId
,
"channelId"
:
freeChannel
,
"timestamp"
:
timestamp
,
"publishUrl"
:
publishUrl
}
};
return
this
.
mediaModule
.
getMediaPublishPath
(
_param
);
}
//推流
...
...
@@ -135,20 +65,20 @@ class VideoApe extends Ape {
loger
.
log
(
'publishVideo -> maxVideoChannels'
,
GlobalConfig
.
maxVideoChannels
);
//同一个nodeId只允许推一个流,如果已经推了就不能再推
if
(
this
.
getOpeningVideo
Channel
(
GlobalConfig
.
nodeId
)
!=
0
){
if
(
this
.
mediaModule
.
getOpeningMedia
Channel
(
GlobalConfig
.
nodeId
)
!=
0
){
loger
.
warn
(
"publishVideo,已经存在一个流,不能再推"
);
return
;
}
//判断当前是否还有空闲的channle
let
freeChannel
=
this
.
getFreeVideo
Channel
();
let
freeChannel
=
this
.
mediaModule
.
getFreeMedia
Channel
();
if
(
freeChannel
==
0
)
{
loger
.
warn
(
"publishVideo,没有空闲的channel "
);
return
{
"code"
:
1
,
"data"
:
"不能再打开更多的设备"
};
}
//判断当前的频道是否已经占用
if
(
this
.
checkChannelIsOpening
(
_param
.
channelId
)){
if
(
this
.
mediaModule
.
checkChannelIsOpening
(
_param
.
channelId
)){
loger
.
warn
(
_param
.
channelId
,
"频道已经被占用"
);
return
{
"code"
:
1
,
"data"
:
"频道已经被占用!"
};
}
...
...
@@ -177,7 +107,7 @@ class VideoApe extends Ape {
nodeId
=
GlobalConfig
.
nodeId
;
}
let
openingChannel
=
this
.
getOpeningVideo
Channel
(
nodeId
);
let
openingChannel
=
this
.
mediaModule
.
getOpeningMedia
Channel
(
nodeId
);
if
(
openingChannel
==
0
)
{
loger
.
warn
(
nodeId
,
"stopPublishVideo,没有打开的channel,不需要关闭"
);
return
{
"code"
:
1
,
"data"
:
"没有打开的channel,不需要关闭"
};
...
...
@@ -214,7 +144,7 @@ class VideoApe extends Ape {
if
(
_param
.
actionType
!=
null
&&
_param
.
actionType
==
ApeConsts
.
MEDIA_ACTION_OPEN_CAMERA
)
{
//判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启
let
freeChannel
=
this
.
getFreeVideo
Channel
();
let
freeChannel
=
this
.
mediaModule
.
getFreeMedia
Channel
();
if
(
freeChannel
==
0
)
{
loger
.
warn
(
'sendVideoCommandMsg,不能再打开更多的设备'
,
_param
);
return
{
"code"
:
1
,
"data"
:
"不能再打开更多的设备"
};
...
...
@@ -325,7 +255,7 @@ class VideoApe extends Ape {
//videoChannelInfo.channelId = itemIdx;
//videoChannelInfo.status = owner === 0 ? ApeConsts.CHANNEL_STATUS_RELEASED : videoChannelInfo.status;
//loger.log('视频消息处理 tableUpdateHandler.',videoChannelInfo);
this
.
video
Channels
[
itemIdx
]
=
videoChannelInfo
;
this
.
mediaModule
.
media
Channels
[
itemIdx
]
=
videoChannelInfo
;
this
.
_emit
(
MessageTypes
.
VIDEO_UPDATE
,
videoChannelInfo
);
/* switch (videoChannelInfo.status) {
...
...
@@ -403,52 +333,6 @@ class VideoApe extends Ape {
}
return
null
;
}
//获取当前空闲的channel,返回值为0代表没有空闲的,否则返回的就是空闲的channelId
getFreeVideoChannel
()
{
loger
.
log
(
"getFreeVideoChannel"
);
console
.
log
(
this
.
videoChannels
);
let
counter
=
0
;
for
(
let
key
in
this
.
videoChannels
)
{
let
item
=
this
.
videoChannels
[
key
];
if
(
item
&&
item
.
status
==
ApeConsts
.
CHANNEL_STATUS_RELEASED
)
{
return
item
.
channelId
;
}
counter
++
;
}
if
(
counter
<
GlobalConfig
.
maxVideoChannels
)
{
return
ApeConsts
.
VIDEO_OBJ_TABLE_ID
+
(
counter
);
}
return
0
;
//没有空闲的
}
//获取当前属于nodeId的已经打开的的channel,返回值为0代表没有打开的,否则返回的就是打开的channelId
getOpeningVideoChannel
(
_nodeId
){
if
(
_nodeId
==
null
||
_nodeId
==
0
){
return
0
;
}
for
(
let
key
in
this
.
videoChannels
)
{
let
item
=
this
.
videoChannels
[
key
];
if
(
item
&&
item
.
status
==
ApeConsts
.
CHANNEL_STATUS_OPENING
&&
item
.
fromNodeId
==
_nodeId
)
{
return
item
.
channelId
;
}
}
return
0
;
}
//检查频道是否已经被占用
checkChannelIsOpening
(
_channelId
){
if
(
_channelId
==
null
){
loger
.
warn
(
"checkChannelIsOpening error,channel="
,
_channelId
);
return
true
;
}
let
channelInfo
=
this
.
videoChannels
[
_channelId
];
if
(
channelInfo
==
null
||
channelInfo
.
status
==
ApeConsts
.
CHANNEL_STATUS_RELEASED
){
return
false
;
}
return
true
;
}
}
export
default
VideoApe
;
...
...
请
注册
或
登录
后发表评论