Worked out bugs in config and checking if localhost

Added comments to server.ts to improve readability
merge-requests/1/merge
knotteye 5 years ago
parent 2cd3f281c5
commit abcd6787ca
  1. 2
      config/default.toml
  2. 5
      package-lock.json
  3. 4
      package.json
  4. 64
      src/server.ts

@ -1,3 +1,5 @@
#DO NOT EDIT THIS FILE
#ALL CHANGES SHOULD GO IN LOCAL.TOML
[bcrypt] [bcrypt]
saltRounds = 12 saltRounds = 12

5
package-lock.json generated

@ -141,11 +141,6 @@
"supports-color": "^5.3.0" "supports-color": "^5.3.0"
} }
}, },
"check-localhost": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/check-localhost/-/check-localhost-0.0.1.tgz",
"integrity": "sha1-5EBBSdDrQr52SE/EnHTTIYOgC60="
},
"chownr": { "chownr": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz",

@ -5,7 +5,8 @@
"license": "AGPL-3.0", "license": "AGPL-3.0",
"author": "knotteye", "author": "knotteye",
"scripts": { "scripts": {
"start": "node build/controller.js" "start": "node build/controller.js",
"build": "tsc"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -13,7 +14,6 @@
}, },
"dependencies": { "dependencies": {
"bcrypt": "^3.0.6", "bcrypt": "^3.0.6",
"check-localhost": "0.0.1",
"config": "^3.2.2", "config": "^3.2.2",
"irc": "^0.5.2", "irc": "^0.5.2",
"mysql": "^2.17.1", "mysql": "^2.17.1",

@ -1,8 +1,7 @@
import * as NodeMediaServer from "node-media-server"; import * as NodeMediaServer from "node-media-server";
import { mkdir } from "fs"; import { mkdir } from "fs";
import * as db from "./database"; import * as db from "./database";
//import { transcode } from "buffer"; //import { transcode } from "buffer"; why is this here?
const isLocal = require("check-localhost");
const { exec } = require('child_process'); const { exec } = require('child_process');
function boot (mediaconfig: any, satyrconfig: any) { function boot (mediaconfig: any, satyrconfig: any) {
@ -10,39 +9,42 @@ function boot (mediaconfig: any, satyrconfig: any) {
nms.run(); nms.run();
nms.on('postPublish', (id, StreamPath, args) => { nms.on('postPublish', (id, StreamPath, args) => {
//this is unreadable, add some comments
console.log("[NodeMediaServer] Prepublish Hook for stream:",id); console.log("[NodeMediaServer] Prepublish Hook for stream:",id);
let session = nms.getSession(id); let session = nms.getSession(id);
let app: string = StreamPath.split("/")[1]; let app: string = StreamPath.split("/")[1];
let key: string = StreamPath.split("/")[2]; let key: string = StreamPath.split("/")[2];
if (StreamPath.split("/").length > 3){ //disallow urls not formatted exactly right
if (StreamPath.split("/").length !== 3){
console.log("[NodeMediaServer] Malformed URL, closing connection for stream:",id); console.log("[NodeMediaServer] Malformed URL, closing connection for stream:",id);
session.reject(); session.reject();
return false; return false;
} }
if(app === mediaconfig.trans.tasks.app) { if(app === mediaconfig.trans.tasks[0].app) {
isLocal(session.ip).then( (local) => { //only allow publish to public endpoint from localhost
if(local) { //this is NOT a comprehensive way of doing this, but I'm ignoring it
console.log("[NodeMediaServer] Local publish, stream:",`${id} ok.`); //until satyr releases and someone opens an issue
} if(session.ip.includes('127.0.0.1') || session.ip === '::1') {
else{ console.log("[NodeMediaServer] Local publish, stream:",`${id} ok.`);
console.log("[NodeMediaServer] Non-local Publish to public endpoint, rejecting stream:",id); }
session.reject(); else{
} console.log("[NodeMediaServer] Non-local Publish to public endpoint, rejecting stream:",id);
}); session.reject();
}
console.log("[NodeMediaServer] Public endpoint, checking record flag."); console.log("[NodeMediaServer] Public endpoint, checking record flag.");
db.raw.query('select username,record_flag from users where username=\''+key+'\' and record_flag=true limit 1', (error, results, fields) => { //if this stream is from the public endpoint, stream
db.raw.query('select username from users where username=\''+key+'\' and record_flag=true limit 1', (error, results, fields) => {
if (error) {throw error;} if (error) {throw error;}
if(results[0] && satyrconfig.record){ if(results[0].username && satyrconfig.record){
console.log('[NodeMediaServer] Initiating recording for stream:',id); console.log('[NodeMediaServer] Initiating recording for stream:',id);
mkdir(mediaconfig.http.mediaroot+'/'+mediaconfig.trans.tasks.app+'/'+results[0].username, { recursive : true }, (err) => { mkdir(mediaconfig.http.mediaroot+'/'+mediaconfig.trans.tasks[0].app+'/'+results[0].username, { recursive : true }, (err) => {
if (err) throw err; if (err) throw err;
let subprocess = exec('ffmpeg -i rtmp://127.0.0.1:'+mediaconfig.rtmp.port+'/'+mediaconfig.trans.tasks.app+'/'+results[0].username+' -vcodec copy -acodec copy '+mediaconfig.http.mediaroot+'/'+mediaconfig.trans.tasks.app+'/'+results[0].username+'/$(date +%d%b%Y-%H%M).mp4',{ let subprocess = exec('ffmpeg -i rtmp://127.0.0.1:'+mediaconfig.rtmp.port+'/'+mediaconfig.trans.tasks[0].app+'/'+results[0].username+' -vcodec copy -acodec copy '+mediaconfig.http.mediaroot+'/'+mediaconfig.trans.tasks[0].app+'/'+results[0].username+'/$(date +%d%b%Y-%H%M).mp4',{
detached : true, detached : true,
stdio : 'inherit' stdio : 'inherit'
}); });
subprocess.unref(); subprocess.unref();
//spawn an ffmpeg process to record the stream, then detach it completely //spawn an ffmpeg process to record the stream, then detach it completely
//ffmpeg can then finalize the recording if satyr crashes mid-stream
}); });
} }
else { else {
@ -57,10 +59,13 @@ function boot (mediaconfig: any, satyrconfig: any) {
session.reject(); session.reject();
return false; return false;
} }
//if the url is formatted correctly and the user is streaming to the correct private endpoint
//grab the username from the database and redirect the stream there if the key is valid
//otherwise kill the session
db.raw.query('select username from users where stream_key=\''+key+'\' limit 1', (error, results, fields) => { db.raw.query('select username from users where stream_key=\''+key+'\' limit 1', (error, results, fields) => {
if (error) {throw error;} if (error) {throw error;}
if(results[0]){ if(results[0]){
exec('ffmpeg -analyzeduration 0 -i rtmp://127.0.0.1:'+mediaconfig.rtmp.port+'/'+satyrconfig.privateEndpoint+'/'+key+' -vcodec copy -acodec copy -crf 18 -f flv rtmp://127.0.0.1:'+mediaconfig.rtmp.port+'/'+mediaconfig.trans.tasks.app+'/'+results[0].username); exec('ffmpeg -analyzeduration 0 -i rtmp://127.0.0.1:'+mediaconfig.rtmp.port+'/'+satyrconfig.privateEndpoint+'/'+key+' -vcodec copy -acodec copy -crf 18 -f flv rtmp://127.0.0.1:'+mediaconfig.rtmp.port+'/'+mediaconfig.trans.tasks[0].app+'/'+results[0].username);
console.log('[NodeMediaServer] Stream key okay for stream:',id); console.log('[NodeMediaServer] Stream key okay for stream:',id);
} }
else{ else{
@ -73,21 +78,22 @@ function boot (mediaconfig: any, satyrconfig: any) {
let session = nms.getSession(id); let session = nms.getSession(id);
let app: string = StreamPath.split("/")[1]; let app: string = StreamPath.split("/")[1];
let key: string = StreamPath.split("/")[2]; let key: string = StreamPath.split("/")[2];
if (StreamPath.split("/").length > 3){ //correctly formatted urls again
if (StreamPath.split("/").length !== 3){
console.log("[NodeMediaServer] Malformed URL, closing connection for stream:",id); console.log("[NodeMediaServer] Malformed URL, closing connection for stream:",id);
session.reject(); session.reject();
return false; return false;
} }
//disallow playing from the private endpoint for anyone except localhost
//(this will be the ffmpeg instance redirecting the stream)
if(app === satyrconfig.privateEndpoint) { if(app === satyrconfig.privateEndpoint) {
isLocal(session.ip).then( (local) => { if(session.ip.includes('127.0.0.1') || session.ip === '::1') {
if(local) { console.log("[NodeMediaServer] Local play, client:",`${id} ok.`);
console.log("[NodeMediaServer] Local play, client:",`${id} ok.`); }
} else{
else{ console.log("[NodeMediaServer] Non-local Play from private endpoint, rejecting client:",id);
console.log("[NodeMediaServer] Non-local Play from private endpoint, rejecting client:",id); session.reject();
session.reject(); }
}
});
} }
}); });
} }