正在显示
26 个修改的文件
包含
2223 行增加
和
217 行删除
.env
0 → 100644
.gitignore
100755 → 100644
.idea/misc.xml
100755 → 100644
.idea/modules.xml
100755 → 100644
.idea/vcs.xml
100755 → 100644
.idea/webScreen.iml
100755 → 100644
README.md
100755 → 100644
app.js
100755 → 100644
| @@ -5,6 +5,7 @@ var cookieParser = require('cookie-parser'); | @@ -5,6 +5,7 @@ var cookieParser = require('cookie-parser'); | ||
| 5 | var logger = require('morgan'); | 5 | var logger = require('morgan'); |
| 6 | 6 | ||
| 7 | var indexRouter = require('./routes/index'); | 7 | var indexRouter = require('./routes/index'); |
| 8 | +var bbgRecordingRouter = require('./routes/bbgRecording'); | ||
| 8 | 9 | ||
| 9 | var app = express(); | 10 | var app = express(); |
| 10 | 11 | ||
| @@ -18,7 +19,18 @@ app.use(express.urlencoded({ extended: false })); | @@ -18,7 +19,18 @@ app.use(express.urlencoded({ extended: false })); | ||
| 18 | app.use(cookieParser()); | 19 | app.use(cookieParser()); |
| 19 | app.use(express.static(path.join(__dirname, 'public'))); | 20 | app.use(express.static(path.join(__dirname, 'public'))); |
| 20 | 21 | ||
| 22 | +app.all("*",function(req,res,next){ | ||
| 23 | + //设置允许跨域的域名,*代表允许任意域名跨域 | ||
| 24 | + res.header("Access-Control-Allow-Origin","*"); | ||
| 25 | + //允许的header类型 | ||
| 26 | + res.header("Access-Control-Allow-Headers","content-type"); | ||
| 27 | + //跨域允许的请求方式 | ||
| 28 | + res.header("Access-Control-Allow-Methods","POST,OPTIONS"); | ||
| 29 | + next(); | ||
| 30 | +}); | ||
| 31 | + | ||
| 21 | app.use('/', indexRouter); | 32 | app.use('/', indexRouter); |
| 33 | +app.use('/mp4record',bbgRecordingRouter); | ||
| 22 | 34 | ||
| 23 | // catch 404 and forward to error handler | 35 | // catch 404 and forward to error handler |
| 24 | app.use(function(req, res, next) { | 36 | app.use(function(req, res, next) { |
| @@ -28,12 +40,13 @@ app.use(function(req, res, next) { | @@ -28,12 +40,13 @@ app.use(function(req, res, next) { | ||
| 28 | // error handler | 40 | // error handler |
| 29 | app.use(function(err, req, res, next) { | 41 | app.use(function(err, req, res, next) { |
| 30 | // set locals, only providing error in development | 42 | // set locals, only providing error in development |
| 31 | - res.locals.message = err.message; | ||
| 32 | - res.locals.error = req.app.get('env') === 'development' ? err : {}; | 43 | + //res.locals.message = err.message; |
| 44 | + //res.locals.error = req.app.get('env') === 'development' ? err : {}; | ||
| 33 | 45 | ||
| 34 | // render the error page | 46 | // render the error page |
| 35 | - res.status(err.status || 500); | ||
| 36 | - res.render('error'); | 47 | + // res.status(err.status || 500); |
| 48 | + //res.render('error'); | ||
| 49 | + res.send({ code: err.status || 500 }); | ||
| 37 | }); | 50 | }); |
| 38 | 51 | ||
| 39 | module.exports = app; | 52 | module.exports = app; |
app.jsbak
0 → 100644
| 1 | +var createError = require('http-errors'); | ||
| 2 | +var express = require('express'); | ||
| 3 | +var path = require('path'); | ||
| 4 | +var cookieParser = require('cookie-parser'); | ||
| 5 | +var logger = require('morgan'); | ||
| 6 | + | ||
| 7 | +var indexRouter = require('./routes/index'); | ||
| 8 | + | ||
| 9 | +var app = express(); | ||
| 10 | + | ||
| 11 | +// view engine setup | ||
| 12 | +app.set('views', path.join(__dirname, 'views')); | ||
| 13 | +app.set('view engine', 'jade'); | ||
| 14 | + | ||
| 15 | +app.use(logger('dev')); | ||
| 16 | +app.use(express.json()); | ||
| 17 | +app.use(express.urlencoded({ extended: false })); | ||
| 18 | +app.use(cookieParser()); | ||
| 19 | +app.use(express.static(path.join(__dirname, 'public'))); | ||
| 20 | + | ||
| 21 | +app.use('/', indexRouter); | ||
| 22 | + | ||
| 23 | +// catch 404 and forward to error handler | ||
| 24 | +app.use(function(req, res, next) { | ||
| 25 | + next(createError(404)); | ||
| 26 | +}); | ||
| 27 | + | ||
| 28 | +// error handler | ||
| 29 | +app.use(function(err, req, res, next) { | ||
| 30 | + // set locals, only providing error in development | ||
| 31 | + res.locals.message = err.message; | ||
| 32 | + res.locals.error = req.app.get('env') === 'development' ? err : {}; | ||
| 33 | + | ||
| 34 | + // render the error page | ||
| 35 | + res.status(err.status || 500); | ||
| 36 | + res.render('error'); | ||
| 37 | +}); | ||
| 38 | + | ||
| 39 | +module.exports = app; |
bin/www
100755 → 100644
| @@ -12,7 +12,8 @@ var http = require('http'); | @@ -12,7 +12,8 @@ var http = require('http'); | ||
| 12 | * Get port from environment and store in Express. | 12 | * Get port from environment and store in Express. |
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | -var port = normalizePort(process.env.PORT || '3001'); | 15 | +var port = normalizePort( '3001'); |
| 16 | +console.log("port",port) | ||
| 16 | app.set('port', port); | 17 | app.set('port', port); |
| 17 | 18 | ||
| 18 | /** | 19 | /** |
config/config.json
100755 → 100644
| 1 | { | 1 | { |
| 2 | - "GETCLASSURL":"http://139.196.126.156:8081/getLogs/recordClassList", | 2 | + "GETCLASSURL":"https://log3.xuedianyun.com/getLogs/recordClassList", |
| 3 | "GETCLASSURLPARAMETER":{ | 3 | "GETCLASSURLPARAMETER":{ |
| 4 | - "siteId":["beidatest"], | 4 | + "siteId":["chindle","skyy","hopefound","beidatest"], |
| 5 | "key":"xdymp4record20191225", | 5 | "key":"xdymp4record20191225", |
| 6 | "page":1, | 6 | "page":1, |
| 7 | - "maxMedia":1 | 7 | + "maxMedia":23 |
| 8 | }, | 8 | }, |
| 9 | - "PROJECTWINCATALOG":"F:/project/web_capture_release/win-x64", | ||
| 10 | - "PROJECTCATALOG":"F:/project/web_capture_release", | 9 | + "PROJECTWINCATALOG":"/root/web_capture_release/linux-x64", |
| 10 | + "PROJECTCATALOG":"/root/web_capture_release", | ||
| 11 | "BACKMEDIACONFIG":{ | 11 | "BACKMEDIACONFIG":{ |
| 12 | "url" : "https://pclive.xuedianyun.com/pcBase/pclive2/dev/index.html", | 12 | "url" : "https://pclive.xuedianyun.com/pcBase/pclive2/dev/index.html", |
| 13 | "recordMp4":true, | 13 | "recordMp4":true, |
| @@ -25,5 +25,6 @@ | @@ -25,5 +25,6 @@ | ||
| 25 | "k":0, | 25 | "k":0, |
| 26 | "w":1280, | 26 | "w":1280, |
| 27 | "h":720 | 27 | "h":720 |
| 28 | - } | ||
| 29 | -} | ||
| 28 | + }, | ||
| 29 | + "classLastNumber":["0","1","2","3","4","5","6","7","8","9"] | ||
| 30 | +} |
config/method.js
100755 → 100644
| @@ -5,38 +5,49 @@ const methods = { | @@ -5,38 +5,49 @@ const methods = { | ||
| 5 | let YesterdayTime = (new Date).getTime() - 24 * 60 * 60 * 1000 | 5 | let YesterdayTime = (new Date).getTime() - 24 * 60 * 60 * 1000 |
| 6 | let YesterdayTimeDate = new Date(YesterdayTime) | 6 | let YesterdayTimeDate = new Date(YesterdayTime) |
| 7 | let year = YesterdayTimeDate.getFullYear() | 7 | let year = YesterdayTimeDate.getFullYear() |
| 8 | + year = year.toString() | ||
| 8 | let month = YesterdayTimeDate.getMonth() + 1 | 9 | let month = YesterdayTimeDate.getMonth() + 1 |
| 9 | let date = YesterdayTimeDate.getDate() | 10 | let date = YesterdayTimeDate.getDate() |
| 10 | let startTime = new Date(year + "-" + month + "-" + date + " 5:30:00").getTime() | 11 | let startTime = new Date(year + "-" + month + "-" + date + " 5:30:00").getTime() |
| 11 | let endTime = new Date(year + "-" + month + "-" + date + " 23:59:00").getTime() | 12 | let endTime = new Date(year + "-" + month + "-" + date + " 23:59:00").getTime() |
| 12 | - if(month < 10){ | 13 | + if (month < 10) { |
| 13 | month = '0' + month | 14 | month = '0' + month |
| 15 | + }else{ | ||
| 16 | + month = month.toString() | ||
| 14 | } | 17 | } |
| 15 | - if(date < 10){ | 18 | + |
| 19 | + if (date < 10) { | ||
| 16 | date = '0' + date | 20 | date = '0' + date |
| 21 | + }else{ | ||
| 22 | + date = date.toString() | ||
| 17 | } | 23 | } |
| 18 | return { | 24 | return { |
| 19 | startTime, | 25 | startTime, |
| 20 | endTime, | 26 | endTime, |
| 21 | - ymd:year+month+date | 27 | + ymd: year + month + date |
| 22 | } | 28 | } |
| 23 | }, | 29 | }, |
| 24 | dayTimeYMD() { | 30 | dayTimeYMD() { |
| 25 | let dayTimeDate = new Date() | 31 | let dayTimeDate = new Date() |
| 26 | let year = dayTimeDate.getFullYear() | 32 | let year = dayTimeDate.getFullYear() |
| 33 | + year = year.toString() | ||
| 27 | let month = dayTimeDate.getMonth() + 1 | 34 | let month = dayTimeDate.getMonth() + 1 |
| 28 | let date = dayTimeDate.getDate() | 35 | let date = dayTimeDate.getDate() |
| 29 | - if(month < 10){ | 36 | + if (month < 10) { |
| 30 | month = '0' + month | 37 | month = '0' + month |
| 38 | + }else{ | ||
| 39 | + month = month.toString() | ||
| 31 | } | 40 | } |
| 32 | - if(date < 10){ | 41 | + if (date < 10) { |
| 33 | date = '0' + date | 42 | date = '0' + date |
| 43 | + }else{ | ||
| 44 | + date = date.toString() | ||
| 34 | } | 45 | } |
| 35 | return { | 46 | return { |
| 36 | - ymd:year + "-" + month + "-" + date | 47 | + ymd: year + month + date |
| 37 | } | 48 | } |
| 38 | }, | 49 | }, |
| 39 | - async getRequestClassIds(url, siteId, key, startTime, endTime,page) { | 50 | + async getRequestClassIds(url, siteId, key, startTime, endTime, page) { |
| 40 | let axiosUrl = `${url}?siteId=${siteId}&key=${key}&from=${startTime}&to=${endTime}&page=${page}` | 51 | let axiosUrl = `${url}?siteId=${siteId}&key=${key}&from=${startTime}&to=${endTime}&page=${page}` |
| 41 | let result = await axios.get(axiosUrl) | 52 | let result = await axios.get(axiosUrl) |
| 42 | return result | 53 | return result |
config/realTimeConfig.json
0 → 100644
| 1 | +{ | ||
| 2 | + "PROJECTWINCATALOG":"/root/web_capture_release/linux-x64", | ||
| 3 | + "PROJECTCATALOG":"/oss/oss", | ||
| 4 | + "BACKMEDIACONFIG": { | ||
| 5 | + "url": "https://pclive.xuedianyun.com/pcBase/pclive2/dev/index.html", | ||
| 6 | + "recordMp4": true, | ||
| 7 | + "classId": "", | ||
| 8 | + "userId": 0, | ||
| 9 | + "userName": "", | ||
| 10 | + "userRole": "invisible", | ||
| 11 | + "portalIP": "saas.xuedianyun.com", | ||
| 12 | + "portalPort": 80, | ||
| 13 | + "channels": 0, | ||
| 14 | + "playRecord": 1, | ||
| 15 | + "d": 21600000, | ||
| 16 | + "s": 3000, | ||
| 17 | + "fa": 15, | ||
| 18 | + "k": 0, | ||
| 19 | + "w": 1280, | ||
| 20 | + "h": 720 | ||
| 21 | + } | ||
| 22 | +} |
package-lock.json
100755 → 100644
| @@ -26,6 +26,80 @@ | @@ -26,6 +26,80 @@ | ||
| 26 | "acorn": "^2.1.0" | 26 | "acorn": "^2.1.0" |
| 27 | } | 27 | } |
| 28 | }, | 28 | }, |
| 29 | + "address": { | ||
| 30 | + "version": "1.2.2", | ||
| 31 | + "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", | ||
| 32 | + "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==" | ||
| 33 | + }, | ||
| 34 | + "agentkeepalive": { | ||
| 35 | + "version": "3.5.3", | ||
| 36 | + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.3.tgz", | ||
| 37 | + "integrity": "sha512-yqXL+k5rr8+ZRpOAntkaaRgWgE5o8ESAj5DyRmVTCSoZxXmqemb9Dd7T4i5UzwuERdLAJUy6XzR9zFVuf0kzkw==", | ||
| 38 | + "requires": { | ||
| 39 | + "humanize-ms": "^1.2.1" | ||
| 40 | + } | ||
| 41 | + }, | ||
| 42 | + "ali-oss": { | ||
| 43 | + "version": "6.22.0", | ||
| 44 | + "resolved": "https://registry.npmjs.org/ali-oss/-/ali-oss-6.22.0.tgz", | ||
| 45 | + "integrity": "sha512-X8CHo+wsjCBvDaEvuibFOi3SZxiCBZSRUURrXH0upoVwu3SuW3e+PTVK7xw+uN6EyTcAESqrngrQimhp8iBzsQ==", | ||
| 46 | + "requires": { | ||
| 47 | + "address": "^1.2.2", | ||
| 48 | + "agentkeepalive": "^3.4.1", | ||
| 49 | + "bowser": "^1.6.0", | ||
| 50 | + "copy-to": "^2.0.1", | ||
| 51 | + "dateformat": "^2.0.0", | ||
| 52 | + "debug": "^4.3.4", | ||
| 53 | + "destroy": "^1.0.4", | ||
| 54 | + "end-or-error": "^1.0.1", | ||
| 55 | + "get-ready": "^1.0.0", | ||
| 56 | + "humanize-ms": "^1.2.0", | ||
| 57 | + "is-type-of": "^1.4.0", | ||
| 58 | + "js-base64": "^2.5.2", | ||
| 59 | + "jstoxml": "^2.0.0", | ||
| 60 | + "lodash": "^4.17.21", | ||
| 61 | + "merge-descriptors": "^1.0.1", | ||
| 62 | + "mime": "^2.4.5", | ||
| 63 | + "platform": "^1.3.1", | ||
| 64 | + "pump": "^3.0.0", | ||
| 65 | + "qs": "^6.4.0", | ||
| 66 | + "sdk-base": "^2.0.1", | ||
| 67 | + "stream-http": "2.8.2", | ||
| 68 | + "stream-wormhole": "^1.0.4", | ||
| 69 | + "urllib": "^2.44.0", | ||
| 70 | + "utility": "^1.18.0", | ||
| 71 | + "xml2js": "^0.6.2" | ||
| 72 | + }, | ||
| 73 | + "dependencies": { | ||
| 74 | + "debug": { | ||
| 75 | + "version": "4.4.0", | ||
| 76 | + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", | ||
| 77 | + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", | ||
| 78 | + "requires": { | ||
| 79 | + "ms": "^2.1.3" | ||
| 80 | + } | ||
| 81 | + }, | ||
| 82 | + "mime": { | ||
| 83 | + "version": "2.6.0", | ||
| 84 | + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", | ||
| 85 | + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==" | ||
| 86 | + }, | ||
| 87 | + "ms": { | ||
| 88 | + "version": "2.1.3", | ||
| 89 | + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", | ||
| 90 | + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" | ||
| 91 | + }, | ||
| 92 | + "xml2js": { | ||
| 93 | + "version": "0.6.2", | ||
| 94 | + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", | ||
| 95 | + "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", | ||
| 96 | + "requires": { | ||
| 97 | + "sax": ">=0.6.0", | ||
| 98 | + "xmlbuilder": "~11.0.0" | ||
| 99 | + } | ||
| 100 | + } | ||
| 101 | + } | ||
| 102 | + }, | ||
| 29 | "align-text": { | 103 | "align-text": { |
| 30 | "version": "0.1.4", | 104 | "version": "0.1.4", |
| 31 | "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", | 105 | "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", |
| @@ -41,6 +115,11 @@ | @@ -41,6 +115,11 @@ | ||
| 41 | "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", | 115 | "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", |
| 42 | "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" | 116 | "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" |
| 43 | }, | 117 | }, |
| 118 | + "any-promise": { | ||
| 119 | + "version": "1.3.0", | ||
| 120 | + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", | ||
| 121 | + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" | ||
| 122 | + }, | ||
| 44 | "array-flatten": { | 123 | "array-flatten": { |
| 45 | "version": "1.1.1", | 124 | "version": "1.1.1", |
| 46 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", | 125 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", |
| @@ -97,6 +176,11 @@ | @@ -97,6 +176,11 @@ | ||
| 97 | "type-is": "~1.6.16" | 176 | "type-is": "~1.6.16" |
| 98 | } | 177 | } |
| 99 | }, | 178 | }, |
| 179 | + "bowser": { | ||
| 180 | + "version": "1.9.4", | ||
| 181 | + "resolved": "https://registry.npmjs.org/bowser/-/bowser-1.9.4.tgz", | ||
| 182 | + "integrity": "sha512-9IdMmj2KjigRq6oWhmwv1W36pDuA4STQZ8q6YO9um+x07xgYNCD3Oou+WP/3L1HNz7iqythGet3/p4wvc8AAwQ==" | ||
| 183 | + }, | ||
| 100 | "brace-expansion": { | 184 | "brace-expansion": { |
| 101 | "version": "1.1.11", | 185 | "version": "1.1.11", |
| 102 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", | 186 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", |
| @@ -106,6 +190,11 @@ | @@ -106,6 +190,11 @@ | ||
| 106 | "concat-map": "0.0.1" | 190 | "concat-map": "0.0.1" |
| 107 | } | 191 | } |
| 108 | }, | 192 | }, |
| 193 | + "builtin-status-codes": { | ||
| 194 | + "version": "3.0.0", | ||
| 195 | + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", | ||
| 196 | + "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==" | ||
| 197 | + }, | ||
| 109 | "bytes": { | 198 | "bytes": { |
| 110 | "version": "3.0.0", | 199 | "version": "3.0.0", |
| 111 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", | 200 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", |
| @@ -218,6 +307,16 @@ | @@ -218,6 +307,16 @@ | ||
| 218 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", | 307 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", |
| 219 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" | 308 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" |
| 220 | }, | 309 | }, |
| 310 | + "copy-to": { | ||
| 311 | + "version": "2.0.1", | ||
| 312 | + "resolved": "https://registry.npmjs.org/copy-to/-/copy-to-2.0.1.tgz", | ||
| 313 | + "integrity": "sha512-3DdaFaU/Zf1AnpLiFDeNCD4TOWe3Zl2RZaTzUvWiIk5ERzcCodOE20Vqq4fzCbNoHURFHT4/us/Lfq+S2zyY4w==" | ||
| 314 | + }, | ||
| 315 | + "core-util-is": { | ||
| 316 | + "version": "1.0.3", | ||
| 317 | + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", | ||
| 318 | + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" | ||
| 319 | + }, | ||
| 221 | "css": { | 320 | "css": { |
| 222 | "version": "1.0.8", | 321 | "version": "1.0.8", |
| 223 | "resolved": "https://registry.npmjs.org/css/-/css-1.0.8.tgz", | 322 | "resolved": "https://registry.npmjs.org/css/-/css-1.0.8.tgz", |
| @@ -237,6 +336,16 @@ | @@ -237,6 +336,16 @@ | ||
| 237 | "resolved": "https://registry.npmjs.org/css-stringify/-/css-stringify-1.0.5.tgz", | 336 | "resolved": "https://registry.npmjs.org/css-stringify/-/css-stringify-1.0.5.tgz", |
| 238 | "integrity": "sha1-sNBClG2ylTu50pKQCmy19tASIDE=" | 337 | "integrity": "sha1-sNBClG2ylTu50pKQCmy19tASIDE=" |
| 239 | }, | 338 | }, |
| 339 | + "date-format": { | ||
| 340 | + "version": "3.0.0", | ||
| 341 | + "resolved": "https://registry.npmjs.org/date-format/-/date-format-3.0.0.tgz", | ||
| 342 | + "integrity": "sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w==" | ||
| 343 | + }, | ||
| 344 | + "dateformat": { | ||
| 345 | + "version": "2.2.0", | ||
| 346 | + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", | ||
| 347 | + "integrity": "sha512-GODcnWq3YGoTnygPfi02ygEiRxqUxpJwuRHjdhJYuxpcZmDq4rjBiXYmbCCzStxo176ixfLT6i4NPwQooRySnw==" | ||
| 348 | + }, | ||
| 240 | "debug": { | 349 | "debug": { |
| 241 | "version": "2.6.9", | 350 | "version": "2.6.9", |
| 242 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", | 351 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", |
| @@ -250,6 +359,14 @@ | @@ -250,6 +359,14 @@ | ||
| 250 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", | 359 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", |
| 251 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" | 360 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" |
| 252 | }, | 361 | }, |
| 362 | + "default-user-agent": { | ||
| 363 | + "version": "1.0.0", | ||
| 364 | + "resolved": "https://registry.npmjs.org/default-user-agent/-/default-user-agent-1.0.0.tgz", | ||
| 365 | + "integrity": "sha512-bDF7bg6OSNcSwFWPu4zYKpVkJZQYVrAANMYB8bc9Szem1D0yKdm4sa/rOCs2aC9+2GMqQ7KnwtZRvDhmLF0dXw==", | ||
| 366 | + "requires": { | ||
| 367 | + "os-name": "~1.0.3" | ||
| 368 | + } | ||
| 369 | + }, | ||
| 253 | "define-properties": { | 370 | "define-properties": { |
| 254 | "version": "1.1.3", | 371 | "version": "1.1.3", |
| 255 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", | 372 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", |
| @@ -268,6 +385,16 @@ | @@ -268,6 +385,16 @@ | ||
| 268 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", | 385 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", |
| 269 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" | 386 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" |
| 270 | }, | 387 | }, |
| 388 | + "digest-header": { | ||
| 389 | + "version": "1.1.0", | ||
| 390 | + "resolved": "https://registry.npmjs.org/digest-header/-/digest-header-1.1.0.tgz", | ||
| 391 | + "integrity": "sha512-glXVh42vz40yZb9Cq2oMOt70FIoWiv+vxNvdKdU8CwjLad25qHM3trLxhl9bVjdr6WaslIXhWpn0NO8T/67Qjg==" | ||
| 392 | + }, | ||
| 393 | + "dotenv": { | ||
| 394 | + "version": "16.4.7", | ||
| 395 | + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", | ||
| 396 | + "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==" | ||
| 397 | + }, | ||
| 271 | "ee-first": { | 398 | "ee-first": { |
| 272 | "version": "1.1.1", | 399 | "version": "1.1.1", |
| 273 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", | 400 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", |
| @@ -278,6 +405,19 @@ | @@ -278,6 +405,19 @@ | ||
| 278 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", | 405 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", |
| 279 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" | 406 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" |
| 280 | }, | 407 | }, |
| 408 | + "end-of-stream": { | ||
| 409 | + "version": "1.4.4", | ||
| 410 | + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", | ||
| 411 | + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", | ||
| 412 | + "requires": { | ||
| 413 | + "once": "^1.4.0" | ||
| 414 | + } | ||
| 415 | + }, | ||
| 416 | + "end-or-error": { | ||
| 417 | + "version": "1.0.1", | ||
| 418 | + "resolved": "https://registry.npmjs.org/end-or-error/-/end-or-error-1.0.1.tgz", | ||
| 419 | + "integrity": "sha512-OclLMSug+k2A0JKuf494im25ANRBVW8qsjmwbgX7lQ8P82H21PQ1PWkoYwb9y5yMBS69BPlwtzdIFClo3+7kOQ==" | ||
| 420 | + }, | ||
| 281 | "es-abstract": { | 421 | "es-abstract": { |
| 282 | "version": "1.17.0", | 422 | "version": "1.17.0", |
| 283 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.0.tgz", | 423 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.0.tgz", |
| @@ -311,6 +451,15 @@ | @@ -311,6 +451,15 @@ | ||
| 311 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", | 451 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", |
| 312 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" | 452 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" |
| 313 | }, | 453 | }, |
| 454 | + "esdk-obs-nodejs": { | ||
| 455 | + "version": "3.20.11", | ||
| 456 | + "resolved": "https://registry.npmjs.org/esdk-obs-nodejs/-/esdk-obs-nodejs-3.20.11.tgz", | ||
| 457 | + "integrity": "sha512-pFdlFIV24yLXYwIg6UZz/xFHom5bTF+D5yyJHxngoP4o6KfxVIid3BTMPLh6MVTpSLBgiTwiGKfvvAJavH240g==", | ||
| 458 | + "requires": { | ||
| 459 | + "log4js": "^6.3.0", | ||
| 460 | + "xml2js": "^0.4.23" | ||
| 461 | + } | ||
| 462 | + }, | ||
| 314 | "etag": { | 463 | "etag": { |
| 315 | "version": "1.8.1", | 464 | "version": "1.8.1", |
| 316 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", | 465 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", |
| @@ -353,6 +502,14 @@ | @@ -353,6 +502,14 @@ | ||
| 353 | "vary": "~1.1.2" | 502 | "vary": "~1.1.2" |
| 354 | } | 503 | } |
| 355 | }, | 504 | }, |
| 505 | + "extend-shallow": { | ||
| 506 | + "version": "2.0.1", | ||
| 507 | + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", | ||
| 508 | + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", | ||
| 509 | + "requires": { | ||
| 510 | + "is-extendable": "^0.1.0" | ||
| 511 | + } | ||
| 512 | + }, | ||
| 356 | "finalhandler": { | 513 | "finalhandler": { |
| 357 | "version": "1.1.1", | 514 | "version": "1.1.1", |
| 358 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", | 515 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", |
| @@ -367,6 +524,11 @@ | @@ -367,6 +524,11 @@ | ||
| 367 | "unpipe": "~1.0.0" | 524 | "unpipe": "~1.0.0" |
| 368 | } | 525 | } |
| 369 | }, | 526 | }, |
| 527 | + "flatted": { | ||
| 528 | + "version": "2.0.2", | ||
| 529 | + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", | ||
| 530 | + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==" | ||
| 531 | + }, | ||
| 370 | "follow-redirects": { | 532 | "follow-redirects": { |
| 371 | "version": "1.5.10", | 533 | "version": "1.5.10", |
| 372 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", | 534 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", |
| @@ -385,6 +547,24 @@ | @@ -385,6 +547,24 @@ | ||
| 385 | } | 547 | } |
| 386 | } | 548 | } |
| 387 | }, | 549 | }, |
| 550 | + "formstream": { | ||
| 551 | + "version": "1.5.1", | ||
| 552 | + "resolved": "https://registry.npmjs.org/formstream/-/formstream-1.5.1.tgz", | ||
| 553 | + "integrity": "sha512-q7ORzFqotpwn3Y/GBK2lK7PjtZZwJHz9QE9Phv8zb5IrL9ftGLyi2zjGURON3voK8TaZ+mqJKERYN4lrHYTkUQ==", | ||
| 554 | + "requires": { | ||
| 555 | + "destroy": "^1.0.4", | ||
| 556 | + "mime": "^2.5.2", | ||
| 557 | + "node-hex": "^1.0.1", | ||
| 558 | + "pause-stream": "~0.0.11" | ||
| 559 | + }, | ||
| 560 | + "dependencies": { | ||
| 561 | + "mime": { | ||
| 562 | + "version": "2.6.0", | ||
| 563 | + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", | ||
| 564 | + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==" | ||
| 565 | + } | ||
| 566 | + } | ||
| 567 | + }, | ||
| 388 | "forwarded": { | 568 | "forwarded": { |
| 389 | "version": "0.1.2", | 569 | "version": "0.1.2", |
| 390 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", | 570 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", |
| @@ -395,6 +575,16 @@ | @@ -395,6 +575,16 @@ | ||
| 395 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", | 575 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", |
| 396 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" | 576 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" |
| 397 | }, | 577 | }, |
| 578 | + "fs-extra": { | ||
| 579 | + "version": "8.1.0", | ||
| 580 | + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", | ||
| 581 | + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", | ||
| 582 | + "requires": { | ||
| 583 | + "graceful-fs": "^4.2.0", | ||
| 584 | + "jsonfile": "^4.0.0", | ||
| 585 | + "universalify": "^0.1.0" | ||
| 586 | + } | ||
| 587 | + }, | ||
| 398 | "fs.realpath": { | 588 | "fs.realpath": { |
| 399 | "version": "1.0.0", | 589 | "version": "1.0.0", |
| 400 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", | 590 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", |
| @@ -405,6 +595,11 @@ | @@ -405,6 +595,11 @@ | ||
| 405 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", | 595 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", |
| 406 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" | 596 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" |
| 407 | }, | 597 | }, |
| 598 | + "get-ready": { | ||
| 599 | + "version": "1.0.0", | ||
| 600 | + "resolved": "https://registry.npmjs.org/get-ready/-/get-ready-1.0.0.tgz", | ||
| 601 | + "integrity": "sha512-mFXCZPJIlcYcth+N8267+mghfYN9h3EhsDa6JSnbA3Wrhh/XFpuowviFcsDeYZtKspQyWyJqfs4O6P8CHeTwzw==" | ||
| 602 | + }, | ||
| 408 | "glob": { | 603 | "glob": { |
| 409 | "version": "7.1.6", | 604 | "version": "7.1.6", |
| 410 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", | 605 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", |
| @@ -418,6 +613,11 @@ | @@ -418,6 +613,11 @@ | ||
| 418 | "path-is-absolute": "^1.0.0" | 613 | "path-is-absolute": "^1.0.0" |
| 419 | } | 614 | } |
| 420 | }, | 615 | }, |
| 616 | + "graceful-fs": { | ||
| 617 | + "version": "4.2.4", | ||
| 618 | + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", | ||
| 619 | + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" | ||
| 620 | + }, | ||
| 421 | "graceful-readlink": { | 621 | "graceful-readlink": { |
| 422 | "version": "1.0.1", | 622 | "version": "1.0.1", |
| 423 | "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", | 623 | "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", |
| @@ -447,6 +647,14 @@ | @@ -447,6 +647,14 @@ | ||
| 447 | "statuses": ">= 1.4.0 < 2" | 647 | "statuses": ">= 1.4.0 < 2" |
| 448 | } | 648 | } |
| 449 | }, | 649 | }, |
| 650 | + "humanize-ms": { | ||
| 651 | + "version": "1.2.1", | ||
| 652 | + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", | ||
| 653 | + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", | ||
| 654 | + "requires": { | ||
| 655 | + "ms": "^2.0.0" | ||
| 656 | + } | ||
| 657 | + }, | ||
| 450 | "iconv-lite": { | 658 | "iconv-lite": { |
| 451 | "version": "0.4.23", | 659 | "version": "0.4.23", |
| 452 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", | 660 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", |
| @@ -494,11 +702,21 @@ | @@ -494,11 +702,21 @@ | ||
| 494 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", | 702 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", |
| 495 | "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==" | 703 | "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==" |
| 496 | }, | 704 | }, |
| 705 | + "is-class-hotfix": { | ||
| 706 | + "version": "0.0.6", | ||
| 707 | + "resolved": "https://registry.npmjs.org/is-class-hotfix/-/is-class-hotfix-0.0.6.tgz", | ||
| 708 | + "integrity": "sha512-0n+pzCC6ICtVr/WXnN2f03TK/3BfXY7me4cjCAqT8TYXEl0+JBRoqBo94JJHXcyDSLUeWbNX8Fvy5g5RJdAstQ==" | ||
| 709 | + }, | ||
| 497 | "is-date-object": { | 710 | "is-date-object": { |
| 498 | "version": "1.0.2", | 711 | "version": "1.0.2", |
| 499 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", | 712 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", |
| 500 | "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" | 713 | "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" |
| 501 | }, | 714 | }, |
| 715 | + "is-extendable": { | ||
| 716 | + "version": "0.1.1", | ||
| 717 | + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", | ||
| 718 | + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==" | ||
| 719 | + }, | ||
| 502 | "is-generator-function": { | 720 | "is-generator-function": { |
| 503 | "version": "1.0.7", | 721 | "version": "1.0.7", |
| 504 | "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.7.tgz", | 722 | "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.7.tgz", |
| @@ -525,6 +743,26 @@ | @@ -525,6 +743,26 @@ | ||
| 525 | "has-symbols": "^1.0.1" | 743 | "has-symbols": "^1.0.1" |
| 526 | } | 744 | } |
| 527 | }, | 745 | }, |
| 746 | + "is-type-of": { | ||
| 747 | + "version": "1.4.0", | ||
| 748 | + "resolved": "https://registry.npmjs.org/is-type-of/-/is-type-of-1.4.0.tgz", | ||
| 749 | + "integrity": "sha512-EddYllaovi5ysMLMEN7yzHEKh8A850cZ7pykrY1aNRQGn/CDjRDE9qEWbIdt7xGEVJmjBXzU/fNnC4ABTm8tEQ==", | ||
| 750 | + "requires": { | ||
| 751 | + "core-util-is": "^1.0.2", | ||
| 752 | + "is-class-hotfix": "~0.0.6", | ||
| 753 | + "isstream": "~0.1.2" | ||
| 754 | + } | ||
| 755 | + }, | ||
| 756 | + "isarray": { | ||
| 757 | + "version": "1.0.0", | ||
| 758 | + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", | ||
| 759 | + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" | ||
| 760 | + }, | ||
| 761 | + "isstream": { | ||
| 762 | + "version": "0.1.2", | ||
| 763 | + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", | ||
| 764 | + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" | ||
| 765 | + }, | ||
| 528 | "jade": { | 766 | "jade": { |
| 529 | "version": "1.11.0", | 767 | "version": "1.11.0", |
| 530 | "resolved": "https://registry.npmjs.org/jade/-/jade-1.11.0.tgz", | 768 | "resolved": "https://registry.npmjs.org/jade/-/jade-1.11.0.tgz", |
| @@ -542,6 +780,24 @@ | @@ -542,6 +780,24 @@ | ||
| 542 | "with": "~4.0.0" | 780 | "with": "~4.0.0" |
| 543 | } | 781 | } |
| 544 | }, | 782 | }, |
| 783 | + "js-base64": { | ||
| 784 | + "version": "2.6.4", | ||
| 785 | + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", | ||
| 786 | + "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==" | ||
| 787 | + }, | ||
| 788 | + "jsonfile": { | ||
| 789 | + "version": "4.0.0", | ||
| 790 | + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", | ||
| 791 | + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", | ||
| 792 | + "requires": { | ||
| 793 | + "graceful-fs": "^4.1.6" | ||
| 794 | + } | ||
| 795 | + }, | ||
| 796 | + "jstoxml": { | ||
| 797 | + "version": "2.2.9", | ||
| 798 | + "resolved": "https://registry.npmjs.org/jstoxml/-/jstoxml-2.2.9.tgz", | ||
| 799 | + "integrity": "sha512-OYWlK0j+roh+eyaMROlNbS5cd5R25Y+IUpdl7cNdB8HNrkgwQzIS7L9MegxOiWNBj9dQhA/yAxiMwCC5mwNoBw==" | ||
| 800 | + }, | ||
| 545 | "jstransformer": { | 801 | "jstransformer": { |
| 546 | "version": "0.0.2", | 802 | "version": "0.0.2", |
| 547 | "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-0.0.2.tgz", | 803 | "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-0.0.2.tgz", |
| @@ -564,6 +820,38 @@ | @@ -564,6 +820,38 @@ | ||
| 564 | "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", | 820 | "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", |
| 565 | "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" | 821 | "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" |
| 566 | }, | 822 | }, |
| 823 | + "lodash": { | ||
| 824 | + "version": "4.17.21", | ||
| 825 | + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", | ||
| 826 | + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" | ||
| 827 | + }, | ||
| 828 | + "log4js": { | ||
| 829 | + "version": "6.3.0", | ||
| 830 | + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.3.0.tgz", | ||
| 831 | + "integrity": "sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw==", | ||
| 832 | + "requires": { | ||
| 833 | + "date-format": "^3.0.0", | ||
| 834 | + "debug": "^4.1.1", | ||
| 835 | + "flatted": "^2.0.1", | ||
| 836 | + "rfdc": "^1.1.4", | ||
| 837 | + "streamroller": "^2.2.4" | ||
| 838 | + }, | ||
| 839 | + "dependencies": { | ||
| 840 | + "debug": { | ||
| 841 | + "version": "4.3.1", | ||
| 842 | + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", | ||
| 843 | + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", | ||
| 844 | + "requires": { | ||
| 845 | + "ms": "2.1.2" | ||
| 846 | + } | ||
| 847 | + }, | ||
| 848 | + "ms": { | ||
| 849 | + "version": "2.1.2", | ||
| 850 | + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", | ||
| 851 | + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" | ||
| 852 | + } | ||
| 853 | + } | ||
| 854 | + }, | ||
| 567 | "longest": { | 855 | "longest": { |
| 568 | "version": "1.0.1", | 856 | "version": "1.0.1", |
| 569 | "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", | 857 | "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", |
| @@ -640,11 +928,31 @@ | @@ -640,11 +928,31 @@ | ||
| 640 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", | 928 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", |
| 641 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" | 929 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" |
| 642 | }, | 930 | }, |
| 931 | + "mz": { | ||
| 932 | + "version": "2.7.0", | ||
| 933 | + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", | ||
| 934 | + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", | ||
| 935 | + "requires": { | ||
| 936 | + "any-promise": "^1.0.0", | ||
| 937 | + "object-assign": "^4.0.1", | ||
| 938 | + "thenify-all": "^1.0.0" | ||
| 939 | + } | ||
| 940 | + }, | ||
| 643 | "negotiator": { | 941 | "negotiator": { |
| 644 | "version": "0.6.2", | 942 | "version": "0.6.2", |
| 645 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", | 943 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", |
| 646 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" | 944 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" |
| 647 | }, | 945 | }, |
| 946 | + "node-hex": { | ||
| 947 | + "version": "1.0.1", | ||
| 948 | + "resolved": "https://registry.npmjs.org/node-hex/-/node-hex-1.0.1.tgz", | ||
| 949 | + "integrity": "sha512-iwpZdvW6Umz12ICmu9IYPRxg0tOLGmU3Tq2tKetejCj3oZd7b2nUXwP3a7QA5M9glWy8wlPS1G3RwM/CdsUbdQ==" | ||
| 950 | + }, | ||
| 951 | + "object-assign": { | ||
| 952 | + "version": "4.1.1", | ||
| 953 | + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", | ||
| 954 | + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" | ||
| 955 | + }, | ||
| 648 | "object-inspect": { | 956 | "object-inspect": { |
| 649 | "version": "1.7.0", | 957 | "version": "1.7.0", |
| 650 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", | 958 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", |
| @@ -706,6 +1014,30 @@ | @@ -706,6 +1014,30 @@ | ||
| 706 | "wordwrap": "~0.0.2" | 1014 | "wordwrap": "~0.0.2" |
| 707 | } | 1015 | } |
| 708 | }, | 1016 | }, |
| 1017 | + "os-name": { | ||
| 1018 | + "version": "1.0.3", | ||
| 1019 | + "resolved": "https://registry.npmjs.org/os-name/-/os-name-1.0.3.tgz", | ||
| 1020 | + "integrity": "sha512-f5estLO2KN8vgtTRaILIgEGBoBrMnZ3JQ7W9TMZCnOIGwHe8TRGSpcagnWDo+Dfhd/z08k9Xe75hvciJJ8Qaew==", | ||
| 1021 | + "requires": { | ||
| 1022 | + "osx-release": "^1.0.0", | ||
| 1023 | + "win-release": "^1.0.0" | ||
| 1024 | + } | ||
| 1025 | + }, | ||
| 1026 | + "osx-release": { | ||
| 1027 | + "version": "1.1.0", | ||
| 1028 | + "resolved": "https://registry.npmjs.org/osx-release/-/osx-release-1.1.0.tgz", | ||
| 1029 | + "integrity": "sha512-ixCMMwnVxyHFQLQnINhmIpWqXIfS2YOXchwQrk+OFzmo6nDjQ0E4KXAyyUh0T0MZgV4bUhkRrAbVqlE4yLVq4A==", | ||
| 1030 | + "requires": { | ||
| 1031 | + "minimist": "^1.1.0" | ||
| 1032 | + }, | ||
| 1033 | + "dependencies": { | ||
| 1034 | + "minimist": { | ||
| 1035 | + "version": "1.2.8", | ||
| 1036 | + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", | ||
| 1037 | + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" | ||
| 1038 | + } | ||
| 1039 | + } | ||
| 1040 | + }, | ||
| 709 | "parseurl": { | 1041 | "parseurl": { |
| 710 | "version": "1.3.3", | 1042 | "version": "1.3.3", |
| 711 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", | 1043 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", |
| @@ -726,6 +1058,24 @@ | @@ -726,6 +1058,24 @@ | ||
| 726 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", | 1058 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", |
| 727 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" | 1059 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" |
| 728 | }, | 1060 | }, |
| 1061 | + "pause-stream": { | ||
| 1062 | + "version": "0.0.11", | ||
| 1063 | + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", | ||
| 1064 | + "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", | ||
| 1065 | + "requires": { | ||
| 1066 | + "through": "~2.3" | ||
| 1067 | + } | ||
| 1068 | + }, | ||
| 1069 | + "platform": { | ||
| 1070 | + "version": "1.3.6", | ||
| 1071 | + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", | ||
| 1072 | + "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==" | ||
| 1073 | + }, | ||
| 1074 | + "process-nextick-args": { | ||
| 1075 | + "version": "2.0.1", | ||
| 1076 | + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", | ||
| 1077 | + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" | ||
| 1078 | + }, | ||
| 729 | "promise": { | 1079 | "promise": { |
| 730 | "version": "6.1.0", | 1080 | "version": "6.1.0", |
| 731 | "resolved": "https://registry.npmjs.org/promise/-/promise-6.1.0.tgz", | 1081 | "resolved": "https://registry.npmjs.org/promise/-/promise-6.1.0.tgz", |
| @@ -743,6 +1093,15 @@ | @@ -743,6 +1093,15 @@ | ||
| 743 | "ipaddr.js": "1.9.0" | 1093 | "ipaddr.js": "1.9.0" |
| 744 | } | 1094 | } |
| 745 | }, | 1095 | }, |
| 1096 | + "pump": { | ||
| 1097 | + "version": "3.0.2", | ||
| 1098 | + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", | ||
| 1099 | + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", | ||
| 1100 | + "requires": { | ||
| 1101 | + "end-of-stream": "^1.1.0", | ||
| 1102 | + "once": "^1.3.1" | ||
| 1103 | + } | ||
| 1104 | + }, | ||
| 746 | "qs": { | 1105 | "qs": { |
| 747 | "version": "6.5.2", | 1106 | "version": "6.5.2", |
| 748 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", | 1107 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", |
| @@ -764,6 +1123,20 @@ | @@ -764,6 +1123,20 @@ | ||
| 764 | "unpipe": "1.0.0" | 1123 | "unpipe": "1.0.0" |
| 765 | } | 1124 | } |
| 766 | }, | 1125 | }, |
| 1126 | + "readable-stream": { | ||
| 1127 | + "version": "2.3.8", | ||
| 1128 | + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", | ||
| 1129 | + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", | ||
| 1130 | + "requires": { | ||
| 1131 | + "core-util-is": "~1.0.0", | ||
| 1132 | + "inherits": "~2.0.3", | ||
| 1133 | + "isarray": "~1.0.0", | ||
| 1134 | + "process-nextick-args": "~2.0.0", | ||
| 1135 | + "safe-buffer": "~5.1.1", | ||
| 1136 | + "string_decoder": "~1.1.1", | ||
| 1137 | + "util-deprecate": "~1.0.1" | ||
| 1138 | + } | ||
| 1139 | + }, | ||
| 767 | "rechoir": { | 1140 | "rechoir": { |
| 768 | "version": "0.6.2", | 1141 | "version": "0.6.2", |
| 769 | "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", | 1142 | "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", |
| @@ -785,6 +1158,11 @@ | @@ -785,6 +1158,11 @@ | ||
| 785 | "path-parse": "^1.0.6" | 1158 | "path-parse": "^1.0.6" |
| 786 | } | 1159 | } |
| 787 | }, | 1160 | }, |
| 1161 | + "rfdc": { | ||
| 1162 | + "version": "1.2.0", | ||
| 1163 | + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.2.0.tgz", | ||
| 1164 | + "integrity": "sha512-ijLyszTMmUrXvjSooucVQwimGUk84eRcmCuLV8Xghe3UO85mjUtRAHRyoMM6XtyqbECaXuBWx18La3523sXINA==" | ||
| 1165 | + }, | ||
| 788 | "right-align": { | 1166 | "right-align": { |
| 789 | "version": "0.1.3", | 1167 | "version": "0.1.3", |
| 790 | "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", | 1168 | "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", |
| @@ -803,6 +1181,24 @@ | @@ -803,6 +1181,24 @@ | ||
| 803 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", | 1181 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", |
| 804 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" | 1182 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" |
| 805 | }, | 1183 | }, |
| 1184 | + "sax": { | ||
| 1185 | + "version": "1.2.4", | ||
| 1186 | + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", | ||
| 1187 | + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" | ||
| 1188 | + }, | ||
| 1189 | + "sdk-base": { | ||
| 1190 | + "version": "2.0.1", | ||
| 1191 | + "resolved": "https://registry.npmjs.org/sdk-base/-/sdk-base-2.0.1.tgz", | ||
| 1192 | + "integrity": "sha512-eeG26wRwhtwYuKGCDM3LixCaxY27Pa/5lK4rLKhQa7HBjJ3U3Y+f81MMZQRsDw/8SC2Dao/83yJTXJ8aULuN8Q==", | ||
| 1193 | + "requires": { | ||
| 1194 | + "get-ready": "~1.0.0" | ||
| 1195 | + } | ||
| 1196 | + }, | ||
| 1197 | + "semver": { | ||
| 1198 | + "version": "5.7.2", | ||
| 1199 | + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", | ||
| 1200 | + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==" | ||
| 1201 | + }, | ||
| 806 | "send": { | 1202 | "send": { |
| 807 | "version": "0.16.2", | 1203 | "version": "0.16.2", |
| 808 | "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", | 1204 | "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", |
| @@ -862,6 +1258,53 @@ | @@ -862,6 +1258,53 @@ | ||
| 862 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", | 1258 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", |
| 863 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" | 1259 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" |
| 864 | }, | 1260 | }, |
| 1261 | + "stream-http": { | ||
| 1262 | + "version": "2.8.2", | ||
| 1263 | + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.2.tgz", | ||
| 1264 | + "integrity": "sha512-QllfrBhqF1DPcz46WxKTs6Mz1Bpc+8Qm6vbqOpVav5odAXwbyzwnEczoWqtxrsmlO+cJqtPrp/8gWKWjaKLLlA==", | ||
| 1265 | + "requires": { | ||
| 1266 | + "builtin-status-codes": "^3.0.0", | ||
| 1267 | + "inherits": "^2.0.1", | ||
| 1268 | + "readable-stream": "^2.3.6", | ||
| 1269 | + "to-arraybuffer": "^1.0.0", | ||
| 1270 | + "xtend": "^4.0.0" | ||
| 1271 | + } | ||
| 1272 | + }, | ||
| 1273 | + "stream-wormhole": { | ||
| 1274 | + "version": "1.1.0", | ||
| 1275 | + "resolved": "https://registry.npmjs.org/stream-wormhole/-/stream-wormhole-1.1.0.tgz", | ||
| 1276 | + "integrity": "sha512-gHFfL3px0Kctd6Po0M8TzEvt3De/xu6cnRrjlfYNhwbhLPLwigI2t1nc6jrzNuaYg5C4YF78PPFuQPzRiqn9ew==" | ||
| 1277 | + }, | ||
| 1278 | + "streamroller": { | ||
| 1279 | + "version": "2.2.4", | ||
| 1280 | + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-2.2.4.tgz", | ||
| 1281 | + "integrity": "sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ==", | ||
| 1282 | + "requires": { | ||
| 1283 | + "date-format": "^2.1.0", | ||
| 1284 | + "debug": "^4.1.1", | ||
| 1285 | + "fs-extra": "^8.1.0" | ||
| 1286 | + }, | ||
| 1287 | + "dependencies": { | ||
| 1288 | + "date-format": { | ||
| 1289 | + "version": "2.1.0", | ||
| 1290 | + "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz", | ||
| 1291 | + "integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==" | ||
| 1292 | + }, | ||
| 1293 | + "debug": { | ||
| 1294 | + "version": "4.3.1", | ||
| 1295 | + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", | ||
| 1296 | + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", | ||
| 1297 | + "requires": { | ||
| 1298 | + "ms": "2.1.2" | ||
| 1299 | + } | ||
| 1300 | + }, | ||
| 1301 | + "ms": { | ||
| 1302 | + "version": "2.1.2", | ||
| 1303 | + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", | ||
| 1304 | + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" | ||
| 1305 | + } | ||
| 1306 | + } | ||
| 1307 | + }, | ||
| 865 | "string.prototype.trimleft": { | 1308 | "string.prototype.trimleft": { |
| 866 | "version": "2.1.1", | 1309 | "version": "2.1.1", |
| 867 | "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", | 1310 | "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", |
| @@ -880,6 +1323,40 @@ | @@ -880,6 +1323,40 @@ | ||
| 880 | "function-bind": "^1.1.1" | 1323 | "function-bind": "^1.1.1" |
| 881 | } | 1324 | } |
| 882 | }, | 1325 | }, |
| 1326 | + "string_decoder": { | ||
| 1327 | + "version": "1.1.1", | ||
| 1328 | + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", | ||
| 1329 | + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", | ||
| 1330 | + "requires": { | ||
| 1331 | + "safe-buffer": "~5.1.0" | ||
| 1332 | + } | ||
| 1333 | + }, | ||
| 1334 | + "thenify": { | ||
| 1335 | + "version": "3.3.1", | ||
| 1336 | + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", | ||
| 1337 | + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", | ||
| 1338 | + "requires": { | ||
| 1339 | + "any-promise": "^1.0.0" | ||
| 1340 | + } | ||
| 1341 | + }, | ||
| 1342 | + "thenify-all": { | ||
| 1343 | + "version": "1.6.0", | ||
| 1344 | + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", | ||
| 1345 | + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", | ||
| 1346 | + "requires": { | ||
| 1347 | + "thenify": ">= 3.1.0 < 4" | ||
| 1348 | + } | ||
| 1349 | + }, | ||
| 1350 | + "through": { | ||
| 1351 | + "version": "2.3.8", | ||
| 1352 | + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", | ||
| 1353 | + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" | ||
| 1354 | + }, | ||
| 1355 | + "to-arraybuffer": { | ||
| 1356 | + "version": "1.0.1", | ||
| 1357 | + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", | ||
| 1358 | + "integrity": "sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==" | ||
| 1359 | + }, | ||
| 883 | "transformers": { | 1360 | "transformers": { |
| 884 | "version": "2.1.0", | 1361 | "version": "2.1.0", |
| 885 | "resolved": "https://registry.npmjs.org/transformers/-/transformers-2.1.0.tgz", | 1362 | "resolved": "https://registry.npmjs.org/transformers/-/transformers-2.1.0.tgz", |
| @@ -954,11 +1431,53 @@ | @@ -954,11 +1431,53 @@ | ||
| 954 | "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", | 1431 | "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", |
| 955 | "optional": true | 1432 | "optional": true |
| 956 | }, | 1433 | }, |
| 1434 | + "unescape": { | ||
| 1435 | + "version": "1.0.1", | ||
| 1436 | + "resolved": "https://registry.npmjs.org/unescape/-/unescape-1.0.1.tgz", | ||
| 1437 | + "integrity": "sha512-O0+af1Gs50lyH1nUu3ZyYS1cRh01Q/kUKatTOkSs7jukXE6/NebucDVxyiDsA9AQ4JC1V1jUH9EO8JX2nMDgGQ==", | ||
| 1438 | + "requires": { | ||
| 1439 | + "extend-shallow": "^2.0.1" | ||
| 1440 | + } | ||
| 1441 | + }, | ||
| 1442 | + "universalify": { | ||
| 1443 | + "version": "0.1.2", | ||
| 1444 | + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", | ||
| 1445 | + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" | ||
| 1446 | + }, | ||
| 957 | "unpipe": { | 1447 | "unpipe": { |
| 958 | "version": "1.0.0", | 1448 | "version": "1.0.0", |
| 959 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", | 1449 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", |
| 960 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" | 1450 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" |
| 961 | }, | 1451 | }, |
| 1452 | + "urllib": { | ||
| 1453 | + "version": "2.44.0", | ||
| 1454 | + "resolved": "https://registry.npmjs.org/urllib/-/urllib-2.44.0.tgz", | ||
| 1455 | + "integrity": "sha512-zRCJqdfYllRDA9bXUtx+vccyRqtJPKsw85f44zH7zPD28PIvjMqIgw9VwoTLV7xTBWZsbebUFVHU5ghQcWku2A==", | ||
| 1456 | + "requires": { | ||
| 1457 | + "any-promise": "^1.3.0", | ||
| 1458 | + "content-type": "^1.0.2", | ||
| 1459 | + "default-user-agent": "^1.0.0", | ||
| 1460 | + "digest-header": "^1.0.0", | ||
| 1461 | + "ee-first": "~1.1.1", | ||
| 1462 | + "formstream": "^1.1.0", | ||
| 1463 | + "humanize-ms": "^1.2.0", | ||
| 1464 | + "iconv-lite": "^0.6.3", | ||
| 1465 | + "pump": "^3.0.0", | ||
| 1466 | + "qs": "^6.4.0", | ||
| 1467 | + "statuses": "^1.3.1", | ||
| 1468 | + "utility": "^1.16.1" | ||
| 1469 | + }, | ||
| 1470 | + "dependencies": { | ||
| 1471 | + "iconv-lite": { | ||
| 1472 | + "version": "0.6.3", | ||
| 1473 | + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", | ||
| 1474 | + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", | ||
| 1475 | + "requires": { | ||
| 1476 | + "safer-buffer": ">= 2.1.2 < 3.0.0" | ||
| 1477 | + } | ||
| 1478 | + } | ||
| 1479 | + } | ||
| 1480 | + }, | ||
| 962 | "util": { | 1481 | "util": { |
| 963 | "version": "0.12.1", | 1482 | "version": "0.12.1", |
| 964 | "resolved": "https://registry.npmjs.org/util/-/util-0.12.1.tgz", | 1483 | "resolved": "https://registry.npmjs.org/util/-/util-0.12.1.tgz", |
| @@ -971,6 +1490,23 @@ | @@ -971,6 +1490,23 @@ | ||
| 971 | "safe-buffer": "^5.1.2" | 1490 | "safe-buffer": "^5.1.2" |
| 972 | } | 1491 | } |
| 973 | }, | 1492 | }, |
| 1493 | + "util-deprecate": { | ||
| 1494 | + "version": "1.0.2", | ||
| 1495 | + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", | ||
| 1496 | + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" | ||
| 1497 | + }, | ||
| 1498 | + "utility": { | ||
| 1499 | + "version": "1.18.0", | ||
| 1500 | + "resolved": "https://registry.npmjs.org/utility/-/utility-1.18.0.tgz", | ||
| 1501 | + "integrity": "sha512-PYxZDA+6QtvRvm//++aGdmKG/cI07jNwbROz0Ql+VzFV1+Z0Dy55NI4zZ7RHc9KKpBePNFwoErqIuqQv/cjiTA==", | ||
| 1502 | + "requires": { | ||
| 1503 | + "copy-to": "^2.0.1", | ||
| 1504 | + "escape-html": "^1.0.3", | ||
| 1505 | + "mkdirp": "^0.5.1", | ||
| 1506 | + "mz": "^2.7.0", | ||
| 1507 | + "unescape": "^1.0.1" | ||
| 1508 | + } | ||
| 1509 | + }, | ||
| 974 | "utils-merge": { | 1510 | "utils-merge": { |
| 975 | "version": "1.0.1", | 1511 | "version": "1.0.1", |
| 976 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", | 1512 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", |
| @@ -986,6 +1522,14 @@ | @@ -986,6 +1522,14 @@ | ||
| 986 | "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", | 1522 | "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", |
| 987 | "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=" | 1523 | "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=" |
| 988 | }, | 1524 | }, |
| 1525 | + "win-release": { | ||
| 1526 | + "version": "1.1.1", | ||
| 1527 | + "resolved": "https://registry.npmjs.org/win-release/-/win-release-1.1.1.tgz", | ||
| 1528 | + "integrity": "sha512-iCRnKVvGxOQdsKhcQId2PXV1vV3J/sDPXKA4Oe9+Eti2nb2ESEsYHRYls/UjoUW3bIc5ZDO8dTH50A/5iVN+bw==", | ||
| 1529 | + "requires": { | ||
| 1530 | + "semver": "^5.0.1" | ||
| 1531 | + } | ||
| 1532 | + }, | ||
| 989 | "window-size": { | 1533 | "window-size": { |
| 990 | "version": "0.1.0", | 1534 | "version": "0.1.0", |
| 991 | "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", | 1535 | "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", |
| @@ -1017,6 +1561,25 @@ | @@ -1017,6 +1561,25 @@ | ||
| 1017 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", | 1561 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", |
| 1018 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" | 1562 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" |
| 1019 | }, | 1563 | }, |
| 1564 | + "xml2js": { | ||
| 1565 | + "version": "0.4.23", | ||
| 1566 | + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", | ||
| 1567 | + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", | ||
| 1568 | + "requires": { | ||
| 1569 | + "sax": ">=0.6.0", | ||
| 1570 | + "xmlbuilder": "~11.0.0" | ||
| 1571 | + } | ||
| 1572 | + }, | ||
| 1573 | + "xmlbuilder": { | ||
| 1574 | + "version": "11.0.1", | ||
| 1575 | + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", | ||
| 1576 | + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" | ||
| 1577 | + }, | ||
| 1578 | + "xtend": { | ||
| 1579 | + "version": "4.0.2", | ||
| 1580 | + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", | ||
| 1581 | + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" | ||
| 1582 | + }, | ||
| 1020 | "yargs": { | 1583 | "yargs": { |
| 1021 | "version": "3.10.0", | 1584 | "version": "3.10.0", |
| 1022 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", | 1585 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", |
package.json
100755 → 100644
| @@ -3,14 +3,17 @@ | @@ -3,14 +3,17 @@ | ||
| 3 | "version": "0.0.0", | 3 | "version": "0.0.0", |
| 4 | "private": true, | 4 | "private": true, |
| 5 | "scripts": { | 5 | "scripts": { |
| 6 | - "start": "nodemon ./bin/www", | 6 | + "start": "node ./bin/www", |
| 7 | "pm2": "pm2 start ./bin/www --name webScreen" | 7 | "pm2": "pm2 start ./bin/www --name webScreen" |
| 8 | }, | 8 | }, |
| 9 | "dependencies": { | 9 | "dependencies": { |
| 10 | + "ali-oss": "^6.22.0", | ||
| 10 | "axios": "^0.19.0", | 11 | "axios": "^0.19.0", |
| 11 | "child_process": "^1.0.2", | 12 | "child_process": "^1.0.2", |
| 12 | "cookie-parser": "~1.4.4", | 13 | "cookie-parser": "~1.4.4", |
| 13 | "debug": "~2.6.9", | 14 | "debug": "~2.6.9", |
| 15 | + "dotenv": "^16.4.7", | ||
| 16 | + "esdk-obs-nodejs": "^3.20.11", | ||
| 14 | "express": "~4.16.1", | 17 | "express": "~4.16.1", |
| 15 | "http-errors": "~1.6.3", | 18 | "http-errors": "~1.6.3", |
| 16 | "jade": "~1.11.0", | 19 | "jade": "~1.11.0", |
public/stylesheets/style.css
100755 → 100644
routes/bbgRecording.js
0 → 100644
| 1 | +var express = require('express'); | ||
| 2 | +var router = express.Router(); | ||
| 3 | +const { exec } = require('child_process'); | ||
| 4 | +const fs = require("fs"); | ||
| 5 | +const axios = require('axios'); | ||
| 6 | + | ||
| 7 | +const method = require("../config/method") | ||
| 8 | + | ||
| 9 | +const { dayTimeYMD } = method | ||
| 10 | + | ||
| 11 | + | ||
| 12 | +let classids = [] | ||
| 13 | + | ||
| 14 | +/** | ||
| 15 | + * | ||
| 16 | + * @param {*} id 课堂id | ||
| 17 | + */ | ||
| 18 | +class MediaCreat { | ||
| 19 | + constructor() { | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + wrieLog(text) { | ||
| 23 | + // 写入log | ||
| 24 | + let logFile = `./log/${dayTimeYMD().ymd}.txt` | ||
| 25 | + fs.appendFileSync(logFile, new Date().toLocaleString() + " " + text + '\r\n'); | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + recordingCreat(id,siteId,classUrl,duration,width,height,frameRate,bitrate) { | ||
| 29 | + this.wrieLog(" 课堂录制开始:------>" + id) | ||
| 30 | + let fileConfig = this.getConfigFileJson() | ||
| 31 | + if (!fileConfig) return false | ||
| 32 | + const { BACKMEDIACONFIG, PROJECTWINCATALOG, PROJECTCATALOG } = JSON.parse(fileConfig) | ||
| 33 | + // let mediaDir = PROJECTCATALOG + "/media/" | ||
| 34 | + // let classDir = PROJECTCATALOG + "/media/" + siteId | ||
| 35 | + // let ymdDir = null | ||
| 36 | + // let timeDir = dayTimeYMD().ymd | ||
| 37 | + // ymdDir = PROJECTCATALOG + "/media/" + siteId + "/" + timeDir | ||
| 38 | + | ||
| 39 | + | ||
| 40 | + let classDir = PROJECTCATALOG + "/" + siteId | ||
| 41 | + let ymdDir = null | ||
| 42 | + let timeDir = dayTimeYMD().ymd | ||
| 43 | + ymdDir = PROJECTCATALOG + "/" + siteId + "/" + timeDir | ||
| 44 | + | ||
| 45 | + | ||
| 46 | + if (!fs.existsSync(classDir)) { | ||
| 47 | + fs.mkdirSync(classDir); | ||
| 48 | + } | ||
| 49 | + if (!fs.existsSync(ymdDir)) { | ||
| 50 | + fs.mkdirSync(ymdDir); | ||
| 51 | + } | ||
| 52 | + // let files = fs.readdirSync(ymdDir); | ||
| 53 | + // let interValGetFile = setInterval(()=>{ | ||
| 54 | + // this.wrieLog("files:" + files) | ||
| 55 | + // if (files.indexOf(id + ".mp4") != -1) { | ||
| 56 | + // this.wrieLog("已存在:" + id + "课堂号,停止继续录制") | ||
| 57 | + // return | ||
| 58 | + // } | ||
| 59 | + | ||
| 60 | + // if(!classUrl){ | ||
| 61 | + // 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}"` | ||
| 62 | + // } | ||
| 63 | + // if(!duration){ | ||
| 64 | + // duration = BACKMEDIACONFIG.d | ||
| 65 | + // } | ||
| 66 | + 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}` | ||
| 67 | + this.wrieLog("全地址"+url) | ||
| 68 | + exec(url, { maxBuffer: 1073741824 }, (err, stdout, stderr) => { | ||
| 69 | + if (err != null) { | ||
| 70 | + this.wrieLog(" 错误" + id + ":" + err) | ||
| 71 | + this.wrieLog(" 错误 stdout" + id + ":" + stdout) | ||
| 72 | + this.wrieLog(" 错误 stderr" + id + ":" + stderr) | ||
| 73 | + // 删除已存元素 | ||
| 74 | + classids.splice(classids.findIndex(item => item === id),1) | ||
| 75 | + return | ||
| 76 | + } | ||
| 77 | + // let files = fs.readdirSync(ymdDir); | ||
| 78 | + // if (files.indexOf(id + ".mp4") != -1) { | ||
| 79 | + // 删除已存元素 | ||
| 80 | + classids.splice(classids.findIndex(item => item === id),1) | ||
| 81 | + this.sendMediaInfo(siteId,id,timeDir) | ||
| 82 | + // } | ||
| 83 | + }) | ||
| 84 | + } | ||
| 85 | + // 上报地址 | ||
| 86 | + async sendMediaInfo(siteId,id,timeDir){ | ||
| 87 | + // https://mp4record.obs.cn-north-4.myhuaweicloud.com/oss/media/eebbktest/20210326/1657547103.mp4 | ||
| 88 | + // let MediaUrl = `https://mp4record.obs.cn-north-4.myhuaweicloud.com/oss/media/${siteId}/${timeDir}/${id}.mp4` | ||
| 89 | + let MediaUrl = `https://mp4record.obs.cn-north-4.myhuaweicloud.com/oss/${siteId}/${timeDir}/${id}.mp4` | ||
| 90 | + let urlSizeId = { | ||
| 91 | + "eebbktest": "gdbbkwxyace", | ||
| 92 | + "gdbbk":"gdbbkwx", | ||
| 93 | + "gdbbkdev":"gdbbkwxtest" | ||
| 94 | + } | ||
| 95 | + let requestUrl = `https://${urlSizeId[siteId]}.xuedianyun.com/bbgserver/app/course/updateRecordUrl` | ||
| 96 | + let result = await axios.post( | ||
| 97 | + requestUrl, | ||
| 98 | + {meetingNumber:id,url:MediaUrl}, | ||
| 99 | + {headers: {'orgId':siteId }} | ||
| 100 | + ) | ||
| 101 | + if(result.data){ | ||
| 102 | + this.wrieLog("更新视频地址结果:"+JSON.stringify(result.data)) | ||
| 103 | + } | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + getConfigFileJson() { | ||
| 107 | + const buffer = fs.readFileSync(process.cwd() + "/config/realTimeConfig.json") | ||
| 108 | + return String(buffer) | ||
| 109 | + } | ||
| 110 | +} | ||
| 111 | + | ||
| 112 | +/** | ||
| 113 | + * { | ||
| 114 | + * "classId":[{ classId: '389675110', siteId: 'kuaikuenglish' }] | ||
| 115 | + * } | ||
| 116 | + */ | ||
| 117 | +router.post('/recording/:id', function (req, res, next) { | ||
| 118 | + new MediaCreat().wrieLog("录制启动:------>") | ||
| 119 | + let fileConfig = new MediaCreat().getConfigFileJson() | ||
| 120 | + if (!fileConfig) return false | ||
| 121 | + /** | ||
| 122 | + * classId:课堂号 | ||
| 123 | + * siteId:机构编码 | ||
| 124 | + * url:课堂地址 | ||
| 125 | + * duration:录制时长 | ||
| 126 | + * width height 录制视频宽高 | ||
| 127 | + * frameRate 帧率 | ||
| 128 | + * bitrate 码率 | ||
| 129 | + */ | ||
| 130 | + let { classId,siteId,url:classUrl,duration,width,height,frameRate,bitrate } = req.body | ||
| 131 | + | ||
| 132 | + if (classId && siteId && classUrl && duration && width && height && frameRate && bitrate) { | ||
| 133 | + if(!Number.isInteger(classId) || !Number.isInteger(duration) || !Number.isInteger(width) || !Number.isInteger(height) || !Number.isInteger(frameRate) || !Number.isInteger(bitrate)){ | ||
| 134 | + res.send({ code: "3", message: "参数类型错误" }); | ||
| 135 | + return | ||
| 136 | + } | ||
| 137 | + let maxTime = 10*60*60*1000 | ||
| 138 | + if(duration < 0 || duration > maxTime){ | ||
| 139 | + res.send({ code: "4", message: "参数范围错误" }); | ||
| 140 | + return | ||
| 141 | + } | ||
| 142 | + // 避免多次重复课堂号请求 | ||
| 143 | + if(!classids.includes(classId)){ | ||
| 144 | + // 没有正在录制的该课堂 | ||
| 145 | + classids.push(classId) | ||
| 146 | + bitrate = bitrate * 1024 // 转换 * 1024 | ||
| 147 | + new MediaCreat().recordingCreat(classId, siteId,classUrl,duration,width,height,frameRate,bitrate) | ||
| 148 | + res.send({ code: "0" }); | ||
| 149 | + }else{ | ||
| 150 | + res.send({ code: "2", message: "重复请求课堂号" }); | ||
| 151 | + } | ||
| 152 | + } else { | ||
| 153 | + res.send({ code: "1", message: "缺少参数" }); | ||
| 154 | + } | ||
| 155 | + | ||
| 156 | +}) | ||
| 157 | + | ||
| 158 | + | ||
| 159 | +module.exports = router; |
routes/bbgRecording_1.js
0 → 100644
| 1 | +var express = require('express'); | ||
| 2 | +var router = express.Router(); | ||
| 3 | +const { exec } = require('child_process'); | ||
| 4 | +const fs = require("fs"); | ||
| 5 | +const axios = require('axios'); | ||
| 6 | +const method = require("../config/method") | ||
| 7 | + | ||
| 8 | +const { dayTimeYMD } = method | ||
| 9 | + | ||
| 10 | + | ||
| 11 | +let classids = [] | ||
| 12 | + | ||
| 13 | +/** | ||
| 14 | + * | ||
| 15 | + * @param {*} id 课堂id | ||
| 16 | + */ | ||
| 17 | +class MediaCreat { | ||
| 18 | + constructor() { | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | + wrieLog(text) { | ||
| 22 | + // 写入log | ||
| 23 | + let logFile = `./log/${dayTimeYMD().ymd}.txt` | ||
| 24 | + fs.appendFileSync(logFile, new Date().toLocaleString() + " " + text + '\r\n'); | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + recordingCreat(id,siteId,classUrl,duration,width,height,frameRate,bitrate) { | ||
| 28 | + this.wrieLog(" 课堂录制开始:------>" + id) | ||
| 29 | + let fileConfig = this.getConfigFileJson() | ||
| 30 | + if (!fileConfig) return false | ||
| 31 | + const { BACKMEDIACONFIG, PROJECTWINCATALOG, PROJECTCATALOG } = JSON.parse(fileConfig) | ||
| 32 | + let mediaDir = PROJECTCATALOG + "/media/" | ||
| 33 | + let classDir = PROJECTCATALOG + "/media/" + siteId | ||
| 34 | + let ymdDir = null | ||
| 35 | + let timeDir = dayTimeYMD().ymd | ||
| 36 | + ymdDir = PROJECTCATALOG + "/media/" + siteId + "/" + timeDir | ||
| 37 | + if (!fs.existsSync(mediaDir)) { | ||
| 38 | + fs.mkdirSync(mediaDir); | ||
| 39 | + } | ||
| 40 | + if (!fs.existsSync(classDir)) { | ||
| 41 | + fs.mkdirSync(classDir); | ||
| 42 | + } | ||
| 43 | + if (!fs.existsSync(ymdDir)) { | ||
| 44 | + fs.mkdirSync(ymdDir); | ||
| 45 | + } | ||
| 46 | + let files = fs.readdirSync(ymdDir); | ||
| 47 | + // let interValGetFile = setInterval(()=>{ | ||
| 48 | + this.wrieLog("files:" + files) | ||
| 49 | + if (files.indexOf(id + ".mp4") != -1) { | ||
| 50 | + this.wrieLog("已存在:" + id + "课堂号,停止继续录制") | ||
| 51 | + return | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + // if(!classUrl){ | ||
| 55 | + // 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}"` | ||
| 56 | + // } | ||
| 57 | + // if(!duration){ | ||
| 58 | + // duration = BACKMEDIACONFIG.d | ||
| 59 | + // } | ||
| 60 | + 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}` | ||
| 61 | + this.wrieLog("测试全地址"+url) | ||
| 62 | + exec(url, { maxBuffer: 1073741824 }, (err, stdout, stderr) => { | ||
| 63 | + if (err != null) { | ||
| 64 | + this.wrieLog(" 错误" + id + ":" + err) | ||
| 65 | + this.wrieLog(" 错误 stdout" + id + ":" + stdout) | ||
| 66 | + this.wrieLog(" 错误 stderr" + id + ":" + stderr) | ||
| 67 | + // 删除已存元素 | ||
| 68 | + classids.splice(classids.findIndex(item => item === id),1) | ||
| 69 | + return | ||
| 70 | + } | ||
| 71 | + let files = fs.readdirSync(ymdDir); | ||
| 72 | + if (files.indexOf(id + ".mp4") != -1) { | ||
| 73 | + this.wrieLog(" 录制完成 课堂号:" + id) | ||
| 74 | + // 删除已存元素 | ||
| 75 | + classids.splice(classids.findIndex(item => item === id),1) | ||
| 76 | + } | ||
| 77 | + }) | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + getConfigFileJson() { | ||
| 81 | + const buffer = fs.readFileSync(process.cwd() + "/config/realTimeConfig.json") | ||
| 82 | + return String(buffer) | ||
| 83 | + } | ||
| 84 | +} | ||
| 85 | + | ||
| 86 | +/** | ||
| 87 | + * { | ||
| 88 | + * "classId":[{ classId: '389675110', siteId: 'kuaikuenglish' }] | ||
| 89 | + * } | ||
| 90 | + */ | ||
| 91 | +router.post('/recording', function (req, res, next) { | ||
| 92 | + new MediaCreat().wrieLog("录制启动:------>") | ||
| 93 | + let fileConfig = new MediaCreat().getConfigFileJson() | ||
| 94 | + if (!fileConfig) return false | ||
| 95 | + /** | ||
| 96 | + * classId:课堂号 | ||
| 97 | + * siteId:机构编码 | ||
| 98 | + * url:课堂地址 | ||
| 99 | + * duration:录制时长 | ||
| 100 | + * width height 录制视频宽高 | ||
| 101 | + * frameRate 帧率 | ||
| 102 | + * bitrate 码率 | ||
| 103 | + */ | ||
| 104 | + let { classId,siteId,url:classUrl,duration,width,height,frameRate,bitrate } = req.body | ||
| 105 | + | ||
| 106 | + if (classId && siteId && classUrl && duration && width && height && frameRate && bitrate) { | ||
| 107 | + if(!Number.isInteger(classId) || !Number.isInteger(duration) || !Number.isInteger(width) || !Number.isInteger(height) || !Number.isInteger(frameRate) || !Number.isInteger(bitrate)){ | ||
| 108 | + res.send({ code: "1", message: "参数类型错误" }); | ||
| 109 | + return | ||
| 110 | + } | ||
| 111 | + let maxTime = 10*60*60*1000 | ||
| 112 | + if(duration < 0 || duration > maxTime){ | ||
| 113 | + res.send({ code: "1", message: "参数范围错误" }); | ||
| 114 | + return | ||
| 115 | + } | ||
| 116 | + // 避免多次重复课堂号请求 | ||
| 117 | + if(!classids.includes(classId)){ | ||
| 118 | + // 没有正在录制的该课堂 | ||
| 119 | + classids.push(classId) | ||
| 120 | + bitrate = bitrate * 1024 // 转换 * 1024 | ||
| 121 | + new MediaCreat().recordingCreat(classId, siteId,classUrl,duration,width,height,frameRate,bitrate) | ||
| 122 | + res.send({ code: "0" }); | ||
| 123 | + }else{ | ||
| 124 | + res.send({ code: "2", message: "重复请求课堂号" }); | ||
| 125 | + } | ||
| 126 | + } else { | ||
| 127 | + res.send({ code: "1", message: "缺少参数" }); | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | +}) | ||
| 131 | + | ||
| 132 | + | ||
| 133 | +module.exports = router; |
routes/index.js
100755 → 100644
| 1 | -var express = require('express'); | ||
| 2 | -var router = express.Router(); | ||
| 3 | -const { spawn } = require('child_process'); | 1 | +const express = require('express'); |
| 2 | +const router = express.Router(); | ||
| 3 | +const { spawn, exec } = require('child_process'); | ||
| 4 | const fs = require("fs"); | 4 | const fs = require("fs"); |
| 5 | +var path = require('path') | ||
| 6 | +const OSS = require('ali-oss'); | ||
| 7 | +require('dotenv').config(); // 加载环境变量 | ||
| 5 | 8 | ||
| 6 | const method = require("../config/method") | 9 | const method = require("../config/method") |
| 7 | const config = require("../config/config") | 10 | const config = require("../config/config") |
| 8 | 11 | ||
| 9 | // const { GETCLASSURL, GETCLASSURLPARAMETER, PROJECTCATALOG, PROJECTWINCATALOG, BACKMEDIACONFIG } = config | 12 | // const { GETCLASSURL, GETCLASSURLPARAMETER, PROJECTCATALOG, PROJECTWINCATALOG, BACKMEDIACONFIG } = config |
| 10 | -const { YesterdayTime, getRequestClassIds,dayTimeYMD } = method | 13 | +const { YesterdayTime, getRequestClassIds, dayTimeYMD } = method |
| 11 | 14 | ||
| 12 | -const { startTime, endTime, ymd } = YesterdayTime() | ||
| 13 | let siteIds = [] | 15 | let siteIds = [] |
| 14 | 16 | ||
| 15 | let classid = [] | 17 | let classid = [] |
| 18 | +let classidPost = [] | ||
| 16 | let parentData = {} | 19 | let parentData = {} |
| 17 | var classobj = {}; | 20 | var classobj = {}; |
| 18 | let className = "" | 21 | let className = "" |
| 22 | +let yesterday = "" // get写入课堂的时间 | ||
| 23 | + | ||
| 24 | +// spawn("export DISPLAY=:7", { shell: true}) | ||
| 25 | + | ||
| 19 | /** | 26 | /** |
| 20 | - * | 27 | + * |
| 21 | * @param {*} id 课堂id | 28 | * @param {*} id 课堂id |
| 22 | */ | 29 | */ |
| 23 | class MediaCreat { | 30 | class MediaCreat { |
| 24 | - constructor() { } | ||
| 25 | - // 取出所有数据 | ||
| 26 | - async allData() { | ||
| 27 | - let fileConfig = await new MediaCreat().getConfigFileJson() | ||
| 28 | - if(!fileConfig) return false | ||
| 29 | - className = siteIds.shift() | ||
| 30 | - const { GETCLASSURL,GETCLASSURLPARAMETER } = JSON.parse(fileConfig) | ||
| 31 | - let page = 1 | ||
| 32 | - if (className) { | ||
| 33 | - let result = await getRequestClassIds(GETCLASSURL, className, GETCLASSURLPARAMETER.key, startTime, endTime, page) | ||
| 34 | - parentData[result.data.data.siteId] = new Set() | ||
| 35 | - for (let j = 0; j < result.data.data.list.length; j++) { | ||
| 36 | - classid.push(result.data.data.list[j]) | ||
| 37 | - parentData[result.data.data.siteId].add(result.data.data.list[j]['classId']) | ||
| 38 | - } | ||
| 39 | - const { siteId, list, totalPage } = result.data.data | ||
| 40 | - for (let i = page += 1; i <= totalPage; i++) { | ||
| 41 | - let result = await getRequestClassIds(GETCLASSURL, className, GETCLASSURLPARAMETER.key, startTime, endTime, i) | ||
| 42 | - for (let j = 0; j < result.data.data.list.length; j++) { | ||
| 43 | - classid.push(result.data.data.list[j]) | ||
| 44 | - parentData[result.data.data.siteId].add(result.data.data.list[j]['classId']) | ||
| 45 | - } | ||
| 46 | - } | ||
| 47 | - parentData[result.data.data.siteId] = Array.from(parentData[result.data.data.siteId]) | ||
| 48 | - if (siteIds.length) { | ||
| 49 | - return await new MediaCreat().allData() | ||
| 50 | - } | ||
| 51 | - this.wrieLog("去重前的classId:------>" + JSON.stringify(classid)) | ||
| 52 | - this.wrieLog("httpData:------>" + JSON.stringify(result.data)) | ||
| 53 | - return true | ||
| 54 | - } else { | ||
| 55 | - return false | 31 | + constructor() { |
| 56 | } | 32 | } |
| 57 | - } | ||
| 58 | - wrieLog(text){ | ||
| 59 | - // 写入log | ||
| 60 | - let logFile = `./log/${dayTimeYMD().ymd}.txt` | ||
| 61 | - fs.appendFileSync(logFile,new Date().toLocaleString() + " " +text+'\r\n'); | ||
| 62 | - } | ||
| 63 | - async mediaCreat(id, siteId) { | ||
| 64 | - let fileConfig = await new MediaCreat().getConfigFileJson() | ||
| 65 | - if(!fileConfig) return false | ||
| 66 | - const { BACKMEDIACONFIG,PROJECTWINCATALOG,PROJECTCATALOG } = JSON.parse(fileConfig) | ||
| 67 | - | ||
| 68 | - let mediaDir = PROJECTCATALOG + "/media/" | ||
| 69 | - let classDir = PROJECTCATALOG + "/media/" + siteId | ||
| 70 | - let ymdDir = PROJECTCATALOG + "/media/" + siteId + "/" + ymd | ||
| 71 | - if (!fs.existsSync(mediaDir)) { | ||
| 72 | - fs.mkdirSync(mediaDir); | ||
| 73 | - } | ||
| 74 | - if (!fs.existsSync(classDir)) { | ||
| 75 | - fs.mkdirSync(classDir); | 33 | + |
| 34 | + // 取出所有数据 | ||
| 35 | + async allData() { | ||
| 36 | + const { startTime, endTime } = YesterdayTime() | ||
| 37 | + let fileConfig = new MediaCreat().getConfigFileJson() | ||
| 38 | + if (!fileConfig) return false | ||
| 39 | + className = siteIds.shift() | ||
| 40 | + const { GETCLASSURL, GETCLASSURLPARAMETER, classLastNumber } = JSON.parse(fileConfig) | ||
| 41 | + let page = 1 | ||
| 42 | + if (className) { | ||
| 43 | + let result = await getRequestClassIds(GETCLASSURL, className, GETCLASSURLPARAMETER.key, startTime, endTime, page) | ||
| 44 | + // parentData[result.data.data.siteId] = new Set() | ||
| 45 | + let resultList = result.data.data.list | ||
| 46 | + for (let j = 0; j < resultList.length; j++) { | ||
| 47 | + let item = resultList[j] | ||
| 48 | + let classId = item['classId'] | ||
| 49 | + let number = classId.substr(classId.length - 1, 1) | ||
| 50 | + if (classLastNumber.includes(number)){ | ||
| 51 | + classid.push(item) | ||
| 52 | + // parentData[result.data.data.siteId].add(classId) | ||
| 53 | + } | ||
| 54 | + } | ||
| 55 | + const { siteId, list, totalPage } = result.data.data | ||
| 56 | + for (let i = page += 1; i <= totalPage; i++) { | ||
| 57 | + let result = await getRequestClassIds(GETCLASSURL, className, GETCLASSURLPARAMETER.key, startTime, endTime, i) | ||
| 58 | + let resultList = result.data.data.list | ||
| 59 | + for (let j = 0; j < resultList.length; j++) { | ||
| 60 | + let item = resultList[j] | ||
| 61 | + let classId = item['classId'] | ||
| 62 | + let number = classId.substr(classId.length - 1, 1) | ||
| 63 | + if (classLastNumber.includes(number)) { | ||
| 64 | + classid.push(item) | ||
| 65 | + // parentData[result.data.data.siteId].add(classId) | ||
| 66 | + } | ||
| 67 | + } | ||
| 68 | + } | ||
| 69 | + // parentData[result.data.data.siteId] = Array.from(parentData[result.data.data.siteId]) | ||
| 70 | + if (siteIds.length) { | ||
| 71 | + return await new MediaCreat().allData() | ||
| 72 | + } | ||
| 73 | + this.wrieLog("去重前的classId:------>" + JSON.stringify(classid)) | ||
| 74 | + this.wrieLog("httpData:------>" + JSON.stringify(result.data)) | ||
| 75 | + return true | ||
| 76 | + } else { | ||
| 77 | + return false | ||
| 78 | + } | ||
| 76 | } | 79 | } |
| 77 | - if (!fs.existsSync(ymdDir)) { | ||
| 78 | - fs.mkdirSync(ymdDir); | 80 | + |
| 81 | + wrieLog(text) { | ||
| 82 | + // 写入log | ||
| 83 | + let logFile = `./log/${dayTimeYMD().ymd}.txt` | ||
| 84 | + fs.appendFileSync(logFile, new Date().toLocaleString() + " " + text + '\r\n'); | ||
| 79 | } | 85 | } |
| 80 | - let url = `web_capture_c -o=../media/${siteId}/${ymd}/${id}.mp4 -u="${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}&playRecord=${BACKMEDIACONFIG.playRecord}" -d=${BACKMEDIACONFIG.d} -s=${BACKMEDIACONFIG.s} -fa=${BACKMEDIACONFIG.fa} -k=${BACKMEDIACONFIG.k} -w=${BACKMEDIACONFIG.w} -h=${BACKMEDIACONFIG.h}` | ||
| 81 | - var workerProcess = spawn(url, { cwd: PROJECTWINCATALOG, shell: true }) | ||
| 82 | - // workerProcess.stdout.on('data', async function (data) { | ||
| 83 | - | ||
| 84 | - // }); | ||
| 85 | - | ||
| 86 | - workerProcess.on('close', async (code) => { | ||
| 87 | - let files = fs.readdirSync(ymdDir); | ||
| 88 | - if (files.indexOf(id + ".mp4") == -1) { | ||
| 89 | - //当前课堂没有写入到文件夹,进入重录 | ||
| 90 | - new MediaCreat().mediaCreat(id, siteId) | ||
| 91 | - return false | ||
| 92 | - } else { | ||
| 93 | - if (parentData[siteId].indexOf(id.toString()) != -1) { | ||
| 94 | - parentData[siteId].splice(parentData[siteId].indexOf(id.toString()), 1) | 86 | + |
| 87 | + recordingCreat(id, siteId, type) { | ||
| 88 | + this.wrieLog(" 课堂录制开始:------>" + id) | ||
| 89 | + let fileConfig = this.getConfigFileJson() | ||
| 90 | + if (!fileConfig) return false | ||
| 91 | + const { BACKMEDIACONFIG, PROJECTWINCATALOG, PROJECTCATALOG } = JSON.parse(fileConfig) | ||
| 92 | + let mediaDir = PROJECTCATALOG + "/media/" | ||
| 93 | + let classDir = PROJECTCATALOG + "/media/" + siteId | ||
| 94 | + let ymdDir = null | ||
| 95 | + if (type == 'post') { | ||
| 96 | + ymdDir = PROJECTCATALOG + "/media/" + siteId + "/" + dayTimeYMD().ymd | ||
| 97 | + } else { | ||
| 98 | + // get 的目录创建为上一天日期 | ||
| 99 | + ymdDir = PROJECTCATALOG + "/media/" + siteId + "/" + yesterday | ||
| 95 | } | 100 | } |
| 96 | - if (parentData[siteId].length == 0) { | ||
| 97 | - // //全部录制完毕 | ||
| 98 | - this.wrieLog("录制结束:------>") | ||
| 99 | - fs.writeFile(ymdDir + "/download.json", `{ "code": "0", "success": "ok"}`, function (err) { | ||
| 100 | - if (err) { | ||
| 101 | - console.log(err); | ||
| 102 | - } | ||
| 103 | - }); | 101 | + |
| 102 | + if (!fs.existsSync(mediaDir)) { | ||
| 103 | + fs.mkdirSync(mediaDir); | ||
| 104 | } | 104 | } |
| 105 | - if (classid.length) { | ||
| 106 | - let shiftData = classid.shift() | ||
| 107 | - new MediaCreat().mediaCreat(shiftData['classId'], shiftData['siteId']) | 105 | + if (!fs.existsSync(classDir)) { |
| 106 | + fs.mkdirSync(classDir); | ||
| 108 | } | 107 | } |
| 109 | - } | ||
| 110 | - }); | ||
| 111 | - } | ||
| 112 | - async recordingCreat(id, siteId) { | ||
| 113 | - let fileConfig = await new MediaCreat().getConfigFileJson() | ||
| 114 | - if(!fileConfig) return false | ||
| 115 | - const { BACKMEDIACONFIG,PROJECTWINCATALOG,PROJECTCATALOG } = JSON.parse(fileConfig) | ||
| 116 | - let mediaDir = PROJECTCATALOG + "/media/" | ||
| 117 | - let recordingDir = mediaDir + "recording/" | ||
| 118 | - let classDir = recordingDir + siteId +"/" | ||
| 119 | - let dateDir = classDir + dayTimeYMD().ymd | ||
| 120 | - if (!fs.existsSync(mediaDir)) { | ||
| 121 | - fs.mkdirSync(mediaDir); | ||
| 122 | - } | ||
| 123 | - if (!fs.existsSync(recordingDir)) { | ||
| 124 | - fs.mkdirSync(recordingDir); | ||
| 125 | - } | ||
| 126 | - if (!fs.existsSync(classDir)) { | ||
| 127 | - fs.mkdirSync(classDir); | ||
| 128 | - } | ||
| 129 | - if (!fs.existsSync(dateDir)) { | ||
| 130 | - fs.mkdirSync(dateDir); | ||
| 131 | - } | ||
| 132 | - let url = `web_capture_c -o=../media/recording/${siteId}/${dayTimeYMD().ymd}/${id}.mp4 -u="${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}&playRecord=${BACKMEDIACONFIG.playRecord}" -d=${BACKMEDIACONFIG.d} -s=${BACKMEDIACONFIG.s} -fa=${BACKMEDIACONFIG.fa} -k=${BACKMEDIACONFIG.k} -w=${BACKMEDIACONFIG.w} -h=${BACKMEDIACONFIG.h}` | ||
| 133 | - | ||
| 134 | - var workerProcess = spawn(url, { cwd: PROJECTWINCATALOG, shell: true }) | ||
| 135 | - // workerProcess.stdout.on('data', async function (data) { | ||
| 136 | - | ||
| 137 | - // }); | ||
| 138 | - | ||
| 139 | - workerProcess.on('close', async (code) =>{ | ||
| 140 | - let files = fs.readdirSync(dateDir); | ||
| 141 | - if (files.indexOf(id + ".mp4") == -1) { | ||
| 142 | - //当前课堂没有写入到文件夹,进入重录 | ||
| 143 | - new MediaCreat().recordingCreat(id, siteId) | ||
| 144 | - return false | ||
| 145 | - } else { | ||
| 146 | - if (parentData[siteId].indexOf(id.toString()) != -1) { | ||
| 147 | - parentData[siteId].splice(parentData[siteId].indexOf(id.toString()), 1) | 108 | + if (!fs.existsSync(ymdDir)) { |
| 109 | + fs.mkdirSync(ymdDir); | ||
| 148 | } | 110 | } |
| 149 | - if (parentData[siteId].length == 0) { | ||
| 150 | - // //全部录制完毕 | ||
| 151 | - this.wrieLog("录制结束:------>") | ||
| 152 | - fs.writeFile(dateDir + "/download.json", `{ "code": "0", "success": "ok"}`, function (err) { | ||
| 153 | - if (err) { | ||
| 154 | - console.log(err); | 111 | + let files = fs.readdirSync(ymdDir); |
| 112 | + // let interValGetFile = setInterval(()=>{ | ||
| 113 | + this.wrieLog("ymdDir" + ymdDir) | ||
| 114 | + this.wrieLog("files:" + files) | ||
| 115 | + if (files.indexOf(id + ".mp4") != -1) { | ||
| 116 | + this.wrieLog("已存在:" + id + "课堂号,停止继续录制") | ||
| 117 | + if (type == 'post') { | ||
| 118 | + if (classidPost.length) { | ||
| 119 | + let shiftData = classidPost.shift() | ||
| 120 | + this.wrieLog(" 录制下一节课 课堂号:" + shiftData['classId']) | ||
| 121 | + this.recordingCreat(shiftData['classId'], shiftData['siteId'], type) | ||
| 122 | + } | ||
| 123 | + } else { | ||
| 124 | + if (classid.length) { | ||
| 125 | + let shiftData = classid.shift() | ||
| 126 | + this.wrieLog(" 录制下一节课 课堂号:" + shiftData['classId']) | ||
| 127 | + this.recordingCreat(shiftData['classId'], shiftData['siteId'], type) | ||
| 128 | + } | ||
| 155 | } | 129 | } |
| 156 | - }); | ||
| 157 | - } | ||
| 158 | - if (classid.length) { | ||
| 159 | - let shiftData = classid.shift() | ||
| 160 | - new MediaCreat().recordingCreat(shiftData['classId'], shiftData['siteId']) | 130 | + return |
| 161 | } | 131 | } |
| 162 | - } | ||
| 163 | - }); | ||
| 164 | - } | ||
| 165 | - | ||
| 166 | - async getConfigFileJson(){ | ||
| 167 | - const buffer= fs.readFileSync(process.cwd()+"/config/config.json") | ||
| 168 | - return String(buffer) | ||
| 169 | - } | 132 | + // 目前url是linux的写法 win系统不支持 |
| 133 | + // export DISPLAY=:7 | ||
| 134 | + // let url = `${path.resolve(__dirname, PROJECTWINCATALOG+"/web_capture_c")} -o=${ymdDir}/${id}.mp4 -u="${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}&playRecord=${BACKMEDIACONFIG.playRecord}" -d=${BACKMEDIACONFIG.d} -s=${BACKMEDIACONFIG.s} -fa=${BACKMEDIACONFIG.fa} -k=${BACKMEDIACONFIG.k} -w=${BACKMEDIACONFIG.w} -h=${BACKMEDIACONFIG.h}` | ||
| 135 | + // console.log("url", url) | ||
| 136 | + let url = `${PROJECTWINCATALOG}/web_capture_c -o=${ymdDir}/${id}.mp4 -u="${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}&playRecord=${BACKMEDIACONFIG.playRecord}&language=zh-cn" -d=${BACKMEDIACONFIG.d} -s=${BACKMEDIACONFIG.s} -fa=${BACKMEDIACONFIG.fa} -k=${BACKMEDIACONFIG.k} -w=${BACKMEDIACONFIG.w} -h=${BACKMEDIACONFIG.h}` | ||
| 137 | + this.wrieLog(" 启动url " + url) | ||
| 138 | + exec(url, { maxBuffer: 1073741824 }, (err, stdout, stderr) => { | ||
| 139 | + if (err != null) { | ||
| 140 | + this.wrieLog(" 错误" + id + ":" + err) | ||
| 141 | + this.wrieLog(" 错误 stdout" + id + ":" + stdout) | ||
| 142 | + this.wrieLog(" 错误 stderr" + id + ":" + stderr) | ||
| 143 | + return | ||
| 144 | + } | ||
| 145 | + let files = fs.readdirSync(ymdDir); | ||
| 146 | + // let interValGetFile = setInterval(()=>{ | ||
| 147 | + if (files.indexOf(id + ".mp4") == -1) { | ||
| 148 | + this.wrieLog(" 课堂录制未发现该" + id + "课堂号") | ||
| 149 | + } else { | ||
| 150 | + if (type == 'get') { | ||
| 151 | + if (classid.length) { | ||
| 152 | + let shiftData = classid.shift() | ||
| 153 | + this.wrieLog(" 录制下一节课 课堂号:" + shiftData['classId']) | ||
| 154 | + this.recordingCreat(shiftData['classId'], shiftData['siteId'], type) | ||
| 155 | + } else { | ||
| 156 | + this.wrieLog("录制结束:------>") | ||
| 157 | + fs.writeFile(ymdDir + "/download.json", `{ "code": "0", "success": "ok"}`, function (err) { | ||
| 158 | + if (err) { | ||
| 159 | + console.log(err); | ||
| 160 | + } | ||
| 161 | + }); | ||
| 162 | + } | ||
| 163 | + } else { | ||
| 164 | + if (classidPost.length) { | ||
| 165 | + let shiftData = classidPost.shift() | ||
| 166 | + this.wrieLog(" 录制下一节课 课堂号:" + shiftData['classId']) | ||
| 167 | + this.recordingCreat(shiftData['classId'], shiftData['siteId'], type) | ||
| 168 | + } else { | ||
| 169 | + this.wrieLog("录制结束:------>") | ||
| 170 | + fs.writeFile(ymdDir + "/download.json", `{ "code": "0", "success": "ok"}`, function (err) { | ||
| 171 | + if (err) { | ||
| 172 | + console.log(err); | ||
| 173 | + } | ||
| 174 | + }); | ||
| 175 | + } | ||
| 176 | + } | ||
| 177 | + | ||
| 178 | + } | ||
| 179 | + }) | ||
| 180 | + } | ||
| 181 | + | ||
| 182 | + getConfigFileJson() { | ||
| 183 | + const buffer = fs.readFileSync(process.cwd() + "/config/config.json") | ||
| 184 | + return String(buffer) | ||
| 185 | + } | ||
| 170 | } | 186 | } |
| 171 | 187 | ||
| 172 | 188 | ||
| 173 | -router.get('/', async function (req, res, next) { | ||
| 174 | - new MediaCreat().wrieLog("录制开始:------>") | ||
| 175 | - let fileConfig = await new MediaCreat().getConfigFileJson() | ||
| 176 | - if(!fileConfig) return false | ||
| 177 | - | ||
| 178 | - const {GETCLASSURLPARAMETER} = JSON.parse(fileConfig) | ||
| 179 | - siteIds = GETCLASSURLPARAMETER.siteId | ||
| 180 | - | ||
| 181 | - let result = await new MediaCreat().allData() | ||
| 182 | - if (result) { | ||
| 183 | - // 去重 | ||
| 184 | - classobj = {} | ||
| 185 | - classid = classid.reduce(function (item, next) { | ||
| 186 | - classobj[next.classId] ? '' : classobj[next.classId] = true && item.push(next); | ||
| 187 | - return item; | ||
| 188 | - }, []); | ||
| 189 | - // 写入log | ||
| 190 | - new MediaCreat().wrieLog("去重后的classid:------>" + JSON.stringify(classid)) | ||
| 191 | - if (classid.length) { | ||
| 192 | - for (let i = 0; i < GETCLASSURLPARAMETER.maxMedia; i++) { | ||
| 193 | - let shiftData = classid.shift() | ||
| 194 | - if (shiftData) { | ||
| 195 | - new MediaCreat().mediaCreat(shiftData['classId'], shiftData['siteId']) | 189 | +router.get('/recording', async function (req, res, next) { |
| 190 | + if (classid.length > 0) { | ||
| 191 | + // 有正在录制中的课堂,禁止重复 | ||
| 192 | + res.send({ code: "1", message: "有正在录制中的课堂", data: classid }); | ||
| 193 | + return | ||
| 194 | + } | ||
| 195 | + new MediaCreat().wrieLog("脚本录制开始:------>") | ||
| 196 | + let fileConfig = new MediaCreat().getConfigFileJson() | ||
| 197 | + if (!fileConfig) return false | ||
| 198 | + | ||
| 199 | + const { GETCLASSURLPARAMETER } = JSON.parse(fileConfig) | ||
| 200 | + siteIds = GETCLASSURLPARAMETER.siteId | ||
| 201 | + if (siteIds.length == 0) { | ||
| 202 | + new MediaCreat().wrieLog("脚本录制,未配置siteId:------>" + siteIds) | ||
| 203 | + res.send({ code: "1", message: "未配置siteId", data: siteIds }); | ||
| 204 | + return | ||
| 205 | + } | ||
| 206 | + let result = await new MediaCreat().allData() | ||
| 207 | + if (result) { | ||
| 208 | + // 去重 | ||
| 209 | + classobj = {} | ||
| 210 | + classid = classid.reduce(function (item, next) { | ||
| 211 | + classobj[next.classId] ? '' : classobj[next.classId] = true && item.push(next); | ||
| 212 | + return item; | ||
| 213 | + }, []); | ||
| 214 | + // 写入log | ||
| 215 | + new MediaCreat().wrieLog("去重后的classid:------>" + JSON.stringify(classid)) | ||
| 216 | + if (classid.length) { | ||
| 217 | + for (let i = 0; i < GETCLASSURLPARAMETER.maxMedia; i++) { | ||
| 218 | + let shiftData = classid.shift() | ||
| 219 | + if (shiftData) { | ||
| 220 | + yesterday = YesterdayTime().ymd | ||
| 221 | + new MediaCreat().recordingCreat(shiftData['classId'], shiftData['siteId'], 'get') | ||
| 222 | + } else { | ||
| 223 | + return false | ||
| 224 | + } | ||
| 225 | + } | ||
| 226 | + res.send({ code: "0" }); | ||
| 196 | } else { | 227 | } else { |
| 197 | - return false | 228 | + res.send({ code: "1", message: "无录制数据" }); |
| 198 | } | 229 | } |
| 199 | - } | ||
| 200 | - res.send({ code: "0" }); | ||
| 201 | - }else{ | ||
| 202 | - res.send({ code: "1" ,message:"无录制数据"}); | 230 | + } else { |
| 231 | + res.send({ code: "1", message: "无录制数据" }); | ||
| 203 | } | 232 | } |
| 204 | - } | ||
| 205 | }); | 233 | }); |
| 206 | 234 | ||
| 207 | /** | 235 | /** |
| @@ -210,33 +238,103 @@ router.get('/', async function (req, res, next) { | @@ -210,33 +238,103 @@ router.get('/', async function (req, res, next) { | ||
| 210 | * } | 238 | * } |
| 211 | */ | 239 | */ |
| 212 | router.post('/recording', async function (req, res, next) { | 240 | router.post('/recording', async function (req, res, next) { |
| 213 | - new MediaCreat().wrieLog("录制开始:------>") | ||
| 214 | - let fileConfig = await new MediaCreat().getConfigFileJson() | ||
| 215 | - if(!fileConfig) return false | ||
| 216 | - const { classId } = req.body | ||
| 217 | - if(classId && classId.length){ | ||
| 218 | - classid = classId | ||
| 219 | - const { PROJECTCATALOG,GETCLASSURLPARAMETER } = JSON.parse(fileConfig) | ||
| 220 | - for(let i=0;i<classId.length;i++){ | ||
| 221 | - if(!Array.isArray(parentData[classId[i].siteId])){ | ||
| 222 | - parentData[classId[i].siteId] = [] | ||
| 223 | - } | ||
| 224 | - parentData[classId[i].siteId].push(classId[i].classId) | 241 | + new MediaCreat().wrieLog("录制启动:------>") |
| 242 | + let fileConfig = new MediaCreat().getConfigFileJson() | ||
| 243 | + if (!fileConfig) return false | ||
| 244 | + let { classId, maxMedia } = req.body | ||
| 245 | + if (classidPost.length > 0) { | ||
| 246 | + // 有正在录制中的课堂,禁止重复 | ||
| 247 | + res.send({ code: "1", message: "有正在录制中的课堂", data: classidPost }); | ||
| 248 | + return | ||
| 225 | } | 249 | } |
| 226 | - for(let i=0;i<GETCLASSURLPARAMETER.maxMedia;i++){ | ||
| 227 | - let shiftData = classid.shift() | ||
| 228 | - if (shiftData) { | ||
| 229 | - new MediaCreat().recordingCreat(shiftData['classId'], shiftData['siteId']) | ||
| 230 | - } else { | ||
| 231 | - return false | ||
| 232 | - } | 250 | + if (classId && classId.length) { |
| 251 | + classidPost = classId | ||
| 252 | + if (!maxMedia || maxMedia == undefined) { | ||
| 253 | + maxMedia = 1 | ||
| 254 | + } | ||
| 255 | + for (let i = 0; i < maxMedia; i++) { | ||
| 256 | + let shiftData = classidPost.shift() | ||
| 257 | + if (shiftData) { | ||
| 258 | + new MediaCreat().recordingCreat(shiftData['classId'], shiftData['siteId'], 'post') | ||
| 259 | + } else { | ||
| 260 | + return false | ||
| 261 | + } | ||
| 262 | + } | ||
| 263 | + res.send({ code: "0" }); | ||
| 264 | + } else { | ||
| 265 | + res.send({ code: "1", message: "无录制数据" }); | ||
| 233 | } | 266 | } |
| 234 | - res.send({ code: "0" }); | ||
| 235 | - }else{ | ||
| 236 | - res.send({ code: "1" ,message:"无录制数据"}); | ||
| 237 | - } | ||
| 238 | - | 267 | + |
| 239 | }) | 268 | }) |
| 240 | 269 | ||
| 270 | +// 判断该视频文件是否存在 | ||
| 271 | +router.post('/fileExists', async (req, res) => { | ||
| 272 | + const { siteId, classId, classStartTime } = req.body; | ||
| 273 | + | ||
| 274 | + // 检查输入参数 | ||
| 275 | + if (!siteId) { | ||
| 276 | + return res.status(400).send({ code: 2, message: "机构编码无效" }); | ||
| 277 | + } | ||
| 278 | + if (!classId) { | ||
| 279 | + return res.status(400).send({ code: 3, message: "课堂号无效" }); | ||
| 280 | + } | ||
| 281 | + | ||
| 282 | + try { | ||
| 283 | + // 检查环境变量是否设置 | ||
| 284 | + if (!process.env.ALIBABA_CLOUD_ACCESS_KEY_ID || !process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET) { | ||
| 285 | + throw new Error('Environment variables are not set correctly.'); | ||
| 286 | + } | ||
| 287 | + | ||
| 288 | + // 创建OSS客户端实例 | ||
| 289 | + const client = new OSS({ | ||
| 290 | + region: 'oss-cn-beijing', | ||
| 291 | + accessKeyId: process.env.ALIBABA_CLOUD_ACCESS_KEY_ID, | ||
| 292 | + accessKeySecret: process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET, | ||
| 293 | + authorizationV4: true, | ||
| 294 | + bucket: 'xdymp4' | ||
| 295 | + }); | ||
| 296 | + | ||
| 297 | + // 构建文件前缀 | ||
| 298 | + let prefix = ''; | ||
| 299 | + if (classStartTime) { | ||
| 300 | + prefix = `oss/${siteId}/${classStartTime}/${classId}.mp4`; | ||
| 301 | + } else { | ||
| 302 | + // 如果没有提供classStartTime,默认返回文件未生成 | ||
| 303 | + let classUrl = `https://pclive.xuedianyun.com/pcBase/pclive2/release/index.html?portalIP=saas.xuedianyun.com&portalPort=80&classId=${classId}&channels=2&playRecord=1#/`; | ||
| 304 | + return res.send({ code: 1, message: "文件未生成", classUrl }); | ||
| 305 | + } | ||
| 306 | + | ||
| 307 | + // 使用 await 处理异步操作 | ||
| 308 | + const result = await client.list({ prefix }); | ||
| 309 | + console.log('OSS list result:', JSON.stringify(result, null, 2)); // 日志记录详细结果 | ||
| 310 | + | ||
| 311 | + // 检查是否有匹配的文件 | ||
| 312 | + let isVideo = false; | ||
| 313 | + let url = ""; | ||
| 314 | + if (result.res.status === 200 && result.objects && result.objects.length > 0) { | ||
| 315 | + for (let item of result.objects) { | ||
| 316 | + // 更精确的匹配逻辑,确保找到的是目标文件 | ||
| 317 | + if (item.name === `${prefix}`) { | ||
| 318 | + isVideo = true; | ||
| 319 | + url = item.name; | ||
| 320 | + break; | ||
| 321 | + } | ||
| 322 | + } | ||
| 323 | + } | ||
| 324 | + | ||
| 325 | + // 根据结果发送响应 | ||
| 326 | + if (!isVideo) { | ||
| 327 | + let classUrl = `https://pclive.xuedianyun.com/pcBase/pclive2/release/index.html?portalIP=saas.xuedianyun.com&portalPort=80&classId=${classId}&channels=2&playRecord=1#/`; | ||
| 328 | + res.send({ code: 1, message: "文件未生成", classUrl }); | ||
| 329 | + } else { | ||
| 330 | + let classUrl = `https://xdymp4.xuedianyun.com/${url}`; | ||
| 331 | + res.send({ code: 0, message: "文件已生成", classUrl }); | ||
| 332 | + } | ||
| 333 | + | ||
| 334 | + } catch (err) { | ||
| 335 | + console.error('Error checking file existence:', err); | ||
| 336 | + res.status(500).send({ code: -1, message: "服务器内部错误", error: err.message }); | ||
| 337 | + } | ||
| 338 | +}); | ||
| 241 | 339 | ||
| 242 | -module.exports = router; | 340 | +module.exports = router |
routes/index.js.bak
0 → 100644
| 1 | +var express = require('express'); | ||
| 2 | +var router = express.Router(); | ||
| 3 | +const { spawn, exec } = require('child_process'); | ||
| 4 | +const fs = require("fs"); | ||
| 5 | +var path = require('path') | ||
| 6 | +var ObsClient = require('esdk-obs-nodejs'); | ||
| 7 | + | ||
| 8 | +const method = require("../config/method") | ||
| 9 | +const config = require("../config/config") | ||
| 10 | + | ||
| 11 | +// const { GETCLASSURL, GETCLASSURLPARAMETER, PROJECTCATALOG, PROJECTWINCATALOG, BACKMEDIACONFIG } = config | ||
| 12 | +const { YesterdayTime, getRequestClassIds, dayTimeYMD } = method | ||
| 13 | + | ||
| 14 | +let siteIds = [] | ||
| 15 | + | ||
| 16 | +let classid = [] | ||
| 17 | +let classidPost = [] | ||
| 18 | +let parentData = {} | ||
| 19 | +var classobj = {}; | ||
| 20 | +let className = "" | ||
| 21 | + | ||
| 22 | +// spawn("export DISPLAY=:7", { shell: true}) | ||
| 23 | + | ||
| 24 | +/** | ||
| 25 | + * | ||
| 26 | + * @param {*} id 课堂id | ||
| 27 | + */ | ||
| 28 | +class MediaCreat { | ||
| 29 | + constructor() { | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + // 取出所有数据 | ||
| 33 | + async allData() { | ||
| 34 | + const { startTime, endTime } = YesterdayTime() | ||
| 35 | + let fileConfig = new MediaCreat().getConfigFileJson() | ||
| 36 | + if (!fileConfig) return false | ||
| 37 | + className = siteIds.shift() | ||
| 38 | + const { GETCLASSURL, GETCLASSURLPARAMETER } = JSON.parse(fileConfig) | ||
| 39 | + let page = 1 | ||
| 40 | + if (className) { | ||
| 41 | + let result = await getRequestClassIds(GETCLASSURL, className, GETCLASSURLPARAMETER.key, startTime, endTime, page) | ||
| 42 | + parentData[result.data.data.siteId] = new Set() | ||
| 43 | + for (let j = 0; j < result.data.data.list.length; j++) { | ||
| 44 | + classid.push(result.data.data.list[j]) | ||
| 45 | + parentData[result.data.data.siteId].add(result.data.data.list[j]['classId']) | ||
| 46 | + } | ||
| 47 | + const { siteId, list, totalPage } = result.data.data | ||
| 48 | + for (let i = page += 1; i <= totalPage; i++) { | ||
| 49 | + let result = await getRequestClassIds(GETCLASSURL, className, GETCLASSURLPARAMETER.key, startTime, endTime, i) | ||
| 50 | + for (let j = 0; j < result.data.data.list.length; j++) { | ||
| 51 | + classid.push(result.data.data.list[j]) | ||
| 52 | + parentData[result.data.data.siteId].add(result.data.data.list[j]['classId']) | ||
| 53 | + } | ||
| 54 | + } | ||
| 55 | + parentData[result.data.data.siteId] = Array.from(parentData[result.data.data.siteId]) | ||
| 56 | + if (siteIds.length) { | ||
| 57 | + return await new MediaCreat().allData() | ||
| 58 | + } | ||
| 59 | + this.wrieLog("去重前的classId:------>" + JSON.stringify(classid)) | ||
| 60 | + this.wrieLog("httpData:------>" + JSON.stringify(result.data)) | ||
| 61 | + return true | ||
| 62 | + } else { | ||
| 63 | + return false | ||
| 64 | + } | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + wrieLog(text) { | ||
| 68 | + // 写入log | ||
| 69 | + let logFile = `./log/${dayTimeYMD().ymd}.txt` | ||
| 70 | + fs.appendFileSync(logFile, new Date().toLocaleString() + " " + text + '\r\n'); | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + recordingCreat(id, siteId, type) { | ||
| 74 | + this.wrieLog(" 课堂录制开始:------>" + id) | ||
| 75 | + let fileConfig = this.getConfigFileJson() | ||
| 76 | + if (!fileConfig) return false | ||
| 77 | + const { BACKMEDIACONFIG, PROJECTWINCATALOG, PROJECTCATALOG } = JSON.parse(fileConfig) | ||
| 78 | + let mediaDir = PROJECTCATALOG + "/media/" | ||
| 79 | + let classDir = PROJECTCATALOG + "/media/" + siteId | ||
| 80 | + let ymdDir = null | ||
| 81 | + if (type == 'post') { | ||
| 82 | + ymdDir = PROJECTCATALOG + "/media/" + siteId + "/" + dayTimeYMD().ymd | ||
| 83 | + } else { | ||
| 84 | + // get 的目录创建为上一天日期 | ||
| 85 | + ymdDir = PROJECTCATALOG + "/media/" + siteId + "/" + YesterdayTime().ymd | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + if (!fs.existsSync(mediaDir)) { | ||
| 89 | + fs.mkdirSync(mediaDir); | ||
| 90 | + } | ||
| 91 | + if (!fs.existsSync(classDir)) { | ||
| 92 | + fs.mkdirSync(classDir); | ||
| 93 | + } | ||
| 94 | + if (!fs.existsSync(ymdDir)) { | ||
| 95 | + fs.mkdirSync(ymdDir); | ||
| 96 | + } | ||
| 97 | + let files = fs.readdirSync(ymdDir); | ||
| 98 | + // let interValGetFile = setInterval(()=>{ | ||
| 99 | + this.wrieLog("files:" + files) | ||
| 100 | + if (files.indexOf(id + ".mp4") != -1) { | ||
| 101 | + this.wrieLog("已存在:" + id + "课堂号,停止继续录制") | ||
| 102 | + if (type == 'post') { | ||
| 103 | + if (classidPost.length) { | ||
| 104 | + let shiftData = classidPost.shift() | ||
| 105 | + this.wrieLog(" 录制下一节课 课堂号:" + shiftData['classId']) | ||
| 106 | + this.recordingCreat(shiftData['classId'], shiftData['siteId'], type) | ||
| 107 | + } | ||
| 108 | + } else { | ||
| 109 | + if (classid.length) { | ||
| 110 | + let shiftData = classid.shift() | ||
| 111 | + this.wrieLog(" 录制下一节课 课堂号:" + shiftData['classId']) | ||
| 112 | + this.recordingCreat(shiftData['classId'], shiftData['siteId'], type) | ||
| 113 | + } | ||
| 114 | + } | ||
| 115 | + return | ||
| 116 | + } | ||
| 117 | + // 目前url是linux的写法 win系统不支持 | ||
| 118 | + // export DISPLAY=:7 | ||
| 119 | + // let url = `${path.resolve(__dirname, PROJECTWINCATALOG+"/web_capture_c")} -o=${ymdDir}/${id}.mp4 -u="${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}&playRecord=${BACKMEDIACONFIG.playRecord}" -d=${BACKMEDIACONFIG.d} -s=${BACKMEDIACONFIG.s} -fa=${BACKMEDIACONFIG.fa} -k=${BACKMEDIACONFIG.k} -w=${BACKMEDIACONFIG.w} -h=${BACKMEDIACONFIG.h}` | ||
| 120 | + // console.log("url", url) | ||
| 121 | + let url = `${PROJECTWINCATALOG}/web_capture_c -o=${ymdDir}/${id}.mp4 -u="${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}&playRecord=${BACKMEDIACONFIG.playRecord}&language=zh-cn" -d=${BACKMEDIACONFIG.d} -s=${BACKMEDIACONFIG.s} -fa=${BACKMEDIACONFIG.fa} -k=${BACKMEDIACONFIG.k} -w=${BACKMEDIACONFIG.w} -h=${BACKMEDIACONFIG.h} -vb=999999999999` | ||
| 122 | + exec(url, { maxBuffer: 1073741824 }, (err, stdout, stderr) => { | ||
| 123 | + if (err != null) { | ||
| 124 | + this.wrieLog(" 错误" + id + ":" + err) | ||
| 125 | + this.wrieLog(" 错误 stdout" + id + ":" + stdout) | ||
| 126 | + this.wrieLog(" 错误 stderr" + id + ":" + stderr) | ||
| 127 | + return | ||
| 128 | + } | ||
| 129 | + let files = fs.readdirSync(ymdDir); | ||
| 130 | + // let interValGetFile = setInterval(()=>{ | ||
| 131 | + if (files.indexOf(id + ".mp4") == -1) { | ||
| 132 | + this.wrieLog(" 课堂录制未发现该" + id + "课堂号") | ||
| 133 | + } else { | ||
| 134 | + if (type == 'get') { | ||
| 135 | + if (classid.length) { | ||
| 136 | + let shiftData = classid.shift() | ||
| 137 | + this.wrieLog(" 录制下一节课 课堂号:" + shiftData['classId']) | ||
| 138 | + this.recordingCreat(shiftData['classId'], shiftData['siteId'], type) | ||
| 139 | + } else { | ||
| 140 | + this.wrieLog("录制结束:------>") | ||
| 141 | + fs.writeFile(ymdDir + "/download.json", `{ "code": "0", "success": "ok"}`, function (err) { | ||
| 142 | + if (err) { | ||
| 143 | + console.log(err); | ||
| 144 | + } | ||
| 145 | + }); | ||
| 146 | + } | ||
| 147 | + } else { | ||
| 148 | + if (classidPost.length) { | ||
| 149 | + let shiftData = classidPost.shift() | ||
| 150 | + this.wrieLog(" 录制下一节课 课堂号:" + shiftData['classId']) | ||
| 151 | + this.recordingCreat(shiftData['classId'], shiftData['siteId'], type) | ||
| 152 | + } else { | ||
| 153 | + this.wrieLog("录制结束:------>") | ||
| 154 | + fs.writeFile(ymdDir + "/download.json", `{ "code": "0", "success": "ok"}`, function (err) { | ||
| 155 | + if (err) { | ||
| 156 | + console.log(err); | ||
| 157 | + } | ||
| 158 | + }); | ||
| 159 | + } | ||
| 160 | + } | ||
| 161 | + | ||
| 162 | + } | ||
| 163 | + }) | ||
| 164 | + } | ||
| 165 | + | ||
| 166 | + getConfigFileJson() { | ||
| 167 | + const buffer = fs.readFileSync(process.cwd() + "/config/config.json") | ||
| 168 | + return String(buffer) | ||
| 169 | + } | ||
| 170 | +} | ||
| 171 | + | ||
| 172 | + | ||
| 173 | +router.get('/recording', async function (req, res, next) { | ||
| 174 | + if (classid.length > 0) { | ||
| 175 | + // 有正在录制中的课堂,禁止重复 | ||
| 176 | + res.send({ code: "1", message: "有正在录制中的课堂", data: classid }); | ||
| 177 | + return | ||
| 178 | + } | ||
| 179 | + new MediaCreat().wrieLog("脚本录制开始:------>") | ||
| 180 | + let fileConfig = new MediaCreat().getConfigFileJson() | ||
| 181 | + if (!fileConfig) return false | ||
| 182 | + | ||
| 183 | + const { GETCLASSURLPARAMETER } = JSON.parse(fileConfig) | ||
| 184 | + siteIds = GETCLASSURLPARAMETER.siteId | ||
| 185 | + if (siteIds.length == 0) { | ||
| 186 | + new MediaCreat().wrieLog("脚本录制,未配置siteId:------>" + siteIds) | ||
| 187 | + res.send({ code: "1", message: "未配置siteId", data: siteIds }); | ||
| 188 | + return | ||
| 189 | + } | ||
| 190 | + let result = await new MediaCreat().allData() | ||
| 191 | + if (result) { | ||
| 192 | + // 去重 | ||
| 193 | + classobj = {} | ||
| 194 | + classid = classid.reduce(function (item, next) { | ||
| 195 | + classobj[next.classId] ? '' : classobj[next.classId] = true && item.push(next); | ||
| 196 | + return item; | ||
| 197 | + }, []); | ||
| 198 | + // 写入log | ||
| 199 | + new MediaCreat().wrieLog("去重后的classid:------>" + JSON.stringify(classid)) | ||
| 200 | + if (classid.length) { | ||
| 201 | + for (let i = 0; i < GETCLASSURLPARAMETER.maxMedia; i++) { | ||
| 202 | + let shiftData = classid.shift() | ||
| 203 | + if (shiftData) { | ||
| 204 | + new MediaCreat().recordingCreat(shiftData['classId'], shiftData['siteId'], 'get') | ||
| 205 | + } else { | ||
| 206 | + return false | ||
| 207 | + } | ||
| 208 | + } | ||
| 209 | + res.send({ code: "0" }); | ||
| 210 | + } else { | ||
| 211 | + res.send({ code: "1", message: "无录制数据" }); | ||
| 212 | + } | ||
| 213 | + } else { | ||
| 214 | + res.send({ code: "1", message: "无录制数据" }); | ||
| 215 | + } | ||
| 216 | +}); | ||
| 217 | + | ||
| 218 | +/** | ||
| 219 | + * { | ||
| 220 | + * "classId":[{ classId: '389675110', siteId: 'kuaikuenglish' }] | ||
| 221 | + * } | ||
| 222 | + */ | ||
| 223 | +router.post('/recording', async function (req, res, next) { | ||
| 224 | + new MediaCreat().wrieLog("录制启动:------>") | ||
| 225 | + let fileConfig = new MediaCreat().getConfigFileJson() | ||
| 226 | + if (!fileConfig) return false | ||
| 227 | + let { classId, maxMedia } = req.body | ||
| 228 | + if (classidPost.length > 0) { | ||
| 229 | + // 有正在录制中的课堂,禁止重复 | ||
| 230 | + res.send({ code: "1", message: "有正在录制中的课堂", data: classidPost }); | ||
| 231 | + return | ||
| 232 | + } | ||
| 233 | + if (classId && classId.length) { | ||
| 234 | + classidPost = classId | ||
| 235 | + if (!maxMedia || maxMedia == undefined) { | ||
| 236 | + maxMedia = 1 | ||
| 237 | + } | ||
| 238 | + for (let i = 0; i < maxMedia; i++) { | ||
| 239 | + let shiftData = classidPost.shift() | ||
| 240 | + if (shiftData) { | ||
| 241 | + new MediaCreat().recordingCreat(shiftData['classId'], shiftData['siteId'], 'post') | ||
| 242 | + } else { | ||
| 243 | + return false | ||
| 244 | + } | ||
| 245 | + } | ||
| 246 | + res.send({ code: "0" }); | ||
| 247 | + } else { | ||
| 248 | + res.send({ code: "1", message: "无录制数据" }); | ||
| 249 | + } | ||
| 250 | + | ||
| 251 | +}) | ||
| 252 | + | ||
| 253 | +// 判断该视频文件是否存在 | ||
| 254 | +router.post('/fileExists', async function (req, res, next) { | ||
| 255 | + const body = req.body | ||
| 256 | + if(!body.siteId) { | ||
| 257 | + res.send({ code: 2,message:"机构编码无效" }); | ||
| 258 | + return | ||
| 259 | + } | ||
| 260 | + if(!body.classId) { | ||
| 261 | + res.send({ code: 3,message:"课堂号无效" }); | ||
| 262 | + return | ||
| 263 | + } | ||
| 264 | + | ||
| 265 | + // 创建ObsClient实例 | ||
| 266 | + var obsClient = new ObsClient({ | ||
| 267 | + access_key_id: 'FY27OD11ZJVC385AOTW9', | ||
| 268 | + secret_access_key: 'ZqnfRjaseCtuRbE79GvqkPiYUdT83ZbB0oU7fBo3', | ||
| 269 | + server : 'obs.cn-north-4.myhuaweicloud.com' | ||
| 270 | + }); | ||
| 271 | + | ||
| 272 | + let isVideo = false | ||
| 273 | + let url = "" | ||
| 274 | + obsClient.listObjects({ | ||
| 275 | + Bucket : 'xdymp4' | ||
| 276 | + }, (err, result) => { | ||
| 277 | + if(err){ | ||
| 278 | + console.error('Error-->' + err); | ||
| 279 | + }else{ | ||
| 280 | + if(result.CommonMsg.Status == 200){ | ||
| 281 | + for(let i=0;i<result.InterfaceResult.Contents.length;i++){ | ||
| 282 | + let item = result.InterfaceResult.Contents[i] | ||
| 283 | + if(item.Key && item.Key.indexOf(body.classId) > -1){ | ||
| 284 | + isVideo = true | ||
| 285 | + url = item.Key | ||
| 286 | + break | ||
| 287 | + } | ||
| 288 | + } | ||
| 289 | + } | ||
| 290 | + } | ||
| 291 | + if(!isVideo){ | ||
| 292 | + let classUrl = `https://pclive.xuedianyun.com/pcBase/pclive2/release/index.html?portalIP=saas.xuedianyun.com&portalPort=80&classId=${body.classId}&channels=2&playRecord=1#/` | ||
| 293 | + res.send({ code: 1,message:"文件未生成",classUrl }); | ||
| 294 | + }else{ | ||
| 295 | + let classUrl = `https://xdymp4.xuedianyun.com/${url}` | ||
| 296 | + res.send({ code: 0,message:"文件已生成",classUrl }); | ||
| 297 | + } | ||
| 298 | + // 关闭obsClient | ||
| 299 | + obsClient.close(); | ||
| 300 | + }); | ||
| 301 | +}) | ||
| 302 | + | ||
| 303 | +module.exports = router; |
routes/index.js20250102
0 → 100644
| 1 | +var express = require('express'); | ||
| 2 | +var router = express.Router(); | ||
| 3 | +const { spawn, exec } = require('child_process'); | ||
| 4 | +const fs = require("fs"); | ||
| 5 | +var path = require('path') | ||
| 6 | +var ObsClient = require('esdk-obs-nodejs'); | ||
| 7 | + | ||
| 8 | +const method = require("../config/method") | ||
| 9 | +const config = require("../config/config") | ||
| 10 | + | ||
| 11 | +// const { GETCLASSURL, GETCLASSURLPARAMETER, PROJECTCATALOG, PROJECTWINCATALOG, BACKMEDIACONFIG } = config | ||
| 12 | +const { YesterdayTime, getRequestClassIds, dayTimeYMD } = method | ||
| 13 | + | ||
| 14 | +let siteIds = [] | ||
| 15 | + | ||
| 16 | +let classid = [] | ||
| 17 | +let classidPost = [] | ||
| 18 | +let parentData = {} | ||
| 19 | +var classobj = {}; | ||
| 20 | +let className = "" | ||
| 21 | +let yesterday = "" // get写入课堂的时间 | ||
| 22 | + | ||
| 23 | +// spawn("export DISPLAY=:7", { shell: true}) | ||
| 24 | + | ||
| 25 | +/** | ||
| 26 | + * | ||
| 27 | + * @param {*} id 课堂id | ||
| 28 | + */ | ||
| 29 | +class MediaCreat { | ||
| 30 | + constructor() { | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + // 取出所有数据 | ||
| 34 | + async allData() { | ||
| 35 | + const { startTime, endTime } = YesterdayTime() | ||
| 36 | + let fileConfig = new MediaCreat().getConfigFileJson() | ||
| 37 | + if (!fileConfig) return false | ||
| 38 | + className = siteIds.shift() | ||
| 39 | + const { GETCLASSURL, GETCLASSURLPARAMETER, classLastNumber } = JSON.parse(fileConfig) | ||
| 40 | + let page = 1 | ||
| 41 | + if (className) { | ||
| 42 | + let result = await getRequestClassIds(GETCLASSURL, className, GETCLASSURLPARAMETER.key, startTime, endTime, page) | ||
| 43 | + // parentData[result.data.data.siteId] = new Set() | ||
| 44 | + let resultList = result.data.data.list | ||
| 45 | + for (let j = 0; j < resultList.length; j++) { | ||
| 46 | + let item = resultList[j] | ||
| 47 | + let classId = item['classId'] | ||
| 48 | + let number = classId.substr(classId.length - 1, 1) | ||
| 49 | + if (classLastNumber.includes(number)){ | ||
| 50 | + classid.push(item) | ||
| 51 | + // parentData[result.data.data.siteId].add(classId) | ||
| 52 | + } | ||
| 53 | + } | ||
| 54 | + const { siteId, list, totalPage } = result.data.data | ||
| 55 | + for (let i = page += 1; i <= totalPage; i++) { | ||
| 56 | + let result = await getRequestClassIds(GETCLASSURL, className, GETCLASSURLPARAMETER.key, startTime, endTime, i) | ||
| 57 | + let resultList = result.data.data.list | ||
| 58 | + for (let j = 0; j < resultList.length; j++) { | ||
| 59 | + let item = resultList[j] | ||
| 60 | + let classId = item['classId'] | ||
| 61 | + let number = classId.substr(classId.length - 1, 1) | ||
| 62 | + if (classLastNumber.includes(number)) { | ||
| 63 | + classid.push(item) | ||
| 64 | + // parentData[result.data.data.siteId].add(classId) | ||
| 65 | + } | ||
| 66 | + } | ||
| 67 | + } | ||
| 68 | + // parentData[result.data.data.siteId] = Array.from(parentData[result.data.data.siteId]) | ||
| 69 | + if (siteIds.length) { | ||
| 70 | + return await new MediaCreat().allData() | ||
| 71 | + } | ||
| 72 | + this.wrieLog("去重前的classId:------>" + JSON.stringify(classid)) | ||
| 73 | + this.wrieLog("httpData:------>" + JSON.stringify(result.data)) | ||
| 74 | + return true | ||
| 75 | + } else { | ||
| 76 | + return false | ||
| 77 | + } | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + wrieLog(text) { | ||
| 81 | + // 写入log | ||
| 82 | + let logFile = `./log/${dayTimeYMD().ymd}.txt` | ||
| 83 | + fs.appendFileSync(logFile, new Date().toLocaleString() + " " + text + '\r\n'); | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + recordingCreat(id, siteId, type) { | ||
| 87 | + this.wrieLog(" 课堂录制开始:------>" + id) | ||
| 88 | + let fileConfig = this.getConfigFileJson() | ||
| 89 | + if (!fileConfig) return false | ||
| 90 | + const { BACKMEDIACONFIG, PROJECTWINCATALOG, PROJECTCATALOG } = JSON.parse(fileConfig) | ||
| 91 | + let mediaDir = PROJECTCATALOG + "/media/" | ||
| 92 | + let classDir = PROJECTCATALOG + "/media/" + siteId | ||
| 93 | + let ymdDir = null | ||
| 94 | + if (type == 'post') { | ||
| 95 | + ymdDir = PROJECTCATALOG + "/media/" + siteId + "/" + dayTimeYMD().ymd | ||
| 96 | + } else { | ||
| 97 | + // get 的目录创建为上一天日期 | ||
| 98 | + ymdDir = PROJECTCATALOG + "/media/" + siteId + "/" + yesterday | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + if (!fs.existsSync(mediaDir)) { | ||
| 102 | + fs.mkdirSync(mediaDir); | ||
| 103 | + } | ||
| 104 | + if (!fs.existsSync(classDir)) { | ||
| 105 | + fs.mkdirSync(classDir); | ||
| 106 | + } | ||
| 107 | + if (!fs.existsSync(ymdDir)) { | ||
| 108 | + fs.mkdirSync(ymdDir); | ||
| 109 | + } | ||
| 110 | + let files = fs.readdirSync(ymdDir); | ||
| 111 | + // let interValGetFile = setInterval(()=>{ | ||
| 112 | + this.wrieLog("ymdDir" + ymdDir) | ||
| 113 | + this.wrieLog("files:" + files) | ||
| 114 | + if (files.indexOf(id + ".mp4") != -1) { | ||
| 115 | + this.wrieLog("已存在:" + id + "课堂号,停止继续录制") | ||
| 116 | + if (type == 'post') { | ||
| 117 | + if (classidPost.length) { | ||
| 118 | + let shiftData = classidPost.shift() | ||
| 119 | + this.wrieLog(" 录制下一节课 课堂号:" + shiftData['classId']) | ||
| 120 | + this.recordingCreat(shiftData['classId'], shiftData['siteId'], type) | ||
| 121 | + } | ||
| 122 | + } else { | ||
| 123 | + if (classid.length) { | ||
| 124 | + let shiftData = classid.shift() | ||
| 125 | + this.wrieLog(" 录制下一节课 课堂号:" + shiftData['classId']) | ||
| 126 | + this.recordingCreat(shiftData['classId'], shiftData['siteId'], type) | ||
| 127 | + } | ||
| 128 | + } | ||
| 129 | + return | ||
| 130 | + } | ||
| 131 | + // 目前url是linux的写法 win系统不支持 | ||
| 132 | + // export DISPLAY=:7 | ||
| 133 | + // let url = `${path.resolve(__dirname, PROJECTWINCATALOG+"/web_capture_c")} -o=${ymdDir}/${id}.mp4 -u="${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}&playRecord=${BACKMEDIACONFIG.playRecord}" -d=${BACKMEDIACONFIG.d} -s=${BACKMEDIACONFIG.s} -fa=${BACKMEDIACONFIG.fa} -k=${BACKMEDIACONFIG.k} -w=${BACKMEDIACONFIG.w} -h=${BACKMEDIACONFIG.h}` | ||
| 134 | + // console.log("url", url) | ||
| 135 | + let url = `${PROJECTWINCATALOG}/web_capture_c -o=${ymdDir}/${id}.mp4 -u="${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}&playRecord=${BACKMEDIACONFIG.playRecord}&language=zh-tw" -d=${BACKMEDIACONFIG.d} -s=${BACKMEDIACONFIG.s} -fa=${BACKMEDIACONFIG.fa} -k=${BACKMEDIACONFIG.k} -w=${BACKMEDIACONFIG.w} -h=${BACKMEDIACONFIG.h}` | ||
| 136 | + this.wrieLog(" 启动url " + url) | ||
| 137 | + exec(url, { maxBuffer: 1073741824 }, (err, stdout, stderr) => { | ||
| 138 | + if (err != null) { | ||
| 139 | + this.wrieLog(" 错误" + id + ":" + err) | ||
| 140 | + this.wrieLog(" 错误 stdout" + id + ":" + stdout) | ||
| 141 | + this.wrieLog(" 错误 stderr" + id + ":" + stderr) | ||
| 142 | + return | ||
| 143 | + } | ||
| 144 | + let files = fs.readdirSync(ymdDir); | ||
| 145 | + // let interValGetFile = setInterval(()=>{ | ||
| 146 | + if (files.indexOf(id + ".mp4") == -1) { | ||
| 147 | + this.wrieLog(" 课堂录制未发现该" + id + "课堂号") | ||
| 148 | + } else { | ||
| 149 | + if (type == 'get') { | ||
| 150 | + if (classid.length) { | ||
| 151 | + let shiftData = classid.shift() | ||
| 152 | + this.wrieLog(" 录制下一节课 课堂号:" + shiftData['classId']) | ||
| 153 | + this.recordingCreat(shiftData['classId'], shiftData['siteId'], type) | ||
| 154 | + } else { | ||
| 155 | + this.wrieLog("录制结束:------>") | ||
| 156 | + fs.writeFile(ymdDir + "/download.json", `{ "code": "0", "success": "ok"}`, function (err) { | ||
| 157 | + if (err) { | ||
| 158 | + console.log(err); | ||
| 159 | + } | ||
| 160 | + }); | ||
| 161 | + } | ||
| 162 | + } else { | ||
| 163 | + if (classidPost.length) { | ||
| 164 | + let shiftData = classidPost.shift() | ||
| 165 | + this.wrieLog(" 录制下一节课 课堂号:" + shiftData['classId']) | ||
| 166 | + this.recordingCreat(shiftData['classId'], shiftData['siteId'], type) | ||
| 167 | + } else { | ||
| 168 | + this.wrieLog("录制结束:------>") | ||
| 169 | + fs.writeFile(ymdDir + "/download.json", `{ "code": "0", "success": "ok"}`, function (err) { | ||
| 170 | + if (err) { | ||
| 171 | + console.log(err); | ||
| 172 | + } | ||
| 173 | + }); | ||
| 174 | + } | ||
| 175 | + } | ||
| 176 | + | ||
| 177 | + } | ||
| 178 | + }) | ||
| 179 | + } | ||
| 180 | + | ||
| 181 | + getConfigFileJson() { | ||
| 182 | + const buffer = fs.readFileSync(process.cwd() + "/config/config.json") | ||
| 183 | + return String(buffer) | ||
| 184 | + } | ||
| 185 | +} | ||
| 186 | + | ||
| 187 | + | ||
| 188 | +router.get('/recording', async function (req, res, next) { | ||
| 189 | + if (classid.length > 0) { | ||
| 190 | + // 有正在录制中的课堂,禁止重复 | ||
| 191 | + res.send({ code: "1", message: "有正在录制中的课堂", data: classid }); | ||
| 192 | + return | ||
| 193 | + } | ||
| 194 | + new MediaCreat().wrieLog("脚本录制开始:------>") | ||
| 195 | + let fileConfig = new MediaCreat().getConfigFileJson() | ||
| 196 | + if (!fileConfig) return false | ||
| 197 | + | ||
| 198 | + const { GETCLASSURLPARAMETER } = JSON.parse(fileConfig) | ||
| 199 | + siteIds = GETCLASSURLPARAMETER.siteId | ||
| 200 | + if (siteIds.length == 0) { | ||
| 201 | + new MediaCreat().wrieLog("脚本录制,未配置siteId:------>" + siteIds) | ||
| 202 | + res.send({ code: "1", message: "未配置siteId", data: siteIds }); | ||
| 203 | + return | ||
| 204 | + } | ||
| 205 | + let result = await new MediaCreat().allData() | ||
| 206 | + if (result) { | ||
| 207 | + // 去重 | ||
| 208 | + classobj = {} | ||
| 209 | + classid = classid.reduce(function (item, next) { | ||
| 210 | + classobj[next.classId] ? '' : classobj[next.classId] = true && item.push(next); | ||
| 211 | + return item; | ||
| 212 | + }, []); | ||
| 213 | + // 写入log | ||
| 214 | + new MediaCreat().wrieLog("去重后的classid:------>" + JSON.stringify(classid)) | ||
| 215 | + if (classid.length) { | ||
| 216 | + for (let i = 0; i < GETCLASSURLPARAMETER.maxMedia; i++) { | ||
| 217 | + let shiftData = classid.shift() | ||
| 218 | + if (shiftData) { | ||
| 219 | + yesterday = YesterdayTime().ymd | ||
| 220 | + new MediaCreat().recordingCreat(shiftData['classId'], shiftData['siteId'], 'get') | ||
| 221 | + } else { | ||
| 222 | + return false | ||
| 223 | + } | ||
| 224 | + } | ||
| 225 | + res.send({ code: "0" }); | ||
| 226 | + } else { | ||
| 227 | + res.send({ code: "1", message: "无录制数据" }); | ||
| 228 | + } | ||
| 229 | + } else { | ||
| 230 | + res.send({ code: "1", message: "无录制数据" }); | ||
| 231 | + } | ||
| 232 | +}); | ||
| 233 | + | ||
| 234 | +/** | ||
| 235 | + * { | ||
| 236 | + * "classId":[{ classId: '389675110', siteId: 'kuaikuenglish' }] | ||
| 237 | + * } | ||
| 238 | + */ | ||
| 239 | +router.post('/recording', async function (req, res, next) { | ||
| 240 | + new MediaCreat().wrieLog("录制启动:------>") | ||
| 241 | + let fileConfig = new MediaCreat().getConfigFileJson() | ||
| 242 | + if (!fileConfig) return false | ||
| 243 | + let { classId, maxMedia } = req.body | ||
| 244 | + if (classidPost.length > 0) { | ||
| 245 | + // 有正在录制中的课堂,禁止重复 | ||
| 246 | + res.send({ code: "1", message: "有正在录制中的课堂", data: classidPost }); | ||
| 247 | + return | ||
| 248 | + } | ||
| 249 | + if (classId && classId.length) { | ||
| 250 | + classidPost = classId | ||
| 251 | + if (!maxMedia || maxMedia == undefined) { | ||
| 252 | + maxMedia = 1 | ||
| 253 | + } | ||
| 254 | + for (let i = 0; i < maxMedia; i++) { | ||
| 255 | + let shiftData = classidPost.shift() | ||
| 256 | + if (shiftData) { | ||
| 257 | + new MediaCreat().recordingCreat(shiftData['classId'], shiftData['siteId'], 'post') | ||
| 258 | + } else { | ||
| 259 | + return false | ||
| 260 | + } | ||
| 261 | + } | ||
| 262 | + res.send({ code: "0" }); | ||
| 263 | + } else { | ||
| 264 | + res.send({ code: "1", message: "无录制数据" }); | ||
| 265 | + } | ||
| 266 | + | ||
| 267 | +}) | ||
| 268 | + | ||
| 269 | +// 判断该视频文件是否存在 | ||
| 270 | +router.post('/fileExists', async function (req, res, next) { | ||
| 271 | + const body = req.body | ||
| 272 | + if (!body.siteId) { | ||
| 273 | + res.send({code: 2, message: "机构编码无效"}); | ||
| 274 | + return | ||
| 275 | + } | ||
| 276 | + if (!body.classId) { | ||
| 277 | + res.send({code: 3, message: "课堂号无效"}); | ||
| 278 | + return | ||
| 279 | + } | ||
| 280 | + | ||
| 281 | + // if(!body.classStartTime) { | ||
| 282 | + // res.send({ code: 4,message:"时间不存在" }); | ||
| 283 | + // return | ||
| 284 | + // } | ||
| 285 | + | ||
| 286 | + // 创建ObsClient实例 | ||
| 287 | + var obsClient = new ObsClient({ | ||
| 288 | + access_key_id: 'LHFQDCSI4AQVDMEBI5TQ', | ||
| 289 | + secret_access_key: '6iPZ2RM41cAFUvAmTSrjRS4vgjAP0bnwM9kiCXIk', | ||
| 290 | + server: 'obs.cn-north-4.myhuaweicloud.com' | ||
| 291 | + }); | ||
| 292 | + | ||
| 293 | + let isVideo = false | ||
| 294 | + let url = "" | ||
| 295 | + let Prefix = "" | ||
| 296 | + if (body.classStartTime) { | ||
| 297 | + Prefix = `oss/${body.siteId}/${body.classStartTime}/${body.classId}.mp4` | ||
| 298 | + obsClient.listObjects({ | ||
| 299 | + Bucket: 'mp4record', | ||
| 300 | + Prefix: Prefix, | ||
| 301 | + // MaxKeys:1 | ||
| 302 | + }, (err, result) => { | ||
| 303 | + if (err) { | ||
| 304 | + console.error('Error-->' + err); | ||
| 305 | + } else { | ||
| 306 | + if (result.CommonMsg.Status == 200) { | ||
| 307 | + let content = result.InterfaceResult.Contents | ||
| 308 | + if (content && content.length) { | ||
| 309 | + if (content[0].Key) { | ||
| 310 | + isVideo = true | ||
| 311 | + url = content[0].Key | ||
| 312 | + } | ||
| 313 | + } | ||
| 314 | + // for(let i=0;i<result.InterfaceResult.Contents.length;i++){ | ||
| 315 | + // let item = result.InterfaceResult.Contents[i] | ||
| 316 | + // if(item.Key && item.Key.indexOf(body.classId) > -1){ | ||
| 317 | + // isVideo = true | ||
| 318 | + // url = item.Key | ||
| 319 | + // break | ||
| 320 | + // } | ||
| 321 | + // } | ||
| 322 | + } | ||
| 323 | + } | ||
| 324 | + if (!isVideo) { | ||
| 325 | + let classUrl = `https://pclive.xuedianyun.com/pcBase/pclive2/release/index.html?portalIP=saas.xuedianyun.com&portalPort=80&classId=${body.classId}&channels=2&playRecord=1#/` | ||
| 326 | + res.send({code: 1, message: "文件未生成", classUrl}); | ||
| 327 | + } else { | ||
| 328 | + let classUrl = `https://xdymp4.xuedianyun.com/${url}` | ||
| 329 | + res.send({code: 0, message: "文件已生成", classUrl}); | ||
| 330 | + } | ||
| 331 | + // 关闭obsClient | ||
| 332 | + obsClient.close(); | ||
| 333 | + }); | ||
| 334 | + }else{ | ||
| 335 | + let classUrl = `https://pclive.xuedianyun.com/pcBase/pclive2/release/index.html?portalIP=saas.xuedianyun.com&portalPort=80&classId=${body.classId}&channels=2&playRecord=1#/` | ||
| 336 | + res.send({code: 1, message: "文件未生成", classUrl}); | ||
| 337 | + } | ||
| 338 | +}) | ||
| 339 | + | ||
| 340 | +module.exports = router; |
routes/index.js_bak
0 → 100644
| 1 | +var express = require('express'); | ||
| 2 | +var router = express.Router(); | ||
| 3 | +const { spawn, exec } = require('child_process'); | ||
| 4 | +const fs = require("fs"); | ||
| 5 | +var path = require('path') | ||
| 6 | +var ObsClient = require('esdk-obs-nodejs'); | ||
| 7 | + | ||
| 8 | +const method = require("../config/method") | ||
| 9 | +const config = require("../config/config") | ||
| 10 | + | ||
| 11 | +// const { GETCLASSURL, GETCLASSURLPARAMETER, PROJECTCATALOG, PROJECTWINCATALOG, BACKMEDIACONFIG } = config | ||
| 12 | +const { YesterdayTime, getRequestClassIds, dayTimeYMD } = method | ||
| 13 | + | ||
| 14 | +let siteIds = [] | ||
| 15 | + | ||
| 16 | +let classid = [] | ||
| 17 | +let classidPost = [] | ||
| 18 | +let parentData = {} | ||
| 19 | +var classobj = {}; | ||
| 20 | +let className = "" | ||
| 21 | +let yesterday = "" // get写入课堂的时间 | ||
| 22 | + | ||
| 23 | +// spawn("export DISPLAY=:7", { shell: true}) | ||
| 24 | + | ||
| 25 | +/** | ||
| 26 | + * | ||
| 27 | + * @param {*} id 课堂id | ||
| 28 | + */ | ||
| 29 | +class MediaCreat { | ||
| 30 | + constructor() { | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + // 取出所有数据 | ||
| 34 | + async allData() { | ||
| 35 | + const { startTime, endTime } = YesterdayTime() | ||
| 36 | + let fileConfig = new MediaCreat().getConfigFileJson() | ||
| 37 | + if (!fileConfig) return false | ||
| 38 | + className = siteIds.shift() | ||
| 39 | + const { GETCLASSURL, GETCLASSURLPARAMETER,classLastNumber } = JSON.parse(fileConfig) | ||
| 40 | + let page = 1 | ||
| 41 | + if (className) { | ||
| 42 | + let result = await getRequestClassIds(GETCLASSURL, className, GETCLASSURLPARAMETER.key, startTime, endTime, page) | ||
| 43 | + //parentData[result.data.data.siteId] = new Set() | ||
| 44 | + let resultList = result.data.data.list | ||
| 45 | + for (let j = 0; j < resultList.length; j++) { | ||
| 46 | + let item = resultList[j] | ||
| 47 | + let classId = item['classId'] | ||
| 48 | + let number = classId.substr(classId.length - 1, 1) | ||
| 49 | + if (classLastNumber.includes(number)){ | ||
| 50 | + classid.push(item) | ||
| 51 | + //parentData[result.data.data.siteId].add(classId) | ||
| 52 | + } | ||
| 53 | + } | ||
| 54 | + const { siteId, list, totalPage } = result.data.data | ||
| 55 | + for (let i = page += 1; i <= totalPage; i++) { | ||
| 56 | + let result = await getRequestClassIds(GETCLASSURL, className, GETCLASSURLPARAMETER.key, startTime, endTime, i) | ||
| 57 | + let resultList = result.data.data.list | ||
| 58 | + for (let j = 0; j < resultList.length; j++) { | ||
| 59 | + let item = resultList[j] | ||
| 60 | + let classId = item['classId'] | ||
| 61 | + let number = classId.substr(classId.length - 1, 1) | ||
| 62 | + if (classLastNumber.includes(number)) { | ||
| 63 | + classid.push(item) | ||
| 64 | + // parentData[result.data.data.siteId].add(classId) | ||
| 65 | + } | ||
| 66 | + } | ||
| 67 | + } | ||
| 68 | + // parentData[result.data.data.siteId] = Array.from(parentData[result.data.data.siteId]) | ||
| 69 | + if (siteIds.length) { | ||
| 70 | + return await new MediaCreat().allData() | ||
| 71 | + } | ||
| 72 | + this.wrieLog("去重前的classId:------>" + JSON.stringify(classid)) | ||
| 73 | + this.wrieLog("httpData:------>" + JSON.stringify(result.data)) | ||
| 74 | + return true | ||
| 75 | + } else { | ||
| 76 | + return false | ||
| 77 | + } | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + wrieLog(text) { | ||
| 81 | + // 写入log | ||
| 82 | + let logFile = `./log/${dayTimeYMD().ymd}.txt` | ||
| 83 | + fs.appendFileSync(logFile, new Date().toLocaleString() + " " + text + '\r\n'); | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + recordingCreat(id, siteId, type) { | ||
| 87 | + this.wrieLog(" 课堂录制开始:------>" + id) | ||
| 88 | + let fileConfig = this.getConfigFileJson() | ||
| 89 | + if (!fileConfig) return false | ||
| 90 | + const { BACKMEDIACONFIG, PROJECTWINCATALOG, PROJECTCATALOG } = JSON.parse(fileConfig) | ||
| 91 | + let mediaDir = PROJECTCATALOG + "/media/" | ||
| 92 | + let classDir = PROJECTCATALOG + "/media/" + siteId | ||
| 93 | + let ymdDir = null | ||
| 94 | + if (type == 'post') { | ||
| 95 | + ymdDir = PROJECTCATALOG + "/media/" + siteId + "/" + dayTimeYMD().ymd | ||
| 96 | + } else { | ||
| 97 | + // get 的目录创建为上一天日期 | ||
| 98 | + ymdDir = PROJECTCATALOG + "/media/" + siteId + "/" + yesterday | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + if (!fs.existsSync(mediaDir)) { | ||
| 102 | + fs.mkdirSync(mediaDir); | ||
| 103 | + } | ||
| 104 | + if (!fs.existsSync(classDir)) { | ||
| 105 | + fs.mkdirSync(classDir); | ||
| 106 | + } | ||
| 107 | + if (!fs.existsSync(ymdDir)) { | ||
| 108 | + fs.mkdirSync(ymdDir); | ||
| 109 | + } | ||
| 110 | + let files = fs.readdirSync(ymdDir); | ||
| 111 | + // let interValGetFile = setInterval(()=>{ | ||
| 112 | + this.wrieLog("files:" + files) | ||
| 113 | + if (files.indexOf(id + ".mp4") != -1) { | ||
| 114 | + this.wrieLog("已存在:" + id + "课堂号,停止继续录制") | ||
| 115 | + if (type == 'post') { | ||
| 116 | + if (classidPost.length) { | ||
| 117 | + let shiftData = classidPost.shift() | ||
| 118 | + this.wrieLog(" 录制下一节课 课堂号:" + shiftData['classId']) | ||
| 119 | + this.recordingCreat(shiftData['classId'], shiftData['siteId'], type) | ||
| 120 | + } | ||
| 121 | + } else { | ||
| 122 | + if (classid.length) { | ||
| 123 | + let shiftData = classid.shift() | ||
| 124 | + this.wrieLog(" 录制下一节课 课堂号:" + shiftData['classId']) | ||
| 125 | + this.recordingCreat(shiftData['classId'], shiftData['siteId'], type) | ||
| 126 | + } | ||
| 127 | + } | ||
| 128 | + return | ||
| 129 | + } | ||
| 130 | + // 目前url是linux的写法 win系统不支持 | ||
| 131 | + // export DISPLAY=:7 | ||
| 132 | + // let url = `${path.resolve(__dirname, PROJECTWINCATALOG+"/web_capture_c")} -o=${ymdDir}/${id}.mp4 -u="${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}&playRecord=${BACKMEDIACONFIG.playRecord}" -d=${BACKMEDIACONFIG.d} -s=${BACKMEDIACONFIG.s} -fa=${BACKMEDIACONFIG.fa} -k=${BACKMEDIACONFIG.k} -w=${BACKMEDIACONFIG.w} -h=${BACKMEDIACONFIG.h}` | ||
| 133 | + // console.log("url", url) | ||
| 134 | + let url = `${PROJECTWINCATALOG}/web_capture_c -o=${ymdDir}/${id}.mp4 -u="${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}&playRecord=${BACKMEDIACONFIG.playRecord}&language=zh-cn" -d=${BACKMEDIACONFIG.d} -s=${BACKMEDIACONFIG.s} -fa=${BACKMEDIACONFIG.fa} -k=${BACKMEDIACONFIG.k} -w=${BACKMEDIACONFIG.w} -h=${BACKMEDIACONFIG.h}` | ||
| 135 | + exec(url, { maxBuffer: 1073741824 }, (err, stdout, stderr) => { | ||
| 136 | + if (err != null) { | ||
| 137 | + this.wrieLog(" 错误" + id + ":" + err) | ||
| 138 | + this.wrieLog(" 错误 stdout" + id + ":" + stdout) | ||
| 139 | + this.wrieLog(" 错误 stderr" + id + ":" + stderr) | ||
| 140 | + return | ||
| 141 | + } | ||
| 142 | + let files = fs.readdirSync(ymdDir); | ||
| 143 | + // let interValGetFile = setInterval(()=>{ | ||
| 144 | + if (files.indexOf(id + ".mp4") == -1) { | ||
| 145 | + this.wrieLog(" 课堂录制未发现该" + id + "课堂号") | ||
| 146 | + } else { | ||
| 147 | + if (type == 'get') { | ||
| 148 | + if (classid.length) { | ||
| 149 | + let shiftData = classid.shift() | ||
| 150 | + this.wrieLog(" 录制下一节课 课堂号:" + shiftData['classId']) | ||
| 151 | + this.recordingCreat(shiftData['classId'], shiftData['siteId'], type) | ||
| 152 | + } else { | ||
| 153 | + this.wrieLog("录制结束:------>") | ||
| 154 | + fs.writeFile(ymdDir + "/download.json", `{ "code": "0", "success": "ok"}`, function (err) { | ||
| 155 | + if (err) { | ||
| 156 | + console.log(err); | ||
| 157 | + } | ||
| 158 | + }); | ||
| 159 | + } | ||
| 160 | + } else { | ||
| 161 | + if (classidPost.length) { | ||
| 162 | + let shiftData = classidPost.shift() | ||
| 163 | + this.wrieLog(" 录制下一节课 课堂号:" + shiftData['classId']) | ||
| 164 | + this.recordingCreat(shiftData['classId'], shiftData['siteId'], type) | ||
| 165 | + } else { | ||
| 166 | + this.wrieLog("录制结束:------>") | ||
| 167 | + fs.writeFile(ymdDir + "/download.json", `{ "code": "0", "success": "ok"}`, function (err) { | ||
| 168 | + if (err) { | ||
| 169 | + console.log(err); | ||
| 170 | + } | ||
| 171 | + }); | ||
| 172 | + } | ||
| 173 | + } | ||
| 174 | + | ||
| 175 | + } | ||
| 176 | + }) | ||
| 177 | + } | ||
| 178 | + | ||
| 179 | + getConfigFileJson() { | ||
| 180 | + const buffer = fs.readFileSync(process.cwd() + "/config/config.json") | ||
| 181 | + return String(buffer) | ||
| 182 | + } | ||
| 183 | +} | ||
| 184 | + | ||
| 185 | + | ||
| 186 | +router.get('/recording', async function (req, res, next) { | ||
| 187 | + if (classid.length > 0) { | ||
| 188 | + // 有正在录制中的课堂,禁止重复 | ||
| 189 | + res.send({ code: "1", message: "有正在录制中的课堂", data: classid }); | ||
| 190 | + return | ||
| 191 | + } | ||
| 192 | + new MediaCreat().wrieLog("脚本录制开始:------>") | ||
| 193 | + let fileConfig = new MediaCreat().getConfigFileJson() | ||
| 194 | + if (!fileConfig) return false | ||
| 195 | + | ||
| 196 | + const { GETCLASSURLPARAMETER } = JSON.parse(fileConfig) | ||
| 197 | + siteIds = GETCLASSURLPARAMETER.siteId | ||
| 198 | + if (siteIds.length == 0) { | ||
| 199 | + new MediaCreat().wrieLog("脚本录制,未配置siteId:------>" + siteIds) | ||
| 200 | + res.send({ code: "1", message: "未配置siteId", data: siteIds }); | ||
| 201 | + return | ||
| 202 | + } | ||
| 203 | + let result = await new MediaCreat().allData() | ||
| 204 | + if (result) { | ||
| 205 | + // 去重 | ||
| 206 | + classobj = {} | ||
| 207 | + classid = classid.reduce(function (item, next) { | ||
| 208 | + classobj[next.classId] ? '' : classobj[next.classId] = true && item.push(next); | ||
| 209 | + return item; | ||
| 210 | + }, []); | ||
| 211 | + // 写入log | ||
| 212 | + new MediaCreat().wrieLog("去重后的classid:------>" + JSON.stringify(classid)) | ||
| 213 | + if (classid.length) { | ||
| 214 | + for (let i = 0; i < GETCLASSURLPARAMETER.maxMedia; i++) { | ||
| 215 | + let shiftData = classid.shift() | ||
| 216 | + if (shiftData) { | ||
| 217 | + yesterday = YesterdayTime().ymd | ||
| 218 | + new MediaCreat().recordingCreat(shiftData['classId'], shiftData['siteId'], 'get') | ||
| 219 | + } else { | ||
| 220 | + return false | ||
| 221 | + } | ||
| 222 | + } | ||
| 223 | + res.send({ code: "0" }); | ||
| 224 | + } else { | ||
| 225 | + res.send({ code: "1", message: "无录制数据" }); | ||
| 226 | + } | ||
| 227 | + } else { | ||
| 228 | + res.send({ code: "1", message: "无录制数据" }); | ||
| 229 | + } | ||
| 230 | +}); | ||
| 231 | + | ||
| 232 | +/** | ||
| 233 | + * { | ||
| 234 | + * "classId":[{ classId: '389675110', siteId: 'kuaikuenglish' }] | ||
| 235 | + * } | ||
| 236 | + */ | ||
| 237 | +router.post('/recording', async function (req, res, next) { | ||
| 238 | + new MediaCreat().wrieLog("录制启动:------>") | ||
| 239 | + let fileConfig = new MediaCreat().getConfigFileJson() | ||
| 240 | + if (!fileConfig) return false | ||
| 241 | + let { classId, maxMedia } = req.body | ||
| 242 | + if (classidPost.length > 0) { | ||
| 243 | + // 有正在录制中的课堂,禁止重复 | ||
| 244 | + res.send({ code: "1", message: "有正在录制中的课堂", data: classidPost }); | ||
| 245 | + return | ||
| 246 | + } | ||
| 247 | + if (classId && classId.length) { | ||
| 248 | + classidPost = classId | ||
| 249 | + if (!maxMedia || maxMedia == undefined) { | ||
| 250 | + maxMedia = 1 | ||
| 251 | + } | ||
| 252 | + for (let i = 0; i < maxMedia; i++) { | ||
| 253 | + let shiftData = classidPost.shift() | ||
| 254 | + if (shiftData) { | ||
| 255 | + new MediaCreat().recordingCreat(shiftData['classId'], shiftData['siteId'], 'post') | ||
| 256 | + } else { | ||
| 257 | + return false | ||
| 258 | + } | ||
| 259 | + } | ||
| 260 | + res.send({ code: "0" }); | ||
| 261 | + } else { | ||
| 262 | + res.send({ code: "1", message: "无录制数据" }); | ||
| 263 | + } | ||
| 264 | + | ||
| 265 | +}) | ||
| 266 | + | ||
| 267 | +// 判断该视频文件是否存在 | ||
| 268 | +router.post('/fileExists', async function (req, res, next) { | ||
| 269 | + const body = req.body | ||
| 270 | + if(!body.siteId) { | ||
| 271 | + res.send({ code: 2,message:"机构编码无效" }); | ||
| 272 | + return | ||
| 273 | + } | ||
| 274 | + if(!body.classId) { | ||
| 275 | + res.send({ code: 3,message:"课堂号无效" }); | ||
| 276 | + return | ||
| 277 | + } | ||
| 278 | + | ||
| 279 | + // 创建ObsClient实例 | ||
| 280 | + var obsClient = new ObsClient({ | ||
| 281 | + access_key_id: 'FY27OD11ZJVC385AOTW9', | ||
| 282 | + secret_access_key: 'ZqnfRjaseCtuRbE79GvqkPiYUdT83ZbB0oU7fBo3', | ||
| 283 | + server : 'obs.cn-north-4.myhuaweicloud.com' | ||
| 284 | + }); | ||
| 285 | + | ||
| 286 | + let isVideo = false | ||
| 287 | + let url = "" | ||
| 288 | + obsClient.listObjects({ | ||
| 289 | + Bucket : 'xdymp4' | ||
| 290 | + }, (err, result) => { | ||
| 291 | + if(err){ | ||
| 292 | + console.error('Error-->' + err); | ||
| 293 | + }else{ | ||
| 294 | + if(result.CommonMsg.Status == 200){ | ||
| 295 | + for(let i=0;i<result.InterfaceResult.Contents.length;i++){ | ||
| 296 | + let item = result.InterfaceResult.Contents[i] | ||
| 297 | + if(item.Key && item.Key.indexOf(body.classId) > -1){ | ||
| 298 | + isVideo = true | ||
| 299 | + url = item.Key | ||
| 300 | + break | ||
| 301 | + } | ||
| 302 | + } | ||
| 303 | + } | ||
| 304 | + } | ||
| 305 | + if(!isVideo){ | ||
| 306 | + let classUrl = `https://pclive.xuedianyun.com/pcBase/pclive2/release/index.html?portalIP=saas.xuedianyun.com&portalPort=80&classId=${body.classId}&channels=2&playRecord=1#/` | ||
| 307 | + res.send({ code: 1,message:"文件未生成",classUrl }); | ||
| 308 | + }else{ | ||
| 309 | + let classUrl = `https://xdymp4.xuedianyun.com/${url}` | ||
| 310 | + res.send({ code: 0,message:"文件已生成",classUrl }); | ||
| 311 | + } | ||
| 312 | + // 关闭obsClient | ||
| 313 | + obsClient.close(); | ||
| 314 | + }); | ||
| 315 | +}) | ||
| 316 | + | ||
| 317 | +module.exports = router; |
routes/users.js
100755 → 100644
views/error.jade
100755 → 100644
views/index.jade
100755 → 100644
views/layout.jade
100755 → 100644
-
请 注册 或 登录 后发表评论