Skip to content

Instantly share code, notes, and snippets.

@sebseb7
Created October 7, 2020 01:47
Show Gist options
  • Save sebseb7/a55eef8b9baf2270b21a11035a7eef12 to your computer and use it in GitHub Desktop.
Save sebseb7/a55eef8b9baf2270b21a11035a7eef12 to your computer and use it in GitHub Desktop.
const express = require('express');
const app = express();
const exec = require('child_process').exec;
const port = 3000;
const http = require('http');
var g_stats = {};
var uplinks = 0;
var started = false;
var ffmpeg;
var lastline = '';
var noline = 0;
var inpath = '1';
var outpath = '1';
var mode = 'recode20';
var livestate = '';
app.get('/', (req, res) => {
//res.send('<html><script>setInterval(function(){fetch("/data").then(function(resp){resp.json().then(function(data){document.getElementById("data").innerHTML=JSON.stringify(data)})})},2000);</script><body><div id="data"></div></body></html')
res.send('<html><script>setInterval(function(){fetch("/data").then(function(resp){resp.json().then(function(data){document.getElementById("data").innerHTML=JSON.stringify(data)})})},2000);</script><body><div id="data"></div><br/><br/><br/><button onclick="fetch(\'/recode05\')">recode05</button><br/><br/><button onclick="fetch(\'/recode10\')">recode10</button><br/><br/><button onclick="fetch(\'/recode20\')">recode20</button><br/><br/><button onclick="fetch(\'/recode30\')">recode30</button><br/><br/><button onclick="fetch(\'/recode40\')">recode40</button><br/><br/><button onclick="fetch(\'/copy\')">copy</button><br/><br/><button onclick="fetch(\'/in1\')">in1</button><br/><br/><button onclick="fetch(\'/in2\')">in2</button><br/><br/><button onclick="fetch(\'/out1\')">out1</button><br/><br/><button onclick="fetch(\'/out2\')">out2</button></body></html')
})
app.get('/data', (req, res) => {
//res.send(JSON.stringify(g_stats));
res.send(JSON.stringify([g_stats,started,noline,lastline.toString(),mode,inpath,outpath,livestate]));
})
app.get('/recode05', (req, res) => {
mode = 'recode05';
if(started) ffmpeg.stdin.write("q\n");
res.send('<html><body></body></html');
})
app.get('/recode10', (req, res) => {
mode = 'recode10';
if(started) ffmpeg.stdin.write("q\n");
res.send('<html><body></body></html');
})
app.get('/recode20', (req, res) => {
mode = 'recode20';
if(started) ffmpeg.stdin.write("q\n");
res.send('<html><body></body></html');
})
app.get('/recode30', (req, res) => {
mode = 'recode30';
if(started) ffmpeg.stdin.write("q\n");
res.send('<html><body></body></html');
})
app.get('/recode40', (req, res) => {
mode = 'recode40';
if(started) ffmpeg.stdin.write("q\n");
res.send('<html><body></body></html');
})
app.get('/copy', (req, res) => {
mode = 'copy';
if(started) ffmpeg.stdin.write("q\n");
res.send('<html><body></body></html');
})
app.get('/out1', (req, res) => {
outpath = '1';
if(started) ffmpeg.stdin.write("q\n");
res.send('<html><body></body></html');
})
app.get('/out2', (req, res) => {
outpath = '2';
if(started) ffmpeg.stdin.write("q\n");
res.send('<html><body></body></html');
})
app.get('/in1', (req, res) => {
inpath = '1';
if(started) ffmpeg.stdin.write("q\n");
res.send('<html><body></body></html');
})
app.get('/in2', (req, res) => {
inpath = '2';
if(started) ffmpeg.stdin.write("q\n");
res.send('<html><body></body></html');
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
setInterval(function() {
//const data = JSON.stringify({links:uplinks,stats:g_stats});
const data = JSON.stringify({links:uplinks,stats:[g_stats,started,noline,lastline.toString(),mode,inpath,outpath,livestate]});
//console.log(data);
const options = {
hostname: 'greentv.rocks',
port: 2001,
path: '/get',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length,
},
}
const req = http.request(options, (res) => {
var data = '';
res.on('data', (d) => {
data += d;
})
res.on('end', () => {
livestate = data;
if(livestate == 'live')
{
//exec('/usr/bin/gpio write 1 1');
}
else
{
//exec('/usr/bin/gpio write 1 0');
}
});
});
req.on('error', (error) => {
});
req.write(data);
req.end()
},3000);
setInterval(function() {
exec('/usr/share/speedify/speedify_cli stats 2 current', function(error, stdout, stderr){
g_stats = {};
for(const item of stdout.split("\n\n")){
try {
const stats = JSON.parse(item);
if(stats[0] == "connection_stats") {
uplinks = 0;
for(const conn of stats[1].connections){
if(conn.adapterID != "speedify") {
//console.log(conn);
g_stats[conn.adapterID] = {'kbps':conn.totalBps,'latency':conn.latencyMs,'conn':conn.connected};
//console.log('updated');
if(conn.connected) uplinks++;
}
}
}
if(stats[0] == "session_stats") {
g_stats['session'] = {'sent':stats[1].current.bytesSent, 'minutes':stats[1].current.totalConnectedMinutes, 'failovers':stats[1].current.numFailovers};
}
}catch(e){/*console.log(e)*/};
}
});
},10000);
const {spawn } = require('child_process');
function start_ffmpeg() {
exec('killall -KILL ffmpeg',[],function(){
//console.log('start');
if(mode == 'copy') {
ffmpeg = spawn('/usr/local/bin/ffmpeg',[
'-hide_banner','-re','-rtmp_live live','-i rtmp://192.168.145.1/feed/'+inpath,'-fflags +genpts+igndts+nobuffer+flush_packets','-vcodec copy',
'-acodec copy','-f flv rtmp://greentv.rocks/feed/'+outpath
],{shell: true});
}else if(mode == 'recode05'){
ffmpeg = spawn('/usr/local/bin/ffmpeg',[
'-hide_banner','-re','-rtmp_live live','-c:v h264_mmal','-i rtmp://192.168.145.1/feed/'+inpath,'-r 30','-g 60','-fflags +genpts+igndts','-vcodec h264_omx',
'-profile:v high','-minrate 250k','-maxrate 500k','-b:v 500k','-bufsize 1000k','-acodec copy','-f flv','-drop_pkts_on_overflow 1','-attempt_recovery 1','-recovery_wait_time 1','rtmp://greentv.rocks/feed/'+outpath
],{shell: true});
}else if(mode == 'recode10'){
ffmpeg = spawn('/usr/local/bin/ffmpeg',[
'-hide_banner','-re','-rtmp_live live','-c:v h264_mmal','-i rtmp://192.168.145.1/feed/'+inpath,'-r 30','-g 60','-fflags +genpts+igndts','-vcodec h264_omx',
'-profile:v high','-minrate 350k','-maxrate 1000k','-b:v 1000k','-bufsize 2000k','-acodec copy','-f flv','-drop_pkts_on_overflow 1','-attempt_recovery 1','-recovery_wait_time 1','rtmp://greentv.rocks/feed/'+outpath
],{shell: true});
}else if(mode == 'recode20'){
ffmpeg = spawn('/usr/local/bin/ffmpeg',[
'-hide_banner','-re','-rtmp_live live','-c:v h264_mmal','-i rtmp://192.168.145.1/feed/'+inpath,'-r 30','-g 60','-fflags +genpts+igndts','-vcodec h264_omx',
'-profile:v high','-minrate 350k','-maxrate 2000k','-b:v 2000k','-bufsize 4000k','-acodec copy','-f flv','-drop_pkts_on_overflow 1','-attempt_recovery 1','-recovery_wait_time 1','rtmp://greentv.rocks/feed/'+outpath
],{shell: true});
}else if(mode == 'recode30'){
ffmpeg = spawn('/usr/local/bin/ffmpeg',[
'-hide_banner','-re','-rtmp_live live','-c:v h264_mmal','-i rtmp://192.168.145.1/feed/'+inpath,'-r 30','-g 60','-fflags +genpts+igndts','-vcodec h264_omx',
'-profile:v high','-minrate 350k','-maxrate 3000k','-b:v 3000k','-bufsize 6000k','-acodec copy','-f flv','-drop_pkts_on_overflow 1','-attempt_recovery 1','-recovery_wait_time 1','rtmp://greentv.rocks/feed/'+outpath
],{shell: true});
}else{
ffmpeg = spawn('/usr/local/bin/ffmpeg',[
'-hide_banner','-re','-rtmp_live live','-c:v h264_mmal','-i rtmp://192.168.145.1/feed/'+inpath,'-r 30','-g 60','-fflags +genpts+igndts','-vcodec h264_omx',
'-profile:v high','-minrate 350k','-maxrate 4500k','-b:v 4500k','-bufsize 8000k','-acodec copy','-f flv','-drop_pkts_on_overflow 1','-attempt_recovery 1','-recovery_wait_time 1','rtmp://greentv.rocks/feed/'+outpath
],{shell: true});
}
started = true;
noline = 0;
ffmpeg.stdout.on('data', (data) => {
//console.log('OUT:'+data);
lastline = data;
noline = 0;
});
ffmpeg.stderr.on('data', (data) => {
//console.log('ERR:'+data);
lastline = data;
noline = 0;
});
ffmpeg.on('close', (code) => {
started = false;
lastline = 'close';
start_ffmpeg();
//console.log('close');
});
ffmpeg.on('error', (code) => {
started = false;
start_ffmpeg();
lastline = 'error';
//console.log('error');
});
});
}
setInterval(function() {
noline++;
//console.log(noline);
if(noline > 5) {
if(started){
process.kill(ffmpeg.pid);
setTimeout(function(){exec('killall -KILL ffmpeg')},2000);
}
started=false;
}
if(noline > 10) {
if(started == false)
start_ffmpeg();
noline = 0;
started = true;
}
},1000);
//exec('/usr/bin/gpio mode 1 out');
//exec('/usr/bin/gpio mode 4 out');
start_ffmpeg();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment