From f7733b9507aef0fed112d483b44656b905992a93 Mon Sep 17 00:00:00 2001 From: knotteye Date: Sat, 21 Dec 2019 08:59:35 -0600 Subject: [PATCH] Big Refactor Stop using config and toml as dependencies Stop passing around config variables through function calls Add config.ts and pull the values you need directly in the files Remove irc.js for incoming new IRC solution Rename controller to index because that was stupid Minor git bullshit with the config folder Change to yaml as a config format --- .gitignore | 6 +- config/.gitkeep | 0 config/default.toml | 58 ---------- install/config.example.yml | 24 ++++ install/setup.sh | 6 +- install/template.local.toml | 19 ---- package-lock.json | 58 ++++++++++ package.json | 8 +- src/api.ts | 15 +-- src/cli.ts | 3 +- src/config.ts | 49 +++++++++ src/controller.ts | 67 ------------ src/database.ts | 15 +-- src/http.ts | 56 ++++------ src/index.ts | 15 +++ src/irc.js | 212 ------------------------------------ src/server.ts | 35 +++--- 17 files changed, 208 insertions(+), 438 deletions(-) create mode 100644 config/.gitkeep delete mode 100644 config/default.toml create mode 100644 install/config.example.yml delete mode 100644 install/template.local.toml create mode 100644 src/config.ts delete mode 100644 src/controller.ts create mode 100644 src/index.ts delete mode 100644 src/irc.js diff --git a/.gitignore b/.gitignore index 116395e..8c8153b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,6 @@ node_modules site/live -config/local.toml -config/jwt.pem -config/generated.toml -config/bans.db +config/**/* +!config/.gitkeep install/db_setup.sql build/** diff --git a/config/.gitkeep b/config/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/config/default.toml b/config/default.toml deleted file mode 100644 index 21b7055..0000000 --- a/config/default.toml +++ /dev/null @@ -1,58 +0,0 @@ -#DO NOT EDIT THIS FILE -#ALL CHANGES SHOULD GO IN LOCAL.TOML -[bcrypt] -saltRounds = 12 - -[satyr] -name = '' -domain = '' -registration = false -restrictedNames = ['live'] -rootredirect = '/users/live' - -[ircd] -enable = false -port = 6667 -sid = '' -server = '' -pass = '' -vhost = 'web.satyr.net' - -[database] -host = 'localhost' -user = 'satyr' -password = '' -database = 'satyr_db' -connectionLimit = '50' -connectionTimeout = '1000' -insecureAuth = false -debug = false - -[server] -logs = 0 -api = false -api_user = false -api_pass = false - -[server.rtmp] -port = 1935 -chunk_size = 6000 -gop_cache = true -ping = 30 -ping_timeout = 60 - -[server.http] -hsts = false -directory = './site' -port = 8000 - -[media] -record = false -publicEndpoint = 'live' -privateEndpoint = 'stream' -ffmpeg = '' - -[transcode] -adapative = false -variants = 3 -format = 'dash' \ No newline at end of file diff --git a/install/config.example.yml b/install/config.example.yml new file mode 100644 index 0000000..4f4ee13 --- /dev/null +++ b/install/config.example.yml @@ -0,0 +1,24 @@ +satyr: + name: '' + domain: '' + email: '' + registration: false + +media: + record: false + ffmpeg: '' + +http: + # uncomment to set HSTS when SSL is ready + #hsts: true + +database: + user: '' + password: '' + database: '' + host: '' + +transcode: + adaptive: false + format: dash + variants: 3 \ No newline at end of file diff --git a/install/setup.sh b/install/setup.sh index 6741d48..e4a153a 100644 --- a/install/setup.sh +++ b/install/setup.sh @@ -38,8 +38,8 @@ dbclient="${dbclient:='*'}" else dbclient="localhost" fi -sed -e "s##$name#g" -e "s##$domain#g" -e "s##$ffmpeg#g" -e "s##$dbuser#g" -e "s##$dbname#g" -e "s##$dbpass#g" -e "s##$dbhost#g" -e "s##$email#g" install/template.local.toml > config/generated.toml +sed -e "s##$name#g" -e "s##$domain#g" -e "s##$ffmpeg#g" -e "s##$dbuser#g" -e "s##$dbname#g" -e "s##$dbpass#g" -e "s##$dbhost#g" -e "s##$email#g" install/config.example.yml > config/generated.yml sed -e "s##$dbuser#g" -e "s##$dbname#g" -e "s##$dbpass#g" -e "s##$dbhost#g" -e "s##$dbclient#g" install/db_template.sql > install/db_setup.sql echo "A setup script for the database has been generated at install/db_setup.sql. Please run it by connecting to your database software and executing 'source install/db_setup.sql;''" -echo "A default configuration file has been generated at config/generated.toml" -echo "If everything looks fine, move it to config/local.toml and start your instance." \ No newline at end of file +echo "A default configuration file has been generated at config/generated.yml" +echo "If everything looks fine, move it to config/config.yml and start your instance." \ No newline at end of file diff --git a/install/template.local.toml b/install/template.local.toml deleted file mode 100644 index bb32b64..0000000 --- a/install/template.local.toml +++ /dev/null @@ -1,19 +0,0 @@ -[satyr] -name = '' -domain = '' -email = '' -registration = false - -[media] -record = false -ffmpeg = '' - -[server.http] -# uncomment to set HSTS when SSL is enabled -# hsts = true - -[database] -user = '' -password = '' -database = '' -host = '' diff --git a/package-lock.json b/package-lock.json index 379f6ce..b0e10eb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -82,6 +82,11 @@ "readable-stream": "^2.0.6" } }, + "arg": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.2.tgz", + "integrity": "sha512-+ytCkGcBtHZ3V2r2Z06AncYO8jz46UEamcspGoU8lHcEbpn6J77QK0vdWvChsclg/tM5XIJC5tnjmPp7Eq6Obg==" + }, "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", @@ -342,6 +347,11 @@ } } }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", @@ -644,6 +654,11 @@ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" }, + "diff": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", + "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==" + }, "dirty": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/dirty/-/dirty-1.1.0.tgz", @@ -1910,6 +1925,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==" + }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", @@ -2292,6 +2312,11 @@ "os-tmpdir": "^1.0.0" } }, + "parse-yaml": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/parse-yaml/-/parse-yaml-0.1.0.tgz", + "integrity": "sha512-tLfs2QiziUPFTA4nNrv2rrC0CnHDIF2o2m5TCgNss/E0asI0ltVjBcNKhcd/8vteZa8xKV5RGfD0ZFFlECMCqQ==" + }, "parseqs": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", @@ -2868,6 +2893,22 @@ "urix": "^0.1.0" } }, + "source-map-support": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, "source-map-url": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", @@ -3029,6 +3070,18 @@ "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==" }, + "ts-node": { + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.5.4.tgz", + "integrity": "sha512-izbVCRV68EasEPQ8MSIGBNK9dc/4sYJJKYA+IarMQct1RtEot6Xp0bXuClsbUSnKpg50ho+aOAx8en5c+y4OFw==", + "requires": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "^3.0.0" + } + }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -3201,6 +3254,11 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" } } } diff --git a/package.json b/package.json index 82dcedf..a5012b2 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,8 @@ "license": "AGPL-3.0", "author": "knotteye", "scripts": { - "start": "tsc && node build/controller.js", - "user": "node build/cli.js", + "start": "ts-node src/index.ts", + "user": "ts-node src/cli.ts", "setup": "sh install/setup.sh" }, "repository": { @@ -16,7 +16,6 @@ "dependencies": { "bcrypt": "^3.0.6", "body-parser": "^1.19.0", - "config": "^3.2.2", "cookie-parser": "^1.4.4", "dirty": "^1.1.0", "express": "^4.17.1", @@ -25,11 +24,12 @@ "mysql": "^2.17.1", "node-media-server": ">=2.1.3 <3.0.0", "nunjucks": "^3.2.0", + "parse-yaml": "^0.1.0", "recursive-readdir": "^2.2.2", "socket-anti-spam": "^2.0.0", "socket.io": "^2.3.0", "strftime": "^0.10.0", - "toml": "^3.0.0", + "ts-node": "^8.5.4", "typescript": "^3.6.3" }, "devDependencies": { diff --git a/src/api.ts b/src/api.ts index 7ff9944..bd9a853 100644 --- a/src/api.ts +++ b/src/api.ts @@ -1,17 +1,12 @@ import * as db from "./database" -import { unregisterUser } from "./irc"; - -var config: any; -function init(conf: object){ - config = conf; -} +import { config } from "./config"; async function register(name: string, password: string, confirm: string) { - if(!config.registration) return {"error":"registration disabled"}; + if(!config['satyr']['registration']) return {"error":"registration disabled"}; if(name.includes(';') || name.includes(' ') || name.includes('\'')) return {"error":"illegal characters"}; if(password !== confirm) return {"error":"mismatched passwords"}; - for(let i=0;i { res.append('Strict-Transport-Security', 'max-age=5184000'); next(); @@ -56,11 +55,11 @@ async function init(satyr: any, http: object, irc: any){ } app.disable('x-powered-by'); //site handlers - await initSite(satyr.registration); + await initSite(config['satyr']['registration']); //api handlers await initAPI(); //static files if nothing else matches first - app.use(express.static(satyr.directory)); + app.use(express.static(config['http']['directory'])); //404 Handler app.use(function (req, res, next) { if(tryDecode(req.cookies.Authorization)) { @@ -70,7 +69,7 @@ async function init(satyr: any, http: object, irc: any){ //res.status(404).render('404.njk', njkconf); }); banlist = new dirty('./config/bans.db').on('load', () => {initChat()}); - server.listen(http['port']); + server.listen(config['http']['port']); } async function newNick(socket, skip?: boolean, i?: number) { @@ -336,23 +335,17 @@ async function initSite(openReg) { } async function initChat() { - //irc peering - if(ircconf.enable){ - await irc.connect({ - port: ircconf.port, - sid: ircconf.sid, - pass: ircconf.pass, - server: ircconf.server, - vhost: ircconf.vhost - }); - irc.events.on('message', (nick, channel, msg) => { - io.to(channel).emit('MSG', {nick: nick, msg: msg}); - }); - } + //set a cookie to request same nick + //apply same nick if the request comes from the same ip + //structure of entry in store should be: + // knotteye: { + // ip: "127.0.0.1", + // id: ["aklsjdnaksj", "asjdnaksjnd", "aksjdnkajs"] + //} + //socket.io chat logic io.on('connection', async (socket) => { socket.nick = await newNick(socket); - if(ircconf.enable) irc.registerUser(socket.nick); socket.on('JOINROOM', async (data) => { let t: any = await db.query('select username from users where username='+db.raw.escape(data)); if(t[0]){ @@ -367,7 +360,6 @@ async function initChat() { } socket.join(data); io.to(data).emit('JOINED', {nick: socket.nick}); - if(ircconf.enable) irc.join(socket.nick, data); } else socket.emit('ALERT', 'Room does not exist'); }); @@ -388,16 +380,13 @@ async function initChat() { }); socket.on('LEAVEROOM', (data) => { socket.leave(data); - if(ircconf.enable) irc.part(socket.nick, data); io.to(data).emit('LEFT', {nick: socket.nick}); }); socket.on('disconnecting', (reason) => { let rooms = Object.keys(socket.rooms); for(let i=1;i { @@ -424,7 +413,6 @@ async function initChat() { socket.on('MSG', (data) => { if(data.msg === "" || !data.msg.replace(/\s/g, '').length) return; io.to(data.room).emit('MSG', {nick: socket.nick, msg: data.msg}); - if(ircconf.enable) irc.send(socket.nick, data.room, data.msg); }); socket.on('KICK', (data) => { if(socket.nick === data.room){ @@ -491,10 +479,8 @@ async function initChat() { socketAS.event.on('ban', (socket) => { let rooms = Object.keys(socket.rooms); for(let i=1;i -// thanks nikki - -const net = require('net') -const EventEmitter = require('events') - -const socket = new net.Socket() -const emitter = new EventEmitter() - -socket.setEncoding('utf8') - -socket.on('error', console.error) - -function m (text) { - console.log('> ' + text) - socket.write(text + '\r\n') -} - -var config - -socket.once('connect', async () => { - console.log('Connected') - m(`PASS ${config.pass} TS 6 :${config.sid}`) - m('CAPAB QS ENCAP EX IE SAVE EUID') - m(`SERVER ${config.server} 1 satyr`) -}) - -function parseLine (l) { - const colIndex = l.lastIndexOf(':') - if (colIndex > -1) { - return { - params: l.substring(0, colIndex - 1).split(' '), - query: l.substring(colIndex + 1) - } - } else return { params: l.split(' ') } -} - -const servers = [] -const users = {} -const channels = {} - -const globalCommands = { - // PING :42X - // params: SID - PING: l => { - const { query } = parseLine(l) - m(`PONG :${query}`) - emitter.emit('ping') - }, - // PASS hunter2 TS 6 :42X - // params: password, 'TS', TS version, SID - PASS: l => { - const { query } = parseLine(l) - // adds a server - servers.push(query) - } -} - -const serverCommands = { - // EUID nik 1 1569146316 +i ~nik localhost6.attlocal.net 0::1 42XAAAAAB * * :nik - // params: nickname, hopcount, nickTS, umodes, username, visible hostname, IP address, UID, real hostname, account name, gecos - EUID: l => { - const { params } = parseLine(l) - const user = { - nick: params[0], - nickTS: params[2], - modes: params[3], - username: params[4], - vhost: params[5], - ip: params[6], - uid: params[7] - } - users[user.uid] = user - }, - // SJOIN 1569142987 #test +nt :42XAAAAAB - // params: channelTS, channel, simple modes, opt. mode parameters..., nicklist - SJOIN: l => { - const { params, query } = parseLine(l) - const channel = { - timestamp: params[0], - name: params[1], - modes: params.slice(2).join(' '), - nicklist: query.split(' ').map(uid => { - if (/[^0-9a-zA-Z]/.test(uid[0])) return { uid: uid.slice(1), mode: uid[0] } - else return { uid: uid, mode: '' } - }) - } - channels[channel.name] = channel - } -} - -const userCommands = { - // :42XAAAAAC PRIVMSG #test :asd - // params: target, msg - PRIVMSG: (l, source) => { - const { params, query } = parseLine(l) - emitter.emit('message', users[source].nick, params[0], query) - }, - // :42XAAAAAC JOIN 1569149395 #test + - JOIN: (l, source) => { - const { params } = parseLine(l) - channels[params[1]].nicklist.push({ - uid: source - }) - }, - // :42XAAAAAC PART #test :WeeChat 2.6 - PART: (l, source) => { - const { params } = parseLine(l) - for (let i = 0; i < channels[params[0]].nicklist.length; i++) { - if (channels[params[0]].nicklist[i].uid === source) { - channels[params[0]].nicklist.splice(i, 1) - return - } - } - }, - QUIT: (_l, source) => { - delete users[source] - } -} - -function parser (l) { - const split = l.split(' ') - const cmd = split[0] - const args = split.slice(1).join(' ') - if (globalCommands[cmd]) return globalCommands[cmd](args) - if (cmd[0] === ':') { - const source = cmd.slice(1) - const subcmd = split[1] - const subargs = split.slice(2).join(' ') - if (servers.indexOf(source) > -1 && serverCommands[subcmd]) serverCommands[subcmd](subargs) - if (users[source] && userCommands[subcmd]) userCommands[subcmd](subargs, source) - } -} - -socket.on('data', data => { - data.split('\r\n') - .filter(l => l !== '') - .forEach(l => { - console.log('< ' + l) - parser(l) - }) -}) - -module.exports.connect = conf => new Promise((resolve, reject) => { - emitter.once('ping', resolve) - config = conf - socket.connect(config.port) - process.on('SIGINT', () => { - socket.write('QUIT\r\n') - process.exit() - }) -}) -module.exports.events = emitter - -const genTS = () => Math.trunc((new Date()).getTime() / 1000) -const genUID = () => { - const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' - var uid = '' - for (let i = 0; i < 6; i++) uid += chars.charAt(Math.floor(Math.random() * chars.length)) - if (users[uid]) return genUID() - return config.sid + uid -} -const getUID = nick => { - for (const key in users) if (users[key].nick === nick) return key -} - -module.exports.registerUser = nick => { - const user = { - nick: nick, - nickTS: genTS(), - modes: '+i', - username: '~' + nick, - vhost: config.vhost, - ip: '0::1', - uid: genUID() - } - users[user.uid] = user - m(`EUID ${user.nick} 1 ${user.nickTS} ${user.modes} ~${user.nick} ${user.vhost} 0::1 ${user.uid} * * :${user.nick}`) -} -module.exports.unregisterUser = nick => { - const uid = getUID(nick) - m(`:${uid} QUIT :Quit: satyr`) - delete users[uid] -} -module.exports.join = (nick, channelName) => { - const uid = getUID(nick) - if (!channels[channelName]) { - const channel = { - timestamp: genTS(), - name: channelName, - modes: '+nt', - nicklist: [{ uid: uid, mode: '' }] - } - channels[channel.name] = channel - } - m(`:${uid} JOIN ${channels[channelName].timestamp} ${channelName} +`) -} -module.exports.part = (nick, channelName) => { - const uid = getUID(nick) - m(`:${uid} PART ${channelName} :satyr`) - for (let i = 0; i < channels[channelName].nicklist.length; i++) { - if (channels[channelName].nicklist[i].uid === uid) { - channels[channelName].nicklist.splice(i, 1) - return - } - } -} -module.exports.send = (nick, channelName, message) => { - const uid = getUID(nick) - m(`:${uid} PRIVMSG ${channelName} :${message}`) - emitter.emit('message', nick, channelName, message) -} diff --git a/src/server.ts b/src/server.ts index 0f0b0cf..054ec06 100644 --- a/src/server.ts +++ b/src/server.ts @@ -3,13 +3,14 @@ import * as dirty from "dirty"; import { mkdir, fstat, access } from "fs"; import * as strf from "strftime"; import * as db from "./database"; +import {config} from "./config"; const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); const { exec, execFile } = require('child_process'); const keystore = dirty(); -function init (mediaconfig: any, satyrconfig: any) { - const nms = new NodeMediaServer(mediaconfig); +function init () { + const nms = new NodeMediaServer({logType: 0,rtmp: config['rtmp']}); nms.run(); nms.on('postPublish', (id, StreamPath, args) => { @@ -23,7 +24,7 @@ function init (mediaconfig: any, satyrconfig: any) { session.reject(); return false; } - if(app !== satyrconfig.privateEndpoint){ + if(app !== config['media']['privateEndpoint']){ //app isn't at public endpoint if we've reached this point console.log("[NodeMediaServer] Wrong endpoint, rejecting stream:",id); session.reject(); @@ -36,21 +37,21 @@ function init (mediaconfig: any, satyrconfig: any) { if(results[0]){ //transcode to mpd after making sure directory exists keystore[results[0].username] = key; - mkdir(satyrconfig.directory+'/'+satyrconfig.publicEndpoint+'/'+results[0].username, { recursive : true }, ()=>{;}); + mkdir(config['http']['directory']+'/'+config['media']['publicEndpoint']+'/'+results[0].username, { recursive : true }, ()=>{;}); while(true){ if(session.audioCodec !== 0 && session.videoCodec !== 0){ - transCommand(mediaconfig, satyrconfig, results[0].username, key).then((r) => { - execFile(satyrconfig.ffmpeg, r, {maxBuffer: Infinity}); + transCommand(results[0].username, key).then((r) => { + execFile(config['media']['ffmpeg'], r, {maxBuffer: Infinity}); }); break; } await sleep(300); } - if(results[0].record_flag && satyrconfig.record){ + if(results[0].record_flag && config['media']['record']){ console.log('[NodeMediaServer] Initiating recording for stream:',id); - mkdir(satyrconfig.directory+'/'+satyrconfig.publicEndpoint+'/'+results[0].username, { recursive : true }, (err) => { + mkdir(config['http']['directory']+'/'+config['media']['publicEndpoint']+'/'+results[0].username, { recursive : true }, (err) => { if (err) throw err; - execFile(satyrconfig.ffmpeg, ['-loglevel', 'fatal', '-i', 'rtmp://127.0.0.1:'+mediaconfig.rtmp.port+'/'+satyrconfig.prviateEndpoint+'/'+key, '-vcodec', 'copy', '-acodec', 'copy', satyrconfig.directory+'/'+satyrconfig.publicEndpoint+'/'+results[0].username+'/'+strf('%d%b%Y-%H%M')+'.mp4'], { + execFile(config['media']['ffmpeg'], ['-loglevel', 'fatal', '-i', 'rtmp://127.0.0.1:'+config['rtmp']['port']+'/'+config['media']['privateEndpoint']+'/'+key, '-vcodec', 'copy', '-acodec', 'copy', config['http']['directory']+'/'+config['media']['publicEndpoint']+'/'+results[0].username+'/'+strf('%d%b%Y-%H%M')+'.mp4'], { detached : true, stdio : 'inherit', maxBuffer: Infinity @@ -74,7 +75,7 @@ function init (mediaconfig: any, satyrconfig: any) { nms.on('donePublish', (id, StreamPath, args) => { let app: string = StreamPath.split("/")[1]; let key: string = StreamPath.split("/")[2]; - if(app === satyrconfig.privateEndpoint) { + if(app === config['media']['privateEndpoint']) { db.query('update user_meta,users set user_meta.live=false where users.stream_key='+db.raw.escape(key)); db.query('select username from users where stream_key='+db.raw.escape(key)+' limit 1').then(async (results) => { if(results[0]) keystore.rm(results[0].username); @@ -94,24 +95,24 @@ function init (mediaconfig: any, satyrconfig: any) { } //localhost can play from whatever endpoint //other clients must use private endpoint - if(app !== satyrconfig.publicEndpoint && !session.isLocal) { + if(app !== config['media']['publicEndpoint'] && !session.isLocal) { console.log("[NodeMediaServer] Non-local Play from private endpoint, rejecting client:",id); session.reject(); return false; } //rewrite playpath to private endpoint serverside //(hopefully) - if(app === satyrconfig.publicEndpoint) { + if(app === config['media']['publicEndpoint']) { if(keystore[key]){ - session.playStreamPath = '/'+satyrconfig.privateEndpoint+'/'+keystore[key]; + session.playStreamPath = '/'+config['media']['privateEndpoint']+'/'+keystore[key]; return true; } } }); } -async function transCommand(config: object, satyrconfig: object, user: string, key: string): Promise{ - let args: string[] = ['-loglevel', 'fatal', '-y', '-i', 'rtmp://127.0.0.1:'+config['rtmp']['port']+'/'+satyrconfig['privateEndpoint']+'/'+key]; +async function transCommand(user: string, key: string): Promise{ + let args: string[] = ['-loglevel', 'fatal', '-y', '-i', 'rtmp://127.0.0.1:'+config['rtmp']['port']+'/'+config['media']['privateEndpoint']+'/'+key]; if(config['transcode']['adaptive']===true && config['transcode']['variants'] > 1) { for(let i=0;i