手把手教你入门直播开发之(二)快速搭一个直播平台

手把手教你入门直播开发之(二)快速搭一个直播平台

Scroll Down

搭建一个后台直播服务

一、前言

上篇我们介绍了音视频原理以及主流的协议,本篇主要进行实操,介绍如何搭建一个直播服务并进行推拉流测试。

img

本系列分为三个部分:

  1. 直播基础知识
  2. 如何搭建一个能跑的直播平台(正是本篇是也)
  3. 使用golang开发一个简单可运行的直播server

本篇内容其实很简单说的很浅,如果有模糊或者不正确的地方,欢迎评论指出,谢谢image-20210629012710771


如果现在要搭建一个直播平台,必不可少的部分有推拉流端、直播中心(直播流处理、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)


    SRShttps://github.com/ossrs/srs)

    SRS是一个全功能运营级的视频服务器,官方的说法是“降低音视频的门槛”,对直播流支持非常完善 ,在2020年还新增支持了WEBRTC,除此之外也支持主流音视频协议以及Forward/Edge/VHOST等功能,官方文档非常齐全,连入门教程都安排的妥妥帖帖!!!

    除了直接用于小团队搭建流媒体服务器,还可以用于协议转换、源站转发等功能,目前的线上应用案例不少,比如又拍云的直播服务是基于SRS做深度定制。

    类似的还有 ZLMediaKit


    Red5https://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如下:

(三)推拉流测试

  1. 功能测试

我这里使用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)
(猜猜这是什么剧image-20210629013112658

vlc拉流

(2) HTML拉http-flv的流

使用b站开源的 flv.js 通过http-flv协议播放flv,flv.js是来自Bilibli的开源项目,可以在不使用Flash的情况下播放FLV。

我这里直接使用一个别人搭好的web拉流网站:http://rtmp.psvmc.cn,填写拉流地址后就能拉流播放了。

image-20210627234051022

  1. 压力测试

一个直播服务单机最大支持推拉的流数量是一个很重要的指标,这里推荐一个来自于SRS的压测工具:https://github.com/ossrs/srs-bench,进行推拉流的压力测试,使用起来很方便,比如测试拉流(我的机子500拉流CPU跑到100%了image-20210629013343429):

./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,但实际用到生产环境还要处理许多问题,最显著的就是直播卡顿与延迟,直接的现象就是花屏、黑屏、音画不同步、首开缓慢甚至断流。

再说后台直播架构,因为团队实力、用户规模的不同其实延伸的方案很多,为了避免篇幅太长,本篇很粗略的提了一下,并没有做详细的列举。有句老话是架构不是设计出来的是演进出来的,用在这一场景也很有说服力。

参考

京东云直播时移回放服务的实践案例

快手直播自建源站的实践

姚冬大神写的flv.js demux部分解析