Created
October 7, 2020 01:47
-
-
Save sebseb7/a55eef8b9baf2270b21a11035a7eef12 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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