作为程序猿(装逼汪),要不要试试用代码推流到B站直播?

推流B站直播

《前传》

菇作为内向 Boy 在B站潜水挺久了,前段时间(去年)开通了直播间准备干番大事业,结果发现并没有什么好玩的,于是直播间就长草了。不过作为一个伪二次元,倒是偶尔会看看直播,什么唱歌、跳舞、游戏、吐槽、炫技、哔狗、电视剧、巴拉巴拉、朵密朵密……

等等...(* ̄0 ̄)ノ,我居然在看直播电视剧!!?怎么做到的!??(主播们是怎么做到直播电视剧的的意思)

于是问了下度娘 ↓

我:直播电视剧

度娘:360电视直播-更全的电视直播影视网站-在线观看

我:(lll¬ω¬)

(一个月后)

我:在线直播电视剧软件

度娘:迅雷看看或者百度影音都行。迅雷看看播放器官方下载2015采用P2P点对点传输技术,可以在线流畅观看高清晰电影。迅雷看看提供丰富的影片库在线流畅点播服务;自动记录上次关闭播放器时的文件位置;迅雷看看沿用了迅雷多资源超线程技术,用户越多,播放越流畅。支持本地播放与在线视频点播,不断完善用户交互和在线产品体验,让用户的工作与生活充满乐趣;百度影音播放器(百度播放器)是百度公司最新推出的一款全新体验的播放器。百度影音播放器官方下载安装,支持主流媒体格式的视频、音频文件,实现本地播放和在线点播。百度影音电影播放器将不断完善产品性能、产品体验及产品功能。让它成为您休闲娱乐的伙伴,让您的工作与生活充满乐趣,为您提供优秀的视听服务。大多数视频软件都能达到要求的。

我:QNMD...

(两个月后)

我:直播电视推流

度娘:OBS、此刻主播助手、暴风云直播助手

……

(OBS最早在B站还没出官方直播姬的时候就用过,功能强大,配置详细,资源占用稍高;而后面两个看过文档之后,发现就是优化了使用场景,更方便无脑操作,对比下来,和直接使用直播姬区别也不是很大。突然就在这时候我脑海中闪过一个生僻古老的词汇:电视卡!!!)

我:硬件推流

度娘:……

我:直播卡

度娘:看斗鱼直播很卡怎么办_互联网_百度经验

我(…):直播采集卡

度娘:【PCI-E四路实时音视频采集卡,带完整视频直播软件】 - 太平洋安防网

我:高清采集卡(site:jd.com)

东娘:¥799.00、¥1599.00、¥1999.00

(就在我即将放弃的时候,另一个香菇在我脑海中吼道:你TM不是会敲代码吗!!?)

惊醒的我:直播推流

度娘:最简单的基于FFmpeg的推流器(以推送RTMP为例) - 雷霄骅(lei...

(缅怀大神 /(ㄒoㄒ)/~~)

我:ffmpeg直播推流

度娘:用node和ffmpeg进行直播推流

你猜我看到了啥!!node!!

怀着激动的心情点了进♂去……

《正史》

用代码推流到B站直播。这里的代码我们便使用 Node.js 来创建,当然准备工作不止这样。

我们需要:

  • node.js 环境(某菇在B站发的唯一一个视频中讲到过)
  • fluent-ffmpeg(封装ffmpeg的api的node模块)
  • ffmpeg(这个是重点)
  • 可以正常联网的计算机(PC、MAC、Linux、Raspberry Pi、……)

部署 Node.js 很简单,能看懂官方文档的请直接转到官网(https://nodejs.org/),不能看懂官方文档的你需要和度娘谈谈;

部署完 Node.js 一般会同时部署好 npm 包管理器,如下所示安装 fluent-ffmpeg 即可:

$ npm -g install fluent-ffmpeg

同时提供 fluent-ffmpeg 的地址(含文档) https://github.com/fluent-ffmpeg/node-fluent-ffmpeg/

然后到 ffmpeg 官网(http://www.ffmpeg.org/)下载适合自己操作系统和 CPU 架构的部署文件并部署;

以 Windows 10 x64 为例,下载到的可能是如下这种东西:

ffmpeg-20161010-c44eae1-win64-static.zip

解压后的文件结构大概是这个样子:

  • bin

    - ffmpeg.exe
    - ffplay.exe
    - ffprobe.exe
  • doc

    + examples
       - *.c
    - *.html
  • licenses

     - *.txt
  • presets

     - ffprobe.xsd
     - *.ffpreset
    • ff-prompt.bat
  • README.txt

不需要管那么多,直接将文件解压到方便自己找到的地方,然后将 bin 目录所在绝对路径添加到系统环境变量 Path 中即可,然后在 CMD 中使用如下命令:

ffmpeg -version

如过输出一堆表明 ffmpeg 的信息证明配置成功。

接下来:

var V = ['CeFrumoasaEIubirea.avi', 'Miyazaki.mp4', 'SecretBase.flv']; // 视频文件名数组,单个亦可。

function liveON(i) {

var ffmpeg = require('fluent-ffmpeg'); // 引入 fluent-ffmpeg 包
var inputPath = './video/' + V[i]; // 拼接视频相对路径字符串,需要将视频文件放到正确的目录中。
var outputPath = ['rtmp://live-send.acg.tv/live/',
  '手冻打码'
]; // 由直播平台提供的推流地址,不限于B站。 [0]是公共推流地址,手冻打码的[1]是直播码,拼接起来组成完整地址。

ffmpeg(inputPath)

 .inputOptions('-re')
  .inputOptions('-ac 2')
  // 下面注释掉的代码块本来是用来加水印的,但是我实际测试时成功加上水印可音轨丢失了。
 // 原作者在 overlay 时 outputs 的是个数组 ['output', 'a'] 但是我运行会报错。
 // 只好修改成 output 了,可能因此造成没有声音,鉴于作者原文发布距离现在有段时间了,母鸡是否和版本有关。。。
 /*.addInput('./pic/gutv.png')
 .complexFilter([{
   filter: 'scale',
    options: [1280, -1],
    inputs: '0',
    outputs: 'video'
  }, {
    filter: 'scale',
    options: [175, -1],
   inputs: '1',
    outputs: 'logo'
 }, {
    filter: 'overlay',
    options: {
      x: 'main_w-overlay_w-15',
     y: 15
   },
    inputs: ['video', 'logo'],
    outputs: 'output'
 }], 'output')*/
 .on('start', function(commandLine) {
    console.log('Spawned Ffmpeg with command: ' + commandLine);
 })
  .on('error', function(err, stdout, stderr) {
    console.log('error: ' + err.message);
   console.log('stdout: ' + stdout);
   console.log('stderr: ' + stderr);
 })
  .on('end', function() {
   console.log('Processing finished !');
   if(i < V.length) { // 这里香菇添加的递归调用函数本身以实现 V 数组中的视频连播。
      liveON(++i);
    } // 也可以添加 else 判定使 i 归零实现循环连播。
 })
  .addOptions([
   '-vcodec libx264',
    '-preset veryfast',
   '-crf 22',
    '-maxrate 1000k',
   '-bufsize 3000k',
   '-acodec libmp3lame',
   '-ac 2',
    '-ar 44100',
    '-b:a 96k'
  ])
  .format('flv')
  .output(outputPath[0] + outputPath[1], { // 修改了原作者使用的 pipe 方法以避免 fluent-ffmpeg 报错
   end: true
 })
  .run();

}

liveON(0);

这就是 Node.js 调用 ffmpeg 推流到直播平台的代码了,保存成 *.js 即可,虽然折腾过程中出了一些问题但最后勉强可以正常使用。

执行方法如下:

node .js # 这里的 是保存的文件名

《后传》

原理:这里使用的 Node.js 及其扩展包其实只是为了编写配置过程更方便,同时附加实现连播,循环等功能,所以理论上可以使用任何计算机编程语言实现基于 ffmpeg 的直播推流,因为如上代码在实际执行中会被翻译成如下命令执行:

ffmpeg -re -ac 2 -i ./video/CeFrumoasaEIubirea.avi -vcodec libx264 -preset veryfast -crf 22 -maxrate 1000k -bufsize 3000k -acodec libmp3lame -ac 2 -ar 44100 -b:a 96k -f flv rtmp://live-send.acg.tv/live/手冻打码

因此相信某些牛人可以在记住 ffmpeg 所有配置选项后,只用命令行实现视频推流。(马上膜拜)

本文参考度娘(360?)给的答案(并私自胡改了一通):http://www.360doc.com/content/15/1227/23/597197_523577418.shtml

Pss. 如过有大神路过并且知道如何加上水印而防止音轨丢失的方法,请不吝赐教。

标签: none

已有 7 条评论

  1. [2017-08-24 00:30] Command: ffmpeg -re -ac 2 -f concat -safe 0 -i concat.txt -i /pic/tips2.png -filter_complex [0:v]scale=1280:-1[video];[1:v]scale=220:-1[logo];[video][logo]overlay=x=main_w-overlay_w-15:y=15 -vcodec libx264 -preset veryfast -crf 22 -maxrate 1000k -bufsize 3000k -acodec libmp3lame -ac 2 -ar 44100 -b:a 96k -f flv rtmp://send1.douyu.com/live/501101rT0YrVvLbm?wsSecret=a41b31b11918bccefbcf0ba7584eadcc&wsTime=599dab4e&wsSeek=off
    error: ffmpeg exited with code 1: Unrecognized option 'crf'.
    Error splitting the argument list: Option not found

    stdout:
    stderr: ffmpeg version 3.3.3 Copyright (c) 2000-2017 the FFmpeg developers
    built with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-11)
    configuration: --enable-shared --prefix=/usr/local/ffmpeg
    libavutil 55. 58.100 / 55. 58.100
    libavcodec 57. 89.100 / 57. 89.100
    libavformat 57. 71.100 / 57. 71.100
    libavdevice 57. 6.100 / 57. 6.100
    libavfilter 6. 82.100 / 6. 82.100
    libswscale 4. 6.100 / 4. 6.100
    libswresample 2. 7.100 / 2. 7.100
    Unrecognized option 'crf'.
    Error splitting the argument list: Option not found
    差一点就推出去了, 可以失败了,博主看下什么原因

  2. 看完了,然而局外人并不是很清楚。他的作用是实现直播?我看到你又说到电视采集卡,是在B站直播电视节目吗?我知道B站上可以看到TVB的直播

    1. 诶~前传中的内容大多是干正事儿前的脑洞产物。采集卡是一种硬件解决方案,但出于习惯还是想从软件层面考虑,本文介绍的是一种偏底层的软件推流方案,但为了提升可读性和可维护性还是引入了nodejs封装,其目的是为了将本地文件或其他网络流可以定义的推送到目标平台

      1. 感觉好厉害的东西,给你个链接,http://token.tvb.com/stream/live/enews/hls/mobilehd_enews.smil能不能推到你的哔哩哔哩上面?

        1. 理论可行,待周末做个测试~

          1. 这样的话直播就不需要开电脑了对吧

            1. 可以解放日常使用的电脑,但还是需要用于运行代码的设备,云服务、开发板、甚至安卓手机都行,我是放到腾迅云上运行的

评论已关闭