近日笔者帮朋友办直播讲课,折腾了几天,不但目标完成,还支持多路节目多机直播,观众自动分配直播源。哈哈哈哈哈哈,这不就差不多搞成一个网络电视台了吗?可把笔者牛逼坏了。
OK,既然是通过网络学习,参考很多朋友的文章,最后有了点成绩,那就记录分享一下笔者的成果,写一个文章吧。

LIVE RTMP HLS Nginx Streaming Broadcast 直播 点播

目录
一:资源准备
二:直播点播技术简介
三:简单直播架设
四:进阶直播
五:录像等其他问题

前提:为啥要费劲心思的搞一个自己的直播平台呢?网上现成的平台多的是,为啥不用?提出需求是因为某个艺术品圈子里的朋友们在微信群等基本手段不能满足需要的时候,便提出了请前辈开视频课的需求。我们的主讲和听众里半数来自大陆,剩下的人都分布在好几个时区上。而斗鱼、抖音之类的直播平台其实都是分区经营的。并且要申请在大陆地区开放,而申请人是非大陆居民的直播间更加漫长和繁琐。其实对不在国内的几位主讲人来说,也有其他好用的直播平台,可惜这些平台在大陆又无法访问。于是建设一个方便的,全球通的视频直播就是个不错的方案了。

一:资源准备

首先要做网络电视台,实现直播或点播服务,必须要有网络服务器,笔者是用的几台VPS实现。由于不是土豪,手里的vps都不是什么太高配置,存储空间也有限,所以算下来成本很低。此次实现多机直播总共动用了5台主机,但是起步阶段只需要一台就够了。主机配置不能太低,1G内存起码是需要的,CPU也不能太差。搬瓦工、Vultr等家的vps提供的CPU还是可以的。但是要注意像谷歌、阿里的最低价最低突发性能cpu就不合适做这个直播,很容易触及性能警戒线。

存储空间的要求看你想放多少东西了。只做基础直播的话,有10G空余空间用来存放录像就可以了(记得及时转存和清理)。如果想开个电影院,那就要准备大大的硬盘了。

最后是网络带宽和流量的问题了,以720p画面,25帧速直播的话,平均上传带宽至少是300KB每秒,观众侧也大体相当。(注意这里使用的是HLS播放模式,并非rtmp广播,理由后文详说。)也就是说10个人看,下行带宽就需要300*10*8Kbps,大约24Mbps的带宽。(请注意KB和Kbps的区别)。实际上由于数据编码的容量弹性问题,以及我们还要采用http或https提供传输,消耗一定的打包流量,所以总下行带宽至少28Mbps才能基本保证观看的稳定。如果希望承载100观众,下行带宽需要250Mbps以上的才可以。我们知道大部分vps商家提供的网络接口都是千兆网或万兆网,似乎网络下行速率不是问题。但那都是共享带宽,实际上每个主机都无法保证连续的高带宽输出。至少在搬瓦工的主机上几乎是没法实现200Mbps稳定输出的(短时可以)。所以要想承载大量观众,就需要多台主机进行负载均衡。最后说说流量,简单来说就是一路上行,N路下行。一般主机商都是只计算下行流量的,目前只有搬瓦工计双向,vultr上下行只计算一路流量多的。以上边我们说的300KB一路直播,一个小时大约1GB流量,10个人就是10GB。请考量自己的流量套餐包喽。

二:直播点播技术简介

RTMP,全称 Real Time Messaging Protocol,即实时消息传送协议。Adobe 公司为 Flash 播放器和服务器之间音视频数据传输开发的私有协议。
HTTP-FLV 依靠 MIME 的特性,根据协议中的 Content-Type 来选择相应的程序去处理相应的内容,使得流媒体可以通过 HTTP 传输。相较于 RTMP 协议,HTTP-FLV 能够好的穿透防火墙,它是基于 HTTP/80 传输,有效避免被防火墙拦截。但是收到flash市场的萎缩影响,以及各大主要浏览器厂商正在逐步取消flash的支持影响。http-flv技术前景堪忧。
HLS (HTTP Live Streaming) 则是苹果公司基于 HTTP 的流媒体传输协议。主要应用于 iOS 设备,包含(iPhone, iPad, iPod touch) 以及 Mac OSX 提供音视频直播服务和录制内容(点播)等服务。但是HLS技术被主流浏览器厂商支持,现在又获得HTML5标准支持。成为未来的主流技术。

直播技术实现有很多小众技术,但是目前最普遍的还是rtmp流媒体技术加HLS。其他的直播技术就不废话了,反正不开源,也不好用。直入正题rtmp是基于tcp协议的媒体流数据传输协议,相比rtsp这种基于udp的协议,rtmp更适合互联网采用。观众这边我们建议使用HLS协议观看,而不建议使用rtmp协议直接收流。理由是rtmp协议在有些观众的网络环境内会遇到防火墙限制,考虑到全球观众的网络环境差异,rtmp方式变得不是十分可靠。同时rtmp容易受网络状况波动影响,出现卡顿或者马赛克花屏。推荐使用的HLS是一种基于http协议的媒体播放协议,由苹果公司推动,获得Html5标准支持。其实HLS并不是针对直播服务设计的,它主要是用来在线提供视频播放服务。HLS并不是真正的实时直播,但是它使用http或https协议,带来的优点是:可以轻松穿过各种防火墙,不受特殊网络限制,主流浏览器完美支持。有一点点缺点就是直播视频会存在无法根除的延时(最低极限也要大于8秒,一般在20~30秒)。HLS对比rtmp协议还有一个问题就是无法使用广播方式来节约带宽(在内网有效,在互联网环境广播方式基本无法使用),也不方便使用多码率实现多种清晰度的切换(可实现但是很复杂)。

流媒体直播基本结构

简单说一下直播的工作流程:
首先主播通过PC或Ipad等终端,进行录音录像,将数据编码后通过rtmp协议推送给流媒体服务器;服务器对音视频进行切片加工或保存后,分发给所有观众;观众通过浏览器或者播放器观看视频内容。很简单吧。
再看看点播工作流程就更简单了,这里没有主播,只有服务器,观众通过web页面浏览到某个电影视频,点击播放,就会访问服务器的流媒体接口,服务器把视频文件地区出来,分片编码,通过流媒体接口发送给客户的浏览器或播放器进行显示。其实点播服务器比直播需要更高的硬件配置,对磁盘性能和内存、CPU都有一定的要求。
以上内容看似简单,却也隐含着很多技术细节。下文我们将一起实现它。

三:简单直播架设

首先选择软件方案。实现rtmp流媒体直播,过去是real公司的流媒体服务Helix系统比较多,后来Flash、QuickTime和微软等公司也提供了类似的服务产品。之后很多开源产品也加入了进来,比如Red5,OSS,Live555,DSS,YASS等等吧。这些有基于linux平台的也有基于windows平台的。这些商用级别的大家伙功能强大,管理能力也更强,但是搞起来难度也着实的高。最重要的是他们需要的硬件资源也更高。我们在性能孱弱的vps小鸡上实现直播,还是应该在性能要求上尽可能的轻量化。况且小鸡上一般都是采用debian或centos系统,所以我们首选就是nginxrtmp插件(Nginx-rtmp-module)来实施,这个插件同时还支持流录制和转发,HLS服务等功能。总之我们所需的它都有了。而且nginx和rtmp插件也有windwos版本,可以在windows环境同样实现。
nginx-rtmp-module是nginx的一个功能插件,开源,免费,稳定,高性能,可扩展。
nginx的安装这里不做详解,网上教程太多了。更有方便的lnmp一键安装包。(https://lnmp.org/notice/lnmp-v1-6.html) 网上找的nginx安装教程,一般都不包含rtmp模块。所以说一下在lnmp环境上增加rtmp模块的方法。
登录主机ssh后,找到lnmp安装包目录,比如笔者这里是 /usr/lnmp1.6 (具体位置取决于你安装lnmp时,下载安装包,自动解压所在的目录位置)。 我们编辑一下 lnmp.conf 配置文件。给Nginx_Modules_Options 这一项添加插件参数 –add-module=/usr/nginx-rtmp-module ,注意两侧单引号别丢了。

编辑 lnmp.conf 安装配置文件

我们添加的参数里指定了一个目录位置,这是可以根据需要改写的,目的是更新nginx时到指定的目录里编译加载插件。所以我们随后要做的就是按照指定的目录,去下载rtmp模块。

执行命令
cd /usr
git clone https://github.com/arut/nginx-rtmp-module

至此完成了rtmp模块的克隆。然后就可以运行 ./upgrade.sh nginx 升级(更新)一下nginx就行了。
顺带说一下,以后我们还需要用到nginx的一个插件stream来实现端口转发,但是这个模块从nginx1.9就是默认安装的,所以不用手动添加,如果你的nginx是自行手工配置编译的,请注意是否包含了这个模块。
至此一个简单的直播服务软件部分已经最低限度的搞好了。下一步进行配置工作。

先去lnmp里架设一个web站点,以后用于观众访问。执行lnmp vhost add ,之后按照提示输入域名,目录,选择https证书等等常规建站操作。(域名的dns解析,需要你提前做好,并且确认dns指向已经生效。)
站点建设完成后,lnmp会在 /home/wwwroot 目录下生成这个站点的根目录。我们再新建一个用于直播和存储的目录,我们就在wwwroot 目录下再mkdir一个 LIVE 目录,在LIVE 之内分别新建 RTMP和record 目录,分别用于观看直播和录像存储。(顺便说一句,linux环境下是严格区分大小写的,所以目录和文件名也需要确认大小写,否则是找不到目录和文件的。目录名称可以随你喜欢,主要是下边配置文件种要与实际一致。)

新建直播需要的存储目录

之后我们开始修改配置文件。

3.1 配置直播推流侧

执行 vim /usr/local/nginx/conf/nginx.conf 命令,可以看到 原本的文件内有一大段http配置。在http段之前,我们增加一个 rtmp段,内容见下图。

Nginx 的主配置文件 nginx.conf

先看一个 listen 1935 这个定义了服务端口号,默认rtmp协议就是使用1935号tcp端口。再来看 application live这段,这里的 live是一个路径名,并不是物理目录,请区别于我们之前设置的LIVE目录。这个live段的配置实现了一个直播服务的接口。内部参数 live on 表示直播服务开启; hls on 表示HLS播放服务开启; hls_path 指定了HLS播放媒体的物理目录。 后边几个hls开头的参数分表表示了缓冲列表最大时长60秒,媒体切片10秒,自动清理切片开启等等。 再下边record开头的几个参数配置了录像信息,内容很好理解,笔者不想多费口舌了。 请注意 allow publish 127.0.0.1 以及下边 deny publish all 这两行信息。 这里是说明只允许 从本机127.0.0.1地址进行推流进来,随后阻止其他任何推流。其他地址尝试推流连接会被服务器拒绝。这么写有什么用呢? 这里仅是提供了一个简单的安全防护,用于防止主机被扫描,被强推流。 我们真正的服务端口可以是其他的,比如使用1905.

通过上图,可以看到在rtmp段之前还添加了一个stream段。这就是前文提到的stream模块。上图我们实现了两个端口转发服务。1905和1904分别转发至本机1935和1934端口。这样当主播推流到1905端口后,就会被转发至127.0.0.1本机的1935端口上。根据你的喜欢,你也可以使用443或者3389等端口实现直播服务。

3.2 配置观众播放服务

观众是通过http/https站点读取的HLS文件数据观看直播内容的。所以要在开始时建立的网站上配置播放信息实现。我们进入 /usr/local/nginx/conf/vhost 目录,编辑之前我们开设的站点配置文件,比如 vim mywebsite.com.conf 。

每个站点有一个conf 配置文件

站点配置文件里默认是配置80端口的。当你站点启用https和证书后,会再增加443端口的配置。两个server段(80和443)里的内容除了证书加密方面的区别,其他基本相同。上图中80段里的配置笔者都给删除了,改写成301跳转,见红线部分。意思是这个站点强制使用https访问,任何访问80端口的请求,都会被301强制跳转到443端口上去。下图是443段里的配置,如果你不启用https,仅使用http服务的话,下图中的内容,就请填写到80段中去。

图中 location /live 段配置了一个url路径live, 内部配置指定了文件类型、物理路径等信息。实际上观众就是通过 https://mywebsite.com/live/节目名/index.m3u8 这个路径观看直播的。m3u8 类型文件本身就是一个索引文件,内部引用了一个 ts文件序列,这个序列是被HLS
服务不断更新的,观众获取这个文件后,根据内部指定的ts文件名去下载ts切片文件进行播放,从而实现观看直播视频。后边还有一个 Location /hls段,这个段不是必须,其实这是笔者配置的另一个播放点而已,与live性质相同。 图片中部有 location /stat 和 /stat.xsl 两个段,这两个段的意义是,管理员可以通过 https://mywebsite.com/stat 这个路径查看rtmp服务器运行状态,监控连接数,数据流量等信息。至此,一个简单的直播服务已经架设完成了。

stat 服务器状态

验证一下直播服务,通过PC端的OBS软件或者iphone上的易推流app,我们就可以发起直播了。
推流地址应该是: rtmp://mywebsite.com:1905/live/my001 推流的其他配置请参考推流软件上的帮助,选择合适的视频码率,和音频参数。 点击开始直播推流。
观众可以通过 https://mywebsite.com/live/my001/index.m3u8 观看,直接把这个地址贴在浏览器上就可以查看(主流浏览器 safari,chrome,edge 浏览器都可以),也可以把这个地址写入某个网页上,进行页面播放。
上文url中的live 我们可以理解为频道名,这个是服务器约定的,不能随便更改, my001 就是节目名,是推流主播可以自行决定的(一般也是约定好的),但是观众也需要知道,否则播放地址就找不到了。

继续阅读 《Part TWO