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
李勇
8 years ago
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
8b4c84b37cd4278d871824674504a3d5ad7ecc65
8b4c84b3
1 parent
982f2290
1.录制回放处理消息和视频地址匹配的问题;2.视频模块推流消息处理播放地址的问题;3.所有课堂开启旁路推流
隐藏空白字符变更
内嵌
并排对比
正在显示
6 个修改的文件
包含
88 行增加
和
24 行删除
src/EngineEntrance.js
src/EngineUtils.js
src/RecordPlayBackParse.js
src/Sass.js
src/apes/MediaModule.js
src/apes/VideoApe.js
src/EngineEntrance.js
查看文件 @
8b4c84b
...
...
@@ -61,8 +61,9 @@ let _base64;
export
default
class
MessageEntrance
extends
Emiter
{
constructor
()
{
super
();
this
.
lastClassActiveTime
=
0
;
//最后一次课堂激活的时间戳
//sdk 信息
GlobalConfig
.
sdkVersion
=
"v2.2
2.9.20171027
"
;
GlobalConfig
.
sdkVersion
=
"v2.2
3.0.20171030
"
;
loger
.
warn
(
"sdkVersion:"
+
GlobalConfig
.
sdkVersion
);
console
.
log
(
"sdkVersion:"
+
GlobalConfig
.
sdkVersion
);
//设置
...
...
@@ -1240,8 +1241,8 @@ export default class MessageEntrance extends Emiter {
//主讲人和老师可以设置旁录
if
(
GlobalConfig
.
appId
&&
!
GlobalConfig
.
openFlash
)
{
//加入之前先设置旁录地址,只有直播支持旁路(1路流)
if
(
_webRtc
&&
GlobalConfig
.
isTeachOrAssistant
&&
GlobalConfig
.
maxMediaChannels
==
1
)
{
//加入之前先设置旁录地址,老师和主讲人开启旁路
if
(
_webRtc
&&
GlobalConfig
.
isTeachOrAssistant
)
{
let
curTimestamp
=
new
Date
().
getTime
();
let
streamId
=
GlobalConfig
.
siteId
+
"_"
+
GlobalConfig
.
classId
+
"_"
+
GlobalConfig
.
userId
+
"_"
+
curTimestamp
;
//传入固定的流Id
...
...
@@ -1870,6 +1871,7 @@ export default class MessageEntrance extends Emiter {
let
dataObj
=
JSON
.
parse
(
_data
.
currentInfo
);
dataObj
.
recordStatus
=
false
;
GlobalConfig
.
setClassStatusInfo
(
dataObj
);
this
.
lastClassActiveTime
=
dataObj
.
lastClassActiveTime
||
0
;
}
catch
(
err
)
{
loger
.
warn
(
"从Sass获取的课堂数据JSON转换失败->"
);
GlobalConfig
.
setClassStatusInfo
(
_data
.
currentInfo
);
...
...
@@ -1919,6 +1921,7 @@ export default class MessageEntrance extends Emiter {
let
dataObj
=
JSON
.
parse
(
_currentInfo
);
dataObj
.
recordStatus
=
false
;
GlobalConfig
.
setClassStatusInfo
(
dataObj
);
this
.
lastClassActiveTime
=
dataObj
.
lastClassActiveTime
||
0
;
}
catch
(
err
)
{
loger
.
warn
(
"getClassRecordInfo获取的课堂数据JSON转换失败->"
);
}
...
...
@@ -2505,8 +2508,15 @@ export default class MessageEntrance extends Emiter {
//文档加入频道成功,同步到MCU服务器上的数据
docJoinChannelSuccess
()
{
loger
.
log
(
"最后一次记录的时间->"
+
GlobalConfig
.
classStopTime
,
"当前时间:"
+
EngineUtils
.
creatTimestamp
());
let
distance
=
new
Date
().
getTime
()
-
parseInt
(
this
.
lastClassActiveTime
);
loger
.
log
(
"最后一次记录的时间->"
+
this
.
lastClassActiveTime
,
"当前时间:"
+
new
Date
().
getTime
(),
"间隔:"
+
distance
/
1000
);
loger
.
log
(
"文档加入频道成功->isHost="
,
GlobalConfig
.
isHost
,
"当前总人数:"
,
GlobalConfig
.
rosterNumber
,
"sassDoclength="
,
GlobalConfig
.
docListPrepare
.
length
);
//如果当前课堂内只有自己或者离开上次课堂的时间大于15分钟,需要停止服务端的视频录制
if
(
GlobalConfig
.
rosterNumber
<=
1
||
distance
>=
(
15
*
60
)){
this
.
_mediaRecordControl
({
"status"
:
WebRtcApe
.
RECORD_STATUS_2
});
}
//如果是主持人,那么需要判断一下文档模块同步的数据和从sass获取的文档数据是否相同,如果mcu服务器不存在的,需要上传
if
(
GlobalConfig
.
docListPrepare
&&
GlobalConfig
.
docListPrepare
.
length
>
0
)
{
//如果当前身份是老师或者当前课堂内只有一个人,有权限同步文档到MCU
...
...
@@ -3282,7 +3292,8 @@ export default class MessageEntrance extends Emiter {
break
;
case
WebRtcApe
.
RECORD_STATUS_2
:
//停止录制
_webRtc
.
stopRecordingMedia
();
//_webRtc.stopRecordingMedia();
_webRtc
.
changePublishStatusAndServerRecord
(
WebRtcApe
.
RECORD_STATUS_2
);
break
;
default
:
break
;
...
...
src/EngineUtils.js
查看文件 @
8b4c84b
...
...
@@ -51,7 +51,15 @@ class EngineUtils{
timeStr
+=
curTime
.
getSeconds
();
return
timeStr
;
}
//根据时间戳字符串转换为时间戳 2017-10-27-15-38-15
static
getTimestampFromStr
(
_timeStr
){
if
(
!
_timeStr
)
return
this
.
creatTimestamp
();
let
timeArr
=
_timeStr
.
split
(
"_"
);
if
(
timeArr
&&
timeArr
.
length
==
6
){
return
parseInt
(
new
Date
(
timeArr
[
0
],
parseInt
(
timeArr
[
1
])
-
1
,
timeArr
[
2
],
timeArr
[
3
],
timeArr
[
4
],
timeArr
[
5
]).
getTime
()
/
1000
);
}
return
this
.
creatTimestamp
();
}
//生成时间戳 格式:"20170209"
static
creatTimestampYMD
(){
let
curTime
=
new
Date
();
...
...
src/RecordPlayBackParse.js
查看文件 @
8b4c84b
...
...
@@ -330,13 +330,13 @@ class RecordPlayBackParse extends Emiter {
}
//时间戳转换为UTC 时间字符串
timestampToUTCTime
(
_timestamp
){
var
date
=
new
Date
(
_timestamp
);
var
y
=
""
+
date
.
getFullYear
();
var
month
=
""
+
(
date
.
getMonth
()
+
1
);
var
d
=
""
+
date
.
getDate
();
var
h
=
""
+
(
date
.
getHours
()
-
8
);
//GMT 转UTC 减8
var
minutes
=
""
+
date
.
getMinutes
();
var
s
=
""
+
date
.
getSeconds
();
let
date
=
new
Date
(
_timestamp
);
let
y
=
""
+
date
.
getFullYear
();
let
month
=
""
+
(
date
.
getMonth
()
+
1
);
let
d
=
""
+
date
.
getDate
();
let
h
=
""
+
(
date
.
getHours
()
-
8
);
//GMT 转UTC 减8
let
minutes
=
""
+
date
.
getMinutes
();
let
s
=
""
+
date
.
getSeconds
();
if
(
month
.
length
<
2
){
month
=
"0"
+
month
;
}
...
...
@@ -352,7 +352,7 @@ class RecordPlayBackParse extends Emiter {
if
(
s
.
length
<
2
){
s
=
"0"
+
s
;
}
var
tiemStr
=
y
+
month
+
d
+
h
+
minutes
+
s
;
let
tiemStr
=
y
+
month
+
d
+
h
+
minutes
+
s
;
//console.log(_timestamp,tiemStr,date);
return
tiemStr
}
...
...
@@ -362,7 +362,13 @@ class RecordPlayBackParse extends Emiter {
console
.
log
(
"没有数据无法解析匹配"
,
_tiemstampMessages
,
_allMedias
)
return
;
}
if
(
Object
.
keys
(
_tiemstampMessages
).
length
<
1
||
Object
.
keys
(
_allMedias
).
length
<
1
){
console
.
log
(
"数据没有加载完成->不做匹配"
);
return
;
};
let
finelMediaInfo
=
{};
let
unknowFiles
=
{};
//记录没有匹配到的,需要再次匹配
let
tItem
;
for
(
let
j
in
_tiemstampMessages
){
tItem
=
_tiemstampMessages
[
j
];
...
...
@@ -377,13 +383,41 @@ class RecordPlayBackParse extends Emiter {
if
(
!
videoUrl
){
videoUrl
=
_allMedias
[
tItem
.
uid
+
"_"
+
(
t
+
1
)];
}
if
(
!
videoUrl
){
unknowFiles
[
tItem
.
timestamp
]
=
tItem
;
}
}
//console.log(tItem.uid+"_"+t+" "+videoUrl);
tItem
.
video_url
=
videoUrl
;
finelMediaInfo
[
tItem
.
timestamp
]
=
tItem
;
MediaModule
.
streams
[
tItem
.
stream_id
]
=
tItem
.
video_url
;
// MediaModule.streams[tItem.stream_id]=tItem.video_url;
MediaModule
.
streams
[
tItem
.
stream_id
]
=
{
video_url
:
tItem
.
video_url
,
seek
:
0
};
}
console
.
log
(
"finelMediaInfo"
,
finelMediaInfo
);
//最后处理没有匹配到的
//检测没有匹配到数据的消息
for
(
let
i
in
unknowFiles
){
let
noItem
=
unknowFiles
[
i
];
for
(
let
k
in
finelMediaInfo
){
let
okItem
=
finelMediaInfo
[
k
];
let
seek
=
(
parseInt
(
noItem
.
timestamp
)
-
parseInt
(
okItem
.
timestamp
))
/
1000
;
console
.
log
(
"seek"
,
seek
);
if
(
noItem
.
uid
==
okItem
.
uid
&&
seek
<
15
&&
noItem
.
timestamp
!=
okItem
.
timestamp
){
console
.
log
(
noItem
,
okItem
);
noItem
.
video_url
=
okItem
.
video_url
;
noItem
.
seek
=
seek
;
finelMediaInfo
[
noItem
.
timestamp
]
=
noItem
;
//MediaModule.streams[noItem.stream_id]=noItem.video_url;
console
.
log
(
"根据时间戳查找流"
,
noItem
.
stream_id
,{
video_url
:
noItem
.
video_url
,
seek
:
seek
})
MediaModule
.
streams
[
noItem
.
stream_id
]
=
{
video_url
:
noItem
.
video_url
,
seek
:
seek
};
}
}
}
console
.
log
(
"服务端所有m3u8文件"
,
_allMedias
);
console
.
log
(
"所有推流消息"
,
_tiemstampMessages
);
console
.
log
(
"最终匹配结束的文件"
,
finelMediaInfo
);
console
.
log
(
"回放中最终使用的视频流数据"
,
MediaModule
.
streams
);
}
//获取媒体录制的地址信息-时间戳流名称和文件地址对应
...
...
@@ -647,7 +681,8 @@ class RecordPlayBackParse extends Emiter {
}
if
(
itemJson
&&
itemJson
.
video_url
){
if
(
itemJson
.
video_url
.
indexOf
(
".m3u8"
)
>
0
){
MediaModule
.
streams
[
itemJson
.
stream_id
]
=
itemJson
.
video_url
;
//MediaModule.streams[itemJson.stream_id]=itemJson.video_url;
MediaModule
.
streams
[
itemJson
.
stream_id
]
=
{
video_url
:
itemJson
.
video_url
,
seek
:
0
};
}
}
}
...
...
src/Sass.js
查看文件 @
8b4c84b
...
...
@@ -433,9 +433,13 @@ class Sass extends Emiter {
loger
.
log
(
'录制回放中,不需要保存课堂信息'
);
return
;
}
if
(
!
_param
||!
_param
.
classStatusInfo
){
return
;
}
//{"classStatusInfo":classStatusInfo}
let
timestamp
=
new
Date
().
getTime
();
let
authId
=
MD5
(
GlobalConfig
.
classId
+
""
+
timestamp
);
// (classId+timestamp)的字符串,转成MD5
_param
.
classStatusInfo
.
lastClassActiveTime
=
timestamp
;
let
classStatusInfo
=
JSON
.
stringify
(
_param
.
classStatusInfo
);
//let url = `http://${GlobalConfig.portal}/3m/api/meeting/saveInfo.do`;
let
url
=
`
$
{
GlobalConfig
.
locationProtocol
+
GlobalConfig
.
portal
}
/3m/
api
/
meeting
/
saveInfo
.
do
`
;
...
...
src/apes/MediaModule.js
查看文件 @
8b4c84b
...
...
@@ -103,15 +103,20 @@ class MediaModule {
}
//如果是外部的流地址,不需要拼接,直接使用就可以,是完整的地址
let
streamPlayUrl
=
MediaModule
.
streams
[
_param
.
streamId
];
if
(
streamPlayUrl
){
loger
.
log
(
"使用外部的流地址->"
,
streamPlayUrl
);
streamPlayUrl
=
streamPlayUrl
.
replace
(
"http://"
,
""
);
streamPlayUrl
=
streamPlayUrl
.
replace
(
"https://"
,
""
);
streamPlayUrl
=
GlobalConfig
.
locationProtocol
+
streamPlayUrl
;
return
{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
""
,
"playUrl"
:
streamPlayUrl
};
let
streamItem
=
MediaModule
.
streams
[
_param
.
streamId
];
if
(
streamItem
){
let
streamPlayUrl
=
streamItem
.
video_url
||
""
;
let
seek
=
parseInt
(
streamItem
.
seek
)
||
0
;
if
(
streamPlayUrl
){
loger
.
log
(
"使用外部的流地址->"
,
streamPlayUrl
);
streamPlayUrl
=
streamPlayUrl
.
replace
(
"http://"
,
""
);
streamPlayUrl
=
streamPlayUrl
.
replace
(
"https://"
,
""
);
streamPlayUrl
=
GlobalConfig
.
locationProtocol
+
streamPlayUrl
;
return
{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
""
,
"playUrl"
:
streamPlayUrl
,
"seek"
:
seek
};
}
}
//M3U8 http://123.56.73.119:6001/live/h5dev_2106728010_8ab3b0ed5a3a9220015a3a958f0d0003_983041_1489113860/total.m3u8
let
port
=
(
GlobalConfig
.
RS_RECORD_PLAY_PORT
==
""
||
GlobalConfig
.
RS_RECORD_PLAY_PORT
==
null
)
?
""
:
":"
+
GlobalConfig
.
RS_RECORD_PLAY_PORT
;
//let path = "http://" + GlobalConfig.RS_RECORD_PLAY_IP
...
...
@@ -129,7 +134,7 @@ class MediaModule {
+
rHlsSuffix
;
path
=
path
.
replace
(
"::"
,
":"
);
//如果ip和port之间有多的:需要去掉
return
{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
""
,
"playUrl"
:
path
};
return
{
"code"
:
ApeConsts
.
RETURN_SUCCESS
,
"data"
:
""
,
"playUrl"
:
path
,
"seek"
:
0
};
}
//推流地址后缀拼接参数
...
...
src/apes/VideoApe.js
查看文件 @
8b4c84b
...
...
@@ -697,6 +697,7 @@ class VideoApe extends Ape {
}
if
(
replay
.
code
==
0
)
{
receiveChannelInfo
.
replay
=
replay
.
playUrl
;
receiveChannelInfo
.
seek
=
receiveChannelInfo
.
seek
+
replay
.
seek
;
}
if
(
unpackChannelInfo
.
mediaType
!=
ApeConsts
.
MEDIA_TYPE_SHARE
&&
...
...
请
注册
或
登录
后发表评论