▲ 视频作者 LiarOnce (http://www.bilibili.com/video/av9852916/
人生不止眼前的苟且,还有装逼和浪。——香菇夫斯基
故事起源于《作为程序猿(装逼汪),要不要试试用代码推流到B站直播?》,这里只是代码的升级优化,所以没什么好说的。
优化内容
- 将函数递归调用实现的“循环推流”改成 pm2 实现的“进程守护”,从而实现进程结束自动重启、意外终结自动重启、后台管理、日志记录等功能;
- 改写参数实现添加水印
- 顺序播放改为随机播放
新的问题
- B站直播修改了网页端播放器,导致断流重推后直播卡住,需要刷新才能续看。(目前与 一心月 交换了新的意见,待测试。
本次需要准备的环境和三方模块(纯净环境下
- node.js 环境(某菇在B站发的唯一一个视频中讲到过)
- pm2(Node模块:本次主角,用于守护进程)
- fluent-ffmpeg(Node模块:封装了ffmpeg的api)
- silly-datetime(Node模块:格式化时间,用于日志记录)
- ffmpeg(用于支持推流)
- 可以正常联网的计算机(PC、MAC、Linux、Raspberry Pi、……)
代码
var fs = require('fs'); //文件操作模块
var sd = require('silly-datetime'); //时间格式化模块
var D = './video2/'; //存放视频文件的目录
var L = './pic/tips2.png'; //水印
var R = 'rtmp://txy.live-send.acg.tv/live-txy/'; //推流地址
var C = '?streamname=live_4669771_4358269&key=a387ef5965ce24df5512345e727e89da'; //推流参数
var O = ''; //测试输出,一般填写“文件名+.格式”的形式,留空则不启用
function showTime() {
return sd.format(new Date(), 'YYYY-MM-DD HH:mm');
}
function liveON() {
var V = fs.readdirSync(D);
var N = V.length;
var ID = Math.floor(Math.random() * N);
var ffmpeg = require('fluent-ffmpeg');
var inputPath = D + V[ID];
var outputPath = O == '' ? (R + C) : O;
console.log('[' + showTime() + '] Find ' + N + ' Video Files !');
ffmpeg(inputPath)
.inputOptions('-re')
.inputOptions('-ac 2')
.addInput(L)
.complexFilter([{
filter: 'scale',
options: [1280, -1],
inputs: '[0:v]',
outputs: 'video'
}, {
filter: 'scale',
options: [220, -1],
inputs: '[1:v]',
outputs: 'logo'
}, {
filter: 'overlay',
options: {
x: 'main_w-overlay_w-15',
y: 15
},
inputs: ['video', 'logo']
}])
.on('start', function(commandLine) {
//console.log('Spawned Ffmpeg with command: ' + commandLine);
console.log('[' + showTime() + '] Vedio "' + V[ID] + '" is Pushing !');
console.log('[' + showTime() + '] Spawned Ffmpeg with command !');
})
.on('error', function(err, stdout, stderr) {
console.log('error: ' + err.message);
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
})
.on('end', function() {
console.log('[' + showTime() + '] Vedio "' + V[ID] + '" Pushing is Finished !');
})
.addOptions([
'-vcodec libx264',
'-preset veryfast',
'-crf 22',
'-maxrate 1000k',//1000k
'-bufsize 3000k',
'-acodec libmp3lame',
'-ac 2',
'-ar 44100',
'-b:a 96k'
])
.format('flv')
.output(outputPath, {
end: true
})
.run();
}
liveON();
截至目前发文,香菇已经把该代码放在腾讯云运行超过48小时,期间直播未间断:http://live.bilibili.com/64285
(待续)
版权属于:香菇
本文链接:https://blog.siitake.cn/nodejs-bilibili-live-2.html
本站未注明转载的文章均为原创,并采用
CC BY-NC-SA 4.0 授权协议,转载请注明来源,谢谢!
最近在调试推流的功能,但是按照上面的代码总是推流不成功,请问可以看一下这个示例的源码吗,希望可以找到出现问题的地方
代码的话 就是上面的了 后续更新在这里 https://blog.siitake.cn/nodejs-bilibili-live-3.html
如果报错 可能是由于ffmpeg或者nodejs的版本不一致造成的 可以先试试对照官方文档检查和直接运行程序生成的 ffmpeg命令行 看看有没有错误
最近要写自动化测试,刚好要用mocha 和 ffmpeg来测试直播推流,帮大忙了谢谢。
哇~很荣幸我的文章对您有参考价值~
话说博主有没有遇到没有推流之后没有声音的情况? 按照你的代码尝试了,推流live是没有声音的,看你上一篇博客介绍加了水印丢失了音轨,我把加水印的代码去掉了也没有声音。
我的代码第二版之后声音都没问题,你可以尝试console出ffmpeg命令后直接在命令行(cmd/terminal)中运行测试有木有声音,同时多换几个源视频文件测试,看看是否是因为原视频的编码问题导致推流无声。
我把-acodec 设为aac 解决了。
顺便一提,
.inputOptions('-ac 2') 这一行和 后面addOptions的'-ac 2' 是不是重复了,还是故意为之?
因为我瞄了一眼fluent-ffmpeg的文档,这个inputOptions和addOptions应该是同一个方法不同的写法而已。
oh sorry, 忽略后面那个愚蠢的问题,我看错了 orz..
哈哈哈哈哈哈问题解决了就好~
哇~dalao 友链否?
已添加,请回链。
交易成功~♂ 居然回复错了QAQ
代码高亮全红看着好难受。。 QAQ
没有用着色高亮插件~
因为想着如果感兴趣的话基本就会拷走在其他地方看的233
好像道理的样子喔 QWQ
话说一直没搞明白你首页的信息流是怎么排列的
就是普通的浮动布局啊并没有用流式布局哈哈哈哈