index.js 13.3 KB
var express = require('express');
var router = express.Router();
const { spawn, exec } = require('child_process');
const fs = require("fs");
var path = require('path')
var ObsClient = require('esdk-obs-nodejs');

const method = require("../config/method")
const config = require("../config/config")

// const { GETCLASSURL, GETCLASSURLPARAMETER, PROJECTCATALOG, PROJECTWINCATALOG, BACKMEDIACONFIG } = config
const { YesterdayTime, getRequestClassIds, dayTimeYMD } = method

let siteIds = []

let classid = []
let classidPost = []
let parentData = {}
var classobj = {};
let className = ""

// spawn("export DISPLAY=:7", { shell: true})

/**
 *
 * @param {*} id 课堂id
 */
class MediaCreat {
    constructor() {
    }

    // 取出所有数据
    async allData() {
        const { startTime, endTime } = YesterdayTime()
        let fileConfig = new MediaCreat().getConfigFileJson()
        if (!fileConfig) return false
        className = siteIds.shift()
        const { GETCLASSURL, GETCLASSURLPARAMETER } = JSON.parse(fileConfig)
        let page = 1
        if (className) {
            let result = await getRequestClassIds(GETCLASSURL, className, GETCLASSURLPARAMETER.key, startTime, endTime, page)
            parentData[result.data.data.siteId] = new Set()
            for (let j = 0; j < result.data.data.list.length; j++) {
                classid.push(result.data.data.list[j])
                parentData[result.data.data.siteId].add(result.data.data.list[j]['classId'])
            }
            const { siteId, list, totalPage } = result.data.data
            for (let i = page += 1; i <= totalPage; i++) {
                let result = await getRequestClassIds(GETCLASSURL, className, GETCLASSURLPARAMETER.key, startTime, endTime, i)
                for (let j = 0; j < result.data.data.list.length; j++) {
                    classid.push(result.data.data.list[j])
                    parentData[result.data.data.siteId].add(result.data.data.list[j]['classId'])
                }
            }
            parentData[result.data.data.siteId] = Array.from(parentData[result.data.data.siteId])
            if (siteIds.length) {
                return await new MediaCreat().allData()
            }
            this.wrieLog("去重前的classId:------>" + JSON.stringify(classid))
            this.wrieLog("httpData:------>" + JSON.stringify(result.data))
            return true
        } else {
            return false
        }
    }

    wrieLog(text) {
        // 写入log
        let logFile = `./log/${dayTimeYMD().ymd}.txt`
        fs.appendFileSync(logFile, new Date().toLocaleString() + " " + text + '\r\n');
    }

    recordingCreat(id, siteId, type) {
        this.wrieLog(" 课堂录制开始:------>" + id)
        let fileConfig = this.getConfigFileJson()
        if (!fileConfig) return false
        const { BACKMEDIACONFIG, PROJECTWINCATALOG, PROJECTCATALOG } = JSON.parse(fileConfig)
        let mediaDir = PROJECTCATALOG + "/media/"
        let classDir = PROJECTCATALOG + "/media/" + siteId
        let ymdDir = null
        if (type == 'post') {
            ymdDir = PROJECTCATALOG + "/media/" + siteId + "/" + dayTimeYMD().ymd
        } else {
            // get 的目录创建为上一天日期
            ymdDir = PROJECTCATALOG + "/media/" + siteId + "/" + YesterdayTime().ymd
        }

        if (!fs.existsSync(mediaDir)) {
            fs.mkdirSync(mediaDir);
        }
        if (!fs.existsSync(classDir)) {
            fs.mkdirSync(classDir);
        }
        if (!fs.existsSync(ymdDir)) {
            fs.mkdirSync(ymdDir);
        }
        let files = fs.readdirSync(ymdDir);
        // let interValGetFile = setInterval(()=>{
        this.wrieLog("files:" + files)
        if (files.indexOf(id + ".mp4") != -1) {
            this.wrieLog("已存在:" + id + "课堂号,停止继续录制")
            if (type == 'post') {
                if (classidPost.length) {
                    let shiftData = classidPost.shift()
                    this.wrieLog(" 录制下一节课 课堂号:" + shiftData['classId'])
                    this.recordingCreat(shiftData['classId'], shiftData['siteId'], type)
                }
            } else {
                if (classid.length) {
                    let shiftData = classid.shift()
                    this.wrieLog(" 录制下一节课 课堂号:" + shiftData['classId'])
                    this.recordingCreat(shiftData['classId'], shiftData['siteId'], type)
                }
            }
            return
        }
        // 目前url是linux的写法 win系统不支持
        // export DISPLAY=:7
        // 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}`
        // console.log("url", url)
        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`
        exec(url, { maxBuffer: 1073741824 }, (err, stdout, stderr) => {
            if (err != null) {
                this.wrieLog(" 错误" + id + ":" + err)
                this.wrieLog(" 错误 stdout" + id + ":" + stdout)
                this.wrieLog(" 错误 stderr" + id + ":" + stderr)
                return
            }
            let files = fs.readdirSync(ymdDir);
            // let interValGetFile = setInterval(()=>{
            if (files.indexOf(id + ".mp4") == -1) {
                this.wrieLog(" 课堂录制未发现该" + id + "课堂号")
            } else {
                if (type == 'get') {
                    if (classid.length) {
                        let shiftData = classid.shift()
                        this.wrieLog(" 录制下一节课 课堂号:" + shiftData['classId'])
                        this.recordingCreat(shiftData['classId'], shiftData['siteId'], type)
                    } else {
                        this.wrieLog("录制结束:------>")
                        fs.writeFile(ymdDir + "/download.json", `{ "code": "0", "success": "ok"}`, function (err) {
                            if (err) {
                                console.log(err);
                            }
                        });
                    }
                } else {
                    if (classidPost.length) {
                        let shiftData = classidPost.shift()
                        this.wrieLog(" 录制下一节课 课堂号:" + shiftData['classId'])
                        this.recordingCreat(shiftData['classId'], shiftData['siteId'], type)
                    } else {
                        this.wrieLog("录制结束:------>")
                        fs.writeFile(ymdDir + "/download.json", `{ "code": "0", "success": "ok"}`, function (err) {
                            if (err) {
                                console.log(err);
                            }
                        });
                    }
                }

            }
        })
    }

    getConfigFileJson() {
        const buffer = fs.readFileSync(process.cwd() + "/config/config.json")
        return String(buffer)
    }
}


router.get('/recording', async function (req, res, next) {
    if (classid.length > 0) {
        // 有正在录制中的课堂,禁止重复
        res.send({ code: "1", message: "有正在录制中的课堂", data: classid });
        return
    }
    new MediaCreat().wrieLog("脚本录制开始:------>")
    let fileConfig = new MediaCreat().getConfigFileJson()
    if (!fileConfig) return false

    const { GETCLASSURLPARAMETER } = JSON.parse(fileConfig)
    siteIds = GETCLASSURLPARAMETER.siteId
    if (siteIds.length == 0) {
        new MediaCreat().wrieLog("脚本录制,未配置siteId:------>" + siteIds)
        res.send({ code: "1", message: "未配置siteId", data: siteIds });
        return
    }
    let result = await new MediaCreat().allData()
    if (result) {
        // 去重
        classobj = {}
        classid = classid.reduce(function (item, next) {
            classobj[next.classId] ? '' : classobj[next.classId] = true && item.push(next);
            return item;
        }, []);
        // 写入log
        new MediaCreat().wrieLog("去重后的classid:------>" + JSON.stringify(classid))
        if (classid.length) {
            for (let i = 0; i < GETCLASSURLPARAMETER.maxMedia; i++) {
                let shiftData = classid.shift()
                if (shiftData) {
                    new MediaCreat().recordingCreat(shiftData['classId'], shiftData['siteId'], 'get')
                } else {
                    return false
                }
            }
            res.send({ code: "0" });
        } else {
            res.send({ code: "1", message: "无录制数据" });
        }
    } else {
        res.send({ code: "1", message: "无录制数据" });
    }
});

/**
 * {
 * "classId":[{ classId: '389675110', siteId: 'kuaikuenglish' }]
 * }
 */
router.post('/recording', async function (req, res, next) {
    new MediaCreat().wrieLog("录制启动:------>")
    let fileConfig = new MediaCreat().getConfigFileJson()
    if (!fileConfig) return false
    let { classId, maxMedia } = req.body
    if (classidPost.length > 0) {
        // 有正在录制中的课堂,禁止重复
        res.send({ code: "1", message: "有正在录制中的课堂", data: classidPost });
        return
    }
    if (classId && classId.length) {
        classidPost = classId
        if (!maxMedia || maxMedia == undefined) {
            maxMedia = 1
        }
        for (let i = 0; i < maxMedia; i++) {
            let shiftData = classidPost.shift()
            if (shiftData) {
                new MediaCreat().recordingCreat(shiftData['classId'], shiftData['siteId'], 'post')
            } else {
                return false
            }
        }
        res.send({ code: "0" });
    } else {
        res.send({ code: "1", message: "无录制数据" });
    }

})

// 判断该视频文件是否存在
router.post('/fileExists', async function (req, res, next) {
    const body = req.body
    if (!body.siteId) {
        res.send({code: 2, message: "机构编码无效"});
        return
    }
    if (!body.classId) {
        res.send({code: 3, message: "课堂号无效"});
        return
    }

    // if(!body.classStartTime) {
    //     res.send({ code: 4,message:"时间不存在" });
    //     return
    // }

    // 创建ObsClient实例
    var obsClient = new ObsClient({
        access_key_id: 'FY27OD11ZJVC385AOTW9',
        secret_access_key: 'ZqnfRjaseCtuRbE79GvqkPiYUdT83ZbB0oU7fBo3',
        server: 'obs.cn-north-4.myhuaweicloud.com'
    });

    let isVideo = false
    let url = ""
    let Prefix = ""
    if (body.classStartTime) {
        Prefix = `oss/${body.siteId}/${body.classStartTime}/${body.classId}.mp4`
        obsClient.listObjects({
            Bucket: 'xdymp4',
            Prefix: Prefix,
            // MaxKeys:1
        }, (err, result) => {
            if (err) {
                console.error('Error-->' + err);
            } else {
                if (result.CommonMsg.Status == 200) {
                    let content = result.InterfaceResult.Contents
                    if (content && content.length) {
                        if (content[0].Key) {
                            isVideo = true
                            url = content[0].Key
                        }
                    }
                    // for(let i=0;i<result.InterfaceResult.Contents.length;i++){
                    //     let item = result.InterfaceResult.Contents[i]
                    //     if(item.Key && item.Key.indexOf(body.classId) > -1){
                    //         isVideo = true
                    //         url = item.Key
                    //         break
                    //     }
                    // }
                }
            }
            if (!isVideo) {
                let classUrl = `https://pclive.xuedianyun.com/pcBase/pclive2/release/index.html?portalIP=saas.xuedianyun.com&portalPort=80&classId=${body.classId}&channels=2&playRecord=1#/`
                res.send({code: 1, message: "文件未生成", classUrl});
            } else {
                let classUrl = `https://xdymp4.xuedianyun.com/${url}`
                res.send({code: 0, message: "文件已生成", classUrl});
            }
            // 关闭obsClient
            obsClient.close();
        });
    }else{
        let classUrl = `https://pclive.xuedianyun.com/pcBase/pclive2/release/index.html?portalIP=saas.xuedianyun.com&portalPort=80&classId=${body.classId}&channels=2&playRecord=1#/`
        res.send({code: 1, message: "文件未生成", classUrl});
    }
})

module.exports = router;