ruanzhijun
文章2
标签4
分类2
nginx+rtmp搭建直播服务器

nginx+rtmp搭建直播服务器

最近有朋友入职直播公司,在闲聊的过程中,激起了对直播业务的兴趣,很想去了解一下是怎么实现的。经过一翻搜索,发现比较主流的是nginx+rtmp方案,今天就来学习一下这个是怎么实现的。

今天的目标就是搭建一个可以推流/拉流的服务器,实现一个直播业务最简单的闭环。

知识扫盲

我们先了解一下先关的知识:

1.RTMP
实时消息传输协议,Real Time Messaging Protocol,是 Adobe Systems 公司为 Flash 播放器和服务器之间音频、视频和数据传输开发的开放协议。协议基于 TCP,是一个协议族,包括 RTMP 基本协议及 RTMPT/RTMPS/RTMPE 等多种变种。RTMP 是一种设计用来进行实时数据通信的网络协议,主要用来在 Flash/AIR 平台和支持RTMP协议的流媒体/交互服务器之间进行音视频和数据通信。这种方式的实时性比较强,基本能保证延迟在1-2s内,是现在国内直播主要采用的方式之一;不过使用这种协议,就必须安装flash,而H5、IOS、Android并不能原生支持flash,因此这种协议能流行多久,就不得而知了,毕竟移动端才是现在的主流。

2.HLS
hls是Apple推出的直播协议,是通过视频流切片成文件片段来直播的。客户端首先会请求一个m3u8文件,里面会有不同码率的流,或者直接是ts文件列表,通过给出的ts文件地址去依次播放。在直播的时候,客户端会不断请求m3u8文件,检查ts列表是否有新的ts切片。这种方式的实时性较差,不过优势是H5、IOS、Android都原生支持。

3.HTTP-FLV
HTTP-FLV就是对RTMP协议的封装,相比于RTMP,它是一个开放的协议。因此他具备了RTMP的实时性和RTMP不具备的开发性,而且随着flv.js出现(感谢B站),使得浏览器在不依赖flash的情况下,播放flv视频,从而兼容了移动端,所以现在很多直播平台,尤其是手机直播平台,都会选择它

环境搭建

环境搭建的第一步,安装带有 nginx-rtmp-module 模块的nginx,这不是本文讨论的范畴,如果对 nginx 安装不熟悉的同学,请搜索相关文章,或者如果想方便的同学,可以直接使用 nginx-quic安装脚本 进行安装,脚本里面已经整合了 nginx-http-flv-module 模块 (nginx-http-flv-module 是基于 nginx-rtmp-module 开发的,功能比它更多,运行更稳定),在 centos 7 / 8 系列的系统是可以顺利安装的。

环境搭建的第二步,编辑 nginx 配置文件,让 nginx-rtmp-module 模块 on work。

我们先按照官方给的demo操作一下:


#在 nginx.conf 文件新增 rtmp 模块
rtmp {
	server {
		listen 1935;
		application myapp {
			live on;
		}
	}
}

#在 nginx.conf 文件的 http 模块加入以下内容
server {
	listen 80;
	listen [::]:80;
	server_name live.ruanzhijun.cn;
	rewrite ^/(.*) https://$host/$1 permanent;
}

server {
	listen 443 ssl http2;
	listen 443 http3;
	listen [::]:443 ssl http2;
	listen [::]:443 http3;
	server_name live.ruanzhijun.cn;
	autoindex off;

	location /stat {
		rtmp_stat all;
		rtmp_stat_stylesheet stat.xsl;
	}

	location /stat.xsl {
		root /install/nginx-http-flv-module-1.2.7/;
	}

	location /control {
		rtmp_control all;
	}

	location /rtmp-publisher {
		root /install/nginx-http-flv-module-1.2.7/test;
	}

	location / {
		root /install/nginx-http-flv-module-1.2.7/test/www;
	}
}

重启 nginx,分别访问 推流端拉流端,已经可以实现这边录像那边播放了,还可以看到数据统计

需要注意有两点:
1.上面的配置中 /install/nginx-http-flv-module-1.2.7 是我服务器的实际路径,请按照你实际的路径修改,其他可以照抄
2.demo上面的地址是localhost,我是把它换成 live.ruanzhijun.cn



好了,官方的demo就体验完了。但是官方的demo是基于flash实现的,flash已经过时了,有时间再研究一下这块。

nginx原生支持quic

nginx原生支持quic

2020 年 6 月 10 日 Nginx 官方博客发文 Introducing a Technology Preview of NGINX Support for QUIC and HTTP/3,同时对外发布了 支持 QUIC 版 Nginx 的代码部署说明,从此体验 QUIC 又多了一个选择,马上体验一下。

准备工作

  • 由于 openssl 暂时还不支持 quic,所以这个版本的 ssl 库需要用 boringssl
  • 编译 boringssl,需要的基础设施就更多了,需要最新版的 go,libunwind (centos 7 可以 yum,centos 8 只能编译),cmake版本要3.0+,cmake是用来编译 boringssl 的,libunwind 是 boringssl 的依赖库
  • boringssl 是不支持 ocsp,如果一向玩 openssl 的同学转过来想要认证自己的证书的话,还要打个让 boringssl 支持 ocsp 的补丁

开始编译

编译过程总体来说还是挺顺畅的,之前看到的教程说有报错的都修复了

修改配置

为了可以使用 quic,需要修改 nginx 一些才配置可以生效

# http3 reuseport,这个就是开启 nginx quic 功能的,并且 reuseport 只可以声明一次
# 即:如果你有n个站点都想上 quic,那么你只需要在某一个站点加了这个 reuseport 就可以了,加多了会报错
listen 443 ssl http2;
listen 443 http3 reuseport;
listen [::]:443 ssl http2;
listen [::]:443 http3 reuseport;

# TLS 一定要有 1.3,其他随意
ssl_protocols TLSv1.3;

# 开启 0-RTT
ssl_early_data on;

# 加header,告诉浏览器,这个站点提供 quic 服务,可以尝试连接
add_header alt-svc 'quic=":443"; ma=2592000; v="46,43",h3-27=":443"; ma=2592000,h3-25=":443"; ma=2592000,h3-T050=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000';

测试

有一个网址,是可以帮你测试你的站点是否支持 quic 服务的,https://http3check.net,当你看到下图这样的字样的时候,就证明你的 quic 服务已经搭建成功
但是,我一直看不到【0-RTT】的字样,原因目前还没找到

浏览器

目前支持 quic 的浏览器也很少,而且都是实验性功能,没有明确开放出来的,要自己手动开启,以 Chrome 85 为例,浏览器地址栏输入:chrome://flags/ 回车,依次搜 quic/TLS 1.3/TLS 1.3 Early Data ,分别开启 enable 并重启浏览器,然后你的浏览器就支持 quic 了

Chrome 的用户,还可以安装一个插件:HTTP/2 and SPDY indicator,当你访问的网站支持 quic 时候,会显示出绿色的闪电

结语

坑终于踩完,我把这次体验的成果写成 一个 shell 脚本

但是我这个 quic 服务不是很稳定,试用 https://http3check.net 测试的时候,一下成功,一下不成功,而且始终都没有出现 0-RTT