2022-05-13 15:13:02 +02:00

104 lines
3.0 KiB
JavaScript

const fs = require("fs")
const loadash = require("lodash")
const mkdirp = require("mkdirp")
const Logger = require("../lib/logger")
const FissionSession = require("../sessionsModels/fission_session")
const { getFFmpegVersion, getFFmpegUrl } = require("../lib/utils")
const context = require("../ctx")
class NodeFissionServer {
constructor(config) {
this.config = config
this.fissionSessions = new Map()
}
async run() {
try {
mkdirp.sync(this.config.mediaroot)
fs.accessSync(this.config.mediaroot, fs.constants.W_OK)
} catch (error) {
Logger.error(`Node Media Fission Server startup failed. MediaRoot:${this.config.mediaroot} cannot be written.`)
return
}
try {
fs.accessSync(this.config.fission.ffmpeg, fs.constants.X_OK)
} catch (error) {
Logger.error(`Node Media Fission Server startup failed. ffmpeg:${this.config.fission.ffmpeg} cannot be executed.`)
return
}
let version = await getFFmpegVersion(this.config.fission.ffmpeg)
if (version === "" || parseInt(version.split(".")[0]) < 4) {
Logger.error("Node Media Fission Server startup failed. ffmpeg requires version 4.0.0 above")
Logger.error("Download the latest ffmpeg static program:", getFFmpegUrl())
return
}
context.nodeEvent.on("postPublish", this.onPostPublish.bind(this))
context.nodeEvent.on("donePublish", this.onDonePublish.bind(this))
Logger.log(`Node Media Fission Server started, MediaRoot: ${this.config.mediaroot}, ffmpeg version: ${version}`)
}
async onPostPublish(id, streamPath, args) {
const fixedStreamingKey = streamPath.split("/").pop()
const userspace = await global.resolveUserspaceOfStreamingKey(fixedStreamingKey)
if (!userspace) {
console.error("No userspace found for streaming key:", fixedStreamingKey)
return false
}
let regRes = /\/(.*)\/(.*)/gi.exec(streamPath)
let [app, name] = loadash.slice(regRes, 1)
for (let task of this.config.fission.tasks) {
regRes = /(.*)\/(.*)/gi.exec(task.rule)
let [ruleApp, ruleName] = loadash.slice(regRes, 1)
if ((app === ruleApp || ruleApp === "*") && (name === ruleName || ruleName === "*")) {
let s = context.sessions.get(id)
if (s.isLocal && name.split("_")[1]) {
continue
}
let conf = task
conf.ffmpeg = this.config.fission.ffmpeg
conf.mediaroot = this.config.mediaroot
conf.rtmpPort = this.config.rtmp.port
conf.streamPath = streamPath
conf.streamApp = app
conf.streamName = name
conf.fixedStreamName = userspace.username
conf.args = args
let session = new FissionSession(conf)
this.fissionSessions.set(id, session)
session.on("end", () => {
this.fissionSessions.delete(id)
})
session.run()
}
}
}
onDonePublish(id, streamPath, args) {
let session = this.fissionSessions.get(id)
if (session) {
session.end()
}
}
}
module.exports = NodeFissionServer