搭建一个后台直播服务
一、前言
上篇我们介绍了音视频原理以及主流的协议,本篇主要进行实操,介绍如何搭建一个直播服务并进行推拉流测试。
本系列分为三个部分:
- 直播基础知识
- 如何搭建一个能跑的直播平台(正是本篇是也)
- 使用golang开发一个简单可运行的直播server
本篇内容其实很简单说的很浅,如果有模糊或者不正确的地方,欢迎评论指出,谢谢
如果现在要搭建一个直播平台,必不可少的部分有推拉流端、直播中心(直播流处理、CDN直播分发)与业务服务(长链接、礼物打赏与结算、以及用户、关系链等业务功能)。
本篇着重介绍直播推拉流部分,一般来说有三种选型方案
-
购买云服务
简单快捷省心,云服务商一般提供全流程能力支持,包括客户端推拉流SDK、直播CDN、转码、录制、鉴黄审核、连麦等功能,只要把业务和云服务的能力做一个整合,同时完成UI、业务层的开发,就可以搭建一套完整的系统,缺点是难以满足定制化需求。
如图是一个典型上云架构,用户向边缘节点推拉流,直播中心承包所有直播流业务。
-
使用成熟的开源软件
如果只是为了小范围使用,或者有个性化定制的需求,往往会选择自己搭建云服务,比如搭建局域网流媒体集群,通常需要分发的流不多,直接搭建更省事,可选的开源软件也非常多,其中最出名的当属Nginx、SRS和Red5。
nginx-rtmp-module (https://github.com/arut/nginx-rtmp-module)
这是Nginx大神arut在Nginx基础上开发的rtmp模块,支持RTMP、HLS、DASH协议,满足我们常规的直播需求,而且搭建简单,在nginx加载该模块,简单配置后就可以进行推拉流。除了rtmp支持,arut还开发了很多Nginx模块,
甚至还开发了一个mysql模块,在nginx的location 配置里直接编写sql连接mysql。
衍生版本nginx-http-flv-module(https://github.com/winshining/nginx-http-flv-module)
SRS(https://github.com/ossrs/srs)
SRS是一个全功能运营级的视频服务器,官方的说法是“降低音视频的门槛”,对直播流支持非常完善 ,在2020年还新增支持了WEBRTC,除此之外也支持主流音视频协议以及Forward/Edge/VHOST等功能,官方文档非常齐全,连入门教程都安排的妥妥帖帖!!!
除了直接用于小团队搭建流媒体服务器,还可以用于协议转换、源站转发等功能,目前的线上应用案例不少,比如又拍云的直播服务是基于SRS做深度定制。
类似的还有 ZLMediaKit
Red5(https://github.com/Red5/red5-server)
这一个使用Java开发的很古早的流媒体服务器,支持RTMP,以前非常流行,当时主要的特点就是对RTMP支持完善而且开源免费,不过现在已经停止更新。
-
云服务+自主研发
第三种是上面两种的综合,而且组合用法也各种各样。一个典型的用法是自己搭建源站,使用 CDN 服务来源站拉流,以此提供 HLS或者RTMP的加速,或者团队搭建转码、录制等服务自己cover相关业务。
二、使用nginx-rtmp-module
本篇我们使用nginx-rtmp-module来搭建一个直播推拉流服务,直观了解下推拉流的流程,用到的工具如下
- 推流工具:ffmpeg(可以使用OBS)
- 拉流工具:VLC(可以使用ffplay)
- 环境:linux/mac(windows编译略麻烦,本教程是在win10上的WSL进行的)
- 推拉流服务:nginx&nginx-rtmp-module
上面所列的软件都是免费、跨平台的,OBS是现在主流的PC开播工具,支持许多插件。
(一)安装模块
1.下载rtmp-module,我这边直接下载 nginx-http-flv-module
2.下载并编译nginx模块
nginx下载地址:http://nginx.org/en/download.html
最后我的目录结构是
drwxr-xr-x 5 jonas jonas 4096 Jun 27 03:26 ./
drwxr-xr-x 5 jonas jonas 4096 Jun 26 22:27 ../
drwxr-xr-x 9 jonas jonas 4096 Jun 27 03:32 nginx/
drwxr-xr-x 3 jonas jonas 4096 Jun 27 03:27 nginx-module/
为了保证nginx正常配置,建议至少安装以下依赖
# c++编译环境
apt-get install gcc gcc-c++
# 支持http rewrite
sudo apt-get install libpcre3 libpcre3-dev
# 安装zlib
apt-get install zlib1g-dev
或者直接一条命令
sudo apt-get install make gcc zlib1g-dev libpcre3-dev libssl-dev
然后进入nginx目录下,将rtmp模块编译进nginx
(默认安装到/usr/local/nginx,如果要自定义安装位置可以指定prefix参数,./configure --prefix=/usr/local/app/nginx)
./configure --add-module=../nginx-module/nginx-http-flv-module
make
make install
(二)配置
接下来在nginx.conf文件里增加rtmp相关的配置,配置参考 nginx-rtmp-module官方配置说明
兼容nginx原生指令,增加了一些补充指令,参考rtmp-module补充指令,这里尽可能少使用相关指令,但是如果要正式使用,最好要通读一次所有指令。
这里贴一个简单可运行的配置,分别配置了http(httpflv/hls)和rtmp两个server,推流的app设置为testapp。
user root;
worker_processes auto;
worker_cpu_affinity auto;
events {
worker_connections 2048;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
server {
listen 8090;
server_name localhost;
location /flvlive {
flv_live on;
chunked_transfer_encoding on;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
}
location /hlslive {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /tmp;
add_header Cache-Control no-cache;
}
location /stat {
default_type application/xml;
rtmp_stat all;
# Use this stylesheet to view XML as web page
# in browser
rtmp_stat_stylesheet stat.xsl;
}
}
}
rtmp {
server {
listen 1935;
application testapp {
live on;
gop_cache on; #打开GOP缓存,减少首屏等待时间
hls on;
hls_path /tmp/hlslive;
hls_fragment 1;#默认5s
hls_playlist_length 10s;#默认30s
}
}
}
如上配置,注意rtmp还配置了gop_cache,这个是直播秒开的一个关键点之一,缓存一组(或多组)GOP随时下发,可以试试如果不加上这个配置,拉流时一般要黑屏等一会,在下一节我们会重点介绍以及实现。
相关的URL如下:
- rtmp推流地址:rtmp://172.26.13.241:1935/testapp/test
- 流状态管理地址:http://172.26.13.241:8090/stat
- http-flv拉流地址:http://172.26.13.241:8090/flvlive?port=1935&app=testapp&stream=test
- hls拉流地址:http://172.26.13.241:8090/hlslive/test.m3u8
(三)推拉流测试
- 功能测试
我这里使用ffmpeg进行推流,把test.flv这个文件推到rtmp://127.0.0.1:1935/testapp/test
ffmpeg -re -i test.flv -c copy -f flv rtmp://127.0.0.1:1935/testapp/test
(1)使用VLC拉rtmp流(也可以拉hls和http-flv)
(猜猜这是什么剧)
(2) HTML拉http-flv的流
使用b站开源的 flv.js 通过http-flv协议播放flv,flv.js是来自Bilibli的开源项目,可以在不使用Flash的情况下播放FLV。
我这里直接使用一个别人搭好的web拉流网站:http://rtmp.psvmc.cn,填写拉流地址后就能拉流播放了。
- 压力测试
一个直播服务单机最大支持推拉的流数量是一个很重要的指标,这里推荐一个来自于SRS的压测工具:https://github.com/ossrs/srs-bench,进行推拉流的压力测试,使用起来很方便,比如测试拉流(我的机子500拉流CPU跑到100%了):
./sb_rtmp_load -c 500 -r rtmp://127.0.0.1:1935/testapp/test
还有其他官方提供的example
Examples:
1. start a client
./sb_rtmp_load -c 1 -r rtmp://127.0.0.1:1935/live/livestream
2. start 1000 clients
./sb_rtmp_load -c 1000 -r rtmp://127.0.0.1:1935/live/livestream
3. start 10000 clients
./sb_rtmp_load -c 10000 -r rtmp://127.0.0.1:1935/live/livestream
4. start 100000 clients
./sb_rtmp_load -c 100000 -r rtmp://127.0.0.1:1935/live/livestream
三、后话
上述搭建了一个非常简易的rtmp server,但实际用到生产环境还要处理许多问题,最显著的就是直播卡顿与延迟,直接的现象就是花屏、黑屏、音画不同步、首开缓慢甚至断流。
再说后台直播架构,因为团队实力、用户规模的不同其实延伸的方案很多,为了避免篇幅太长,本篇很粗略的提了一下,并没有做详细的列举。有句老话是架构不是设计出来的是演进出来的,用在这一场景也很有说服力。