代码拉取完成,页面将自动刷新
同步操作将从 shenwen/nodejs_hls 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
const fs = require('fs');
const cmd = require('child_process');
const express = require('express')
const app = express()
var jsonArr = null; //视频配置数据
var isMyAutoClose = false; //是否主动关闭进程
var path1 = __dirname+'/www/data.json'
var path2 = __dirname+'/www/hls/';
//设置静态文件路径
app.use(express.static('www'));
//允许跨域
app.all('*',function(req, res, next){
res.header("Access-Control-Allow-Origin", "*");
next();
})
//路由设置
app.get('/', function (req, res) {
res.send('hello world')
})
//接受 post 传给接口 /commit 的数据
app.use('/commit',function(req,res,next){
var data = '';
//监听数据流事件,默认二进制流,使用+号是自动toString转化位字符
req.on('data', function (chunk) {
data += chunk;
});
//监听数据接受完成事件
req.on('end', function () {
jsonArr = JSON.parse(data);
//写入文件
fs.writeFile(path1, JSON.stringify(jsonArr,null,2), error => {
if(error){
var obj = { code:'0',msg:error.message }
}else{
var obj = { code:'1',msg:'ok' }
runFFmpeg(path2)
}
res.send(JSON.stringify(obj))
});
});
})
app.listen(2000);
console.log("打开\033[32m http://localhost:2000/index.html \033[0m设置启动推流");
//数据重置操作
resetData(path1)
resetAction(path2)
/***********************************相关函数***************************************/
//删除文件价及里面的文件
function delDir(path){
let files = [];
if(fs.existsSync(path)){
files = fs.readdirSync(path);
files.forEach((file, index) => {
let curPath = path + "/" + file;
if(fs.statSync(curPath).isDirectory()){
delDir(curPath); //递归删除文件夹
} else {
fs.unlinkSync(curPath); //删除文件
}
});
fs.rmdirSync(path);
}
}
//执行命令,关闭进程操作
function viewProcessMessage (name, cb) {
let cmdStr = process.platform === 'win32' ? 'tasklist' : 'ps aux'
cmd.exec(cmdStr, function (err, stdout, stderr) {
if (err) {
return console.error(err)
}
stdout.split('\n').filter((line) => {
let processMessage = line.trim().split(/\s+/)
let processName = processMessage[0] //processMessage[0]进程名称 , processMessage[1]进程id
if (processName === name) {
return cb(processMessage[1])
}
})
})
}
//重置操作,关闭指定进程,删除相关文件
function resetAction(path){
isMyAutoClose = true;
viewProcessMessage('ffmpeg.exe',function (id) {
process.kill(id) //关闭匹配的进程
delDir(path)
})
}
//重置操作,重置配置数据 data.json
function resetData(path){
var json = fs.readFileSync(path, 'utf-8');
jsonArr = JSON.parse(json);
jsonArr.forEach(function(v){
v.error = '';
v.iswork = true;
})
fs.writeFileSync(path, JSON.stringify(jsonArr,null,2));
}
//执行一个拉流推流进程
function cmd_ffmpeg(url,key,path,isTC){
if(isTC){ //转码(注:转码非常消耗电脑性能,最多不超过5个)
var cmdStr = 'ffmpeg -i '
+url
+' -vcodec libx264 -acodec aac -preset ultrafast -tune zerolatency' //新视频格式需要转码
+' -f hls '
+'-hls_time 5 ' //切片间隔3s
+'-hls_flags delete_segments -hls_list_size 2 ' //保留切片设置
+'-hls_segment_filename '+path+key+'-%d.ts ' //重命名切片的名字:test-1.ts,test-2.ts,......
+path+key+'.m3u8';
}else{ //不转码
var cmdStr = 'ffmpeg -i '
+url
+' -c copy -f hls '
+'-hls_time 5 ' //切片间隔3s
+'-hls_flags delete_segments -hls_list_size 2 ' //保留切片设置
+'-hls_segment_filename '+path+key+'-%d.ts ' //重命名切片的名字:test-1.ts,test-2.ts,......
+path+key+'.m3u8';
}
cmd.exec(cmdStr,function(err,stdout,stderr){
if(err){
if(isMyAutoClose) return; //主动关闭进程时,不处理
console.log('错误!')
jsonArr.forEach(function(v){
if(v.key == key){
v.iswork = false;
v.error = stderr;
}
})
fs.writeFileSync(__dirname+'/www/data.json', JSON.stringify(jsonArr,null,2));
}else{
console.log('结束!'); //输出运行结果
}
})
}
//再次拉流推流系列操作
function runFFmpeg(path,arr){
resetAction(path)
//延迟5秒
var arr = arr || jsonArr
setTimeout(function(){
isMyAutoClose = false //关闭主动关闭进程状态
try{
fs.mkdirSync(path,'0755') //重新创建hls文件夹
}catch(er){
}
arr.forEach(function(v){
if(v.iswork) cmd_ffmpeg(v.url, v.key, path, v.isTC); //终端里执行命令
})
},5000)
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。