Toggle navigation
Toggle navigation
此项目
正在载入...
Sign in
张艾宸
/
webScreen
转到一个项目
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
799967501@qq.com
4 years ago
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
48d8cdf63818e3b56da77c882a2d5e7b15a0ff19
48d8cdf6
1 parent
8ffc2b2f
添加实时直播接口(目前步步高用)
隐藏空白字符变更
内嵌
并排对比
正在显示
3 个修改的文件
包含
193 行增加
和
4 行删除
app.js
config/realTimeConfig.json
routes/bbgRecording.js
app.js
查看文件 @
48d8cdf
...
...
@@ -5,6 +5,7 @@ var cookieParser = require('cookie-parser');
var
logger
=
require
(
'morgan'
);
var
indexRouter
=
require
(
'./routes/index'
);
var
bbgRecordingRouter
=
require
(
'./routes/bbgRecording'
);
var
app
=
express
();
...
...
@@ -18,7 +19,18 @@ app.use(express.urlencoded({ extended: false }));
app
.
use
(
cookieParser
());
app
.
use
(
express
.
static
(
path
.
join
(
__dirname
,
'public'
)));
app
.
all
(
"*"
,
function
(
req
,
res
,
next
){
//设置允许跨域的域名,*代表允许任意域名跨域
res
.
header
(
"Access-Control-Allow-Origin"
,
"*"
);
//允许的header类型
res
.
header
(
"Access-Control-Allow-Headers"
,
"content-type"
);
//跨域允许的请求方式
res
.
header
(
"Access-Control-Allow-Methods"
,
"POST,OPTIONS"
);
next
();
});
app
.
use
(
'/'
,
indexRouter
);
app
.
use
(
'/mp4record'
,
bbgRecordingRouter
)
// catch 404 and forward to error handler
app
.
use
(
function
(
req
,
res
,
next
)
{
...
...
@@ -28,12 +40,13 @@ app.use(function(req, res, next) {
// error handler
app
.
use
(
function
(
err
,
req
,
res
,
next
)
{
// set locals, only providing error in development
res
.
locals
.
message
=
err
.
message
;
res
.
locals
.
error
=
req
.
app
.
get
(
'env'
)
===
'development'
?
err
:
{};
// res.locals.message = err.message;
// res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res
.
status
(
err
.
status
||
500
);
res
.
render
(
'error'
);
// res.status(err.status || 500);
// res.render('error');
res
.
send
({
code
:
err
.
status
||
500
});
});
module
.
exports
=
app
;
...
...
config/realTimeConfig.json
0 → 100755
查看文件 @
48d8cdf
{
"PROJECTWINCATALOG"
:
"F:/project/web_capture_release/win-x64"
,
"PROJECTCATALOG"
:
"/Users/zhangaichen/Desktop/学点云/webScreen"
,
"BACKMEDIACONFIG"
:
{
"url"
:
"https://pclive.xuedianyun.com/pcBase/pclive2/dev/index.html"
,
"recordMp4"
:
true
,
"classId"
:
""
,
"userId"
:
0
,
"userName"
:
""
,
"userRole"
:
"invisible"
,
"portalIP"
:
"saas.xuedianyun.com"
,
"portalPort"
:
80
,
"channels"
:
0
,
"playRecord"
:
1
,
"d"
:
21600000
,
"s"
:
3000
,
"fa"
:
15
,
"k"
:
0
,
"w"
:
1280
,
"h"
:
720
}
}
...
...
routes/bbgRecording.js
0 → 100644
查看文件 @
48d8cdf
var
express
=
require
(
'express'
);
var
router
=
express
.
Router
();
const
{
exec
}
=
require
(
'child_process'
);
const
fs
=
require
(
"fs"
);
const
axios
=
require
(
'axios'
);
const
method
=
require
(
"../config/method"
)
const
{
dayTimeYMD
}
=
method
let
classids
=
[]
/**
*
* @param {*} id 课堂id
*/
class
MediaCreat
{
constructor
()
{
}
wrieLog
(
text
)
{
// 写入log
let
logFile
=
`
.
/
log
/
$
{
dayTimeYMD
().
ymd
}.
txt
`
fs
.
appendFileSync
(
logFile
,
new
Date
().
toLocaleString
()
+
" "
+
text
+
'\r\n'
);
}
recordingCreat
(
id
,
siteId
,
classUrl
,
duration
,
width
,
height
,
frameRate
,
bitrate
)
{
this
.
wrieLog
(
" 课堂录制开始:------>"
+
id
)
let
fileConfig
=
this
.
getConfigFileJson
()
if
(
!
fileConfig
)
return
false
const
{
BACKMEDIACONFIG
,
PROJECTWINCATALOG
,
PROJECTCATALOG
}
=
JSON
.
parse
(
fileConfig
)
let
mediaDir
=
PROJECTCATALOG
+
"/media/"
let
classDir
=
PROJECTCATALOG
+
"/media/"
+
siteId
let
ymdDir
=
null
let
timeDir
=
dayTimeYMD
().
ymd
ymdDir
=
PROJECTCATALOG
+
"/media/"
+
siteId
+
"/"
+
timeDir
if
(
!
fs
.
existsSync
(
mediaDir
))
{
fs
.
mkdirSync
(
mediaDir
);
}
if
(
!
fs
.
existsSync
(
classDir
))
{
fs
.
mkdirSync
(
classDir
);
}
if
(
!
fs
.
existsSync
(
ymdDir
))
{
fs
.
mkdirSync
(
ymdDir
);
}
// let files = fs.readdirSync(ymdDir);
// let interValGetFile = setInterval(()=>{
// this.wrieLog("files:" + files)
// if (files.indexOf(id + ".mp4") != -1) {
// this.wrieLog("已存在:" + id + "课堂号,停止继续录制")
// return
// }
// if(!classUrl){
// classUrl = `${BACKMEDIACONFIG.url}?classId=${id}&recordMp4=${BACKMEDIACONFIG.recordMp4}&userId=${BACKMEDIACONFIG.userId}&userName=${BACKMEDIACONFIG.userName}&userRole=${BACKMEDIACONFIG.userRole}&portalIP=${BACKMEDIACONFIG.portalIP}&portalPort=${BACKMEDIACONFIG.portalPort}&channels=${BACKMEDIACONFIG.channels}"`
// }
// if(!duration){
// duration = BACKMEDIACONFIG.d
// }
let
url
=
`
$
{
PROJECTWINCATALOG
}
/web_capture_c -o=${ymdDir}/
$
{
id
}.
mp4
-
u
=
"${classUrl}"
-
d
=
$
{
duration
}
-
s
=
$
{
BACKMEDIACONFIG
.
s
}
-
k
=
$
{
BACKMEDIACONFIG
.
k
}
-
w
=
$
{
width
}
-
h
=
$
{
height
}
-
fa
=
$
{
frameRate
}
-
vb
=
$
{
bitrate
}
`
this
.
wrieLog
(
"全地址"
+
url
)
exec
(
url
,
{
maxBuffer
:
1073741824
},
(
err
,
stdout
,
stderr
)
=>
{
if
(
err
!=
null
)
{
this
.
wrieLog
(
" 错误"
+
id
+
":"
+
err
)
this
.
wrieLog
(
" 错误 stdout"
+
id
+
":"
+
stdout
)
this
.
wrieLog
(
" 错误 stderr"
+
id
+
":"
+
stderr
)
// 删除已存元素
classids
.
splice
(
classids
.
findIndex
(
item
=>
item
===
id
),
1
)
return
}
// let files = fs.readdirSync(ymdDir);
// if (files.indexOf(id + ".mp4") != -1) {
// 删除已存元素
classids
.
splice
(
classids
.
findIndex
(
item
=>
item
===
id
),
1
)
this
.
sendMediaInfo
(
siteId
,
id
,
timeDir
)
// }
})
}
// 上报地址
async
sendMediaInfo
(
siteId
,
id
,
timeDir
){
// https://testmp4.obs.cn-north-4.myhuaweicloud.com/oss/media/eebbktest/20210326/1657547103.mp4
let
MediaUrl
=
`
https
:
//testmp4.obs.cn-north-4.myhuaweicloud.com/oss/media/${siteId}/${timeDir}/${id}.mp4`
let
urlSizeId
=
{
"eebbktest"
:
"gdbbkwxyace"
,
"gdbbk"
:
"gdbbkwx"
,
"gdbbkdev"
:
"gdbbkwxtest"
}
let
requestUrl
=
`
https
:
//${urlSizeId[siteId]}.xuedianyun.com/bbgserver/app/course/updateRecordUrl`
let
result
=
await
axios
.
post
(
requestUrl
,
{
meetingNumber
:
id
,
url
:
MediaUrl
},
{
headers
:
{
'orgId'
:
siteId
}}
)
if
(
result
.
data
){
this
.
wrieLog
(
"更新视频地址结果:"
+
JSON
.
stringify
(
result
.
data
))
}
}
getConfigFileJson
()
{
const
buffer
=
fs
.
readFileSync
(
process
.
cwd
()
+
"/config/realTimeConfig.json"
)
return
String
(
buffer
)
}
}
/**
* {
* "classId":[{ classId: '389675110', siteId: 'kuaikuenglish' }]
* }
*/
router
.
post
(
'/recording/:id'
,
function
(
req
,
res
,
next
)
{
new
MediaCreat
().
wrieLog
(
"录制启动:------>"
)
let
fileConfig
=
new
MediaCreat
().
getConfigFileJson
()
if
(
!
fileConfig
)
return
false
/**
* classId:课堂号
* siteId:机构编码
* url:课堂地址
* duration:录制时长
* width height 录制视频宽高
* frameRate 帧率
* bitrate 码率
*/
let
{
classId
,
siteId
,
url
:
classUrl
,
duration
,
width
,
height
,
frameRate
,
bitrate
}
=
req
.
body
if
(
classId
&&
siteId
&&
classUrl
&&
duration
&&
width
&&
height
&&
frameRate
&&
bitrate
)
{
if
(
!
Number
.
isInteger
(
classId
)
||
!
Number
.
isInteger
(
duration
)
||
!
Number
.
isInteger
(
width
)
||
!
Number
.
isInteger
(
height
)
||
!
Number
.
isInteger
(
frameRate
)
||
!
Number
.
isInteger
(
bitrate
)){
res
.
send
({
code
:
"3"
,
message
:
"参数类型错误"
});
return
}
let
maxTime
=
10
*
60
*
60
*
1000
if
(
duration
<
0
||
duration
>
maxTime
){
res
.
send
({
code
:
"4"
,
message
:
"参数范围错误"
});
return
}
// 避免多次重复课堂号请求
if
(
!
classids
.
includes
(
classId
)){
// 没有正在录制的该课堂
classids
.
push
(
classId
)
bitrate
=
bitrate
*
1024
// 转换 * 1024
new
MediaCreat
().
recordingCreat
(
classId
,
siteId
,
classUrl
,
duration
,
width
,
height
,
frameRate
,
bitrate
)
res
.
send
({
code
:
"0"
});
}
else
{
res
.
send
({
code
:
"2"
,
message
:
"重复请求课堂号"
});
}
}
else
{
res
.
send
({
code
:
"1"
,
message
:
"缺少参数"
});
}
})
module
.
exports
=
router
;
...
...
请
注册
或
登录
后发表评论