php直播平台源码基于 Nginx 搭建(rtmp、http)直播服务器
php直播平台源码基于 Nginx 搭建(rtmp、http)直播服务器
直播协议介绍
国内常见公开的直播协议有几个:RTMP、HLS、HDL(HTTP-FLV)、RTP,我们来逐一介绍。
RTMP
它是 Adobe 的专利协议,现在大部分国外的 CDN 已不支持。在国内流行度很高。原因有几个方面:
1、开源软件和开源库的支持稳定完整。如斗鱼主播常用的 OBS 软件,开源的 librtmp 库,服务端有 nginx-rtmp 插件。
2、播放端安装率高。只要浏览器支持 FlashPlayer 就能非常简易的播放 RTMP 的直播,协议详解可以 Google 了解。相对其他协议而言,RTMP 协议初次建立连接的时候握手过程过于复杂(底层基于 TCP,这里说的是 RTMP 协议本身的交互),视不同的网络状况会带来给首开带来 100ms 以上的延迟。基于 RTMP 的直播一般内容延迟在2~5 秒。
HTTP-FLV
即使用 HTTP 协议流式的传输媒体内容。相对于 RTMP,HTTP 更简单和广为人知,而且不担心被 Adobe 的专利绑架。内容延迟同样可以做到 2~5 秒,打开速度更快,因为 HTTP 本身没有复杂的状态交互。所以从延迟角度来看,HTTP-FLV 要优于 RTMP。
HLS
即 Http Live Streaming ,是由苹果提出基于 HTTP 的流媒体传输协议。HLS 有一个非常大的优点:HTML5 可以直接打开播放;这个意味着可以把一个直播链接通过微信等转发分享,不需要安装任何独立的 APP,有浏览器即可,所以流行度很高。社交直播 APP,HLS 可以说是刚需,下来我们分析下其原理 。
基于 HLS 的直播流 URL 是一个 m3u8 的文件,里面包含了最近若干个小视频 TS(一种视频封装格式,这里就不扩展介绍)文件。如 http://ip:port/live.m3u8
是一个直播留链接,其内容如下:
php直播平台源码基于 Nginx 搭建(rtmp、http)直播服务器
假设列表里面的包含 5 个 TS 文件,每个 TS 文件包含 5 秒的视频内容,那么整体的延迟就是 25 秒。当然可以缩短列表的长度和单个 TS 文件的大小来降低延迟,极致来说可以缩减列表长度为 1,1 秒内容的 m3u8 文件,但是极易受网络波动影响造成卡顿。通过公网的验证,目前按同城网络可以做到比较好的效果是 5~7 秒的延迟,也是综合流畅度和内容延迟的结果。
RTP
即 Real-time Transport Protocol ,用于 Internet 上针对多媒体数据流的一种传输层协议。
实际应用场景下经常需要 RTCP(RTP Control Protocol)配合来使用,可以简单理解为 RTCP 传输交互控制的信令,RTP 传输实际的媒体数据。
RTP 在视频监控、视频会议、IP 电话上有广泛的应用,因为视频会议、IP 电话的一个重要的使用体验:内容实时性强。
对比与上述 3 种或实际是 2 种协议,RTP 和它们有一个重要的区别就是默认是使用 UDP 协议来传输数据,而 RTMP 和 HTTP 是基于 TCP 协议传输。为什么 UDP 能做到如此实时的效果呢?关于 TCP 和 UDP 差别的分析文章一搜一大把,这里不在赘述,简单概括:
UDP:单个数据报,不用建立连接,简单,不可靠,会丢包,会乱序;
TCP:流式,需要建立连接,复杂,可靠 ,有序。
实时音视频流的场景不需要可靠保障,因此也不需要有重传的机制,实时的看到图像声音,网络抖动时丢了一些内容,画面模糊和花屏,完全不重要。TCP 为了重传会造成延迟与不同步,如某一截内容因为重传,导致 1 秒以后才到,那么整个对话就延迟了 1 秒,随着网络抖动,延迟还会增加成 2 秒、3 秒,如果客户端播放是不加以处理将严重影响直播的体验。
总结一下:在直播协议的选择中,如果选择是 RTMP 或 HTTP-FLV 则意味着有 2~5 秒的内容延迟,但是就打开延迟开,HTTP-FLV 要优于 RTMP。HLS 则有 5~7 秒的内容延迟。选择 RTP 进行直播则可以做到1秒内的直播延迟。但就目前所了解,各大 CDN 厂商没有支持基于 RTP 直播的,所以目前国内主流还是 RTMP 或 HTTP-FLV 。
流媒体服务器开源软件
php直播平台源码基于 Nginx 搭建(rtmp、http)直播服务器
环境准备
本来我打算是在我的 个人博客 服务器上搭建的,最终还是放弃了,因为之前的带宽跟容量也不是很大,也正巧碰见了 腾讯云 这几天在搞活动就又购买了一台服务器,以后关于后台服务的项目也基本上在这台部署了。
以下是我搭建以及测试的环境
搭建服务器环境
云服务器: 腾讯云
系统: centos
直播服务器: nginx
拓展模块: nginx-http-flv-module (支持 rtmp、http-flv、http-hls 等)
如果 NGINX 要支持正则表达式,需要安装 PCRE库。
如果 NGINX 要支持加密访问,需要安装 OpenSSL库。
如果 NGINX 要支持压缩,需要安装 zlib库。
测试环境:
电脑 : MAC
推流软件: obs-studio
MAC 拉流软件: VLC
Android 拉流软件: 前几天写的一个 Android 播放器 ykplayer 正好供于拉流测试
HTML5 FLV 播放器: bilibili 开源的 flv.js
本来之前我是借助 nginx-rtmp-module 来搭建的直播服务器(已成功),奈何它好像不支持 Http-flv 协议,所以替换成了 nginx-http-flv-module 模块,它是基于 nginx-rtmp-module 模块二次开发的,所以完美的继承了 rtmp 模块的所有功能。
服务器搭建
1. download nginx
# 通过 wget 命令下载
wget http://nginx.org/download/nginx-1.17.8.tar.gz
# 解压
tar -zxvf nginx-1.17.8.tar.gz
2. download nginx-http-flv-module
提醒: 关于它的详细信息可以参考它的介绍
# 通过 wget 命令下载
wget https://github.com/winshining/nginx-http-flv-module/archive/v1.2.7.tar.gz
# 解压
tar -zxvf v1.2.7.tar.gz
# 重命名
mv v1.2.7 nginx-http-flv-module
复制代码
3. install nginx 需要的环境
如果在执行 configure 之后报 OpenSSL 、PCRE 、Zlib error 那么就必须安装它们
#安装 openssl
yum install openssl
#安装 pcre
yum install pcre-devel
#安装 zlib
yum install zlib-devel
复制代码
等它们安装好了之后编译 nginx
4. build nginx
在当前解压 nginx 目录中创建编译 nginx 和 http-flv 脚本
php直播平台源码基于 Nginx 搭建(rtmp、http)直播服务器
#!/bin/sh
# ../ 代表当前目录的上一级
HTTP_FLV_MODULE_PATH=../nginx-http-flv-module-1.2.7
OpenSSL_PATH=../openssl-1.1.1d
#--prefix=./bin 代表编译完成之后输出的路径地址
#--add-module 将拓展模块添加到当前一起编译
./configure --prefix=./bin \
--add-module=$HTTP_FLV_MODULE_PATH \
--with-openssl=$OpenSSL_PATH \
--with-debug
# 通过 make install 构建
make
make install
复制代码
如果中途没有报任何错误,并且输出了我们指定的 bin 目录,那么就代表成功了。如下图所示:
php直播平台源码基于 Nginx 搭建(rtmp、http)直播服务器
5. 配置 nginx.conf
在当前目录下输入 vim bin/conf/nginx.conf
进行配置 rtmp、http 直播协议,我直接贴上我的配置
user root; worker_processes auto; #运行在Windows上时,设置为1,因为Windows不支持Unix domain socket #worker_processes auto; #1.3.8和1.2.5以及之后的版本 #worker_cpu_affinity 0001 0010 0100 1000; #只能用于FreeBSD和Linux worker_cpu_affinity auto; #1.9.10以及之后的版本 error_log logs/error.log error; #如果此模块被编译为动态模块并且要使用与RTMP相关的功 #能时,必须指定下面的配置项并且它必须位于events配置 #项之前,否则NGINX启动时不会加载此模块或者加载失败 #load_module modules/ngx_http_flv_live_module.so; events { worker_connections 4096; } http { include mime.types; default_type application/octet-stream; keepalive_timeout 65; server { listen 80;//自定义填写 http 的端口 location / { root /root/nginx/nginx-http-flv-module-1.2.7/test/www; index index.html index.htm;//默认首页 } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } location /flvjsplay {//测试地址 root /root/nginx/flv.js-1.5.0; index index.html;//flv.js 测试播放首页 } location /flv { flv_live on; #打开HTTP播放FLV直播流功能 chunked_transfer_encoding on; #支持'Transfer-Encoding: chunked'方式回复 #跨域 add_header 'Access-Control-Allow-Origin' '*'; #添加额外的HTTP头 add_header 'Access-Control-Allow-Credentials' 'true'; #添加额外的HTTP头 } location /hls { types { application/vnd.apple.mpegurl m3u8; video/mp2t ts; } root /root/nginx/nginx-http-flv-module-1.2.7; add_header 'Cache-Control' 'no-cache'; } location /dash { root /root/nginx/nginx-http-flv-module-1.2.7; add_header 'Cache-Control' 'no-cache'; } location /stat { #push和pull状态的配置 rtmp_stat all; rtmp_stat_stylesheet stat.xsl; } location /stat.xsl { root /root/nginx/nginx-http-flv-module-1.2.7; #指定stat.xsl的位置 } #如果需要JSON风格的stat, 不用指定stat.xsl #但是需要指定一个新的配置项rtmp_stat_format #location /stat { # rtmp_stat all; # rtmp_stat_format json; #} location /control { rtmp_control all; #rtmp控制模块的配置 } } } rtmp_auto_push on; rtmp_auto_push_reconnect 1s; rtmp_socket_dir /root/nginx/nginx-http-flv-module-1.2.7; rtmp { out_queue 4096; out_cork 8; max_streams 128; timeout 30s; drop_idle_publisher 30s; log_interval 5s; #log模块在access.log中记录日志的间隔时间,对调试非常有用 log_size 1m; #log模块用来记录日志的缓冲区大小 server { listen 1935;//自定义 rtmp 端口 # server_name www.test.*; #用于虚拟主机名后缀通配 application devyk { live on; gop_cache on; #打开GOP缓存,减少首屏等待时间 } application hls { live on; hls on; hls_path /root/nginx/nginx-http-flv-module-1.2.7/hls; } application dash { live on; dash on; dash_path /root/nginx/nginx-http-flv-module-1.2.7/dash; } } #可以有多个 server 配置 } 复
本文转载自网络,感谢(DevYK)的分享,转载仅为分享干货知识,如有侵权欢迎联系云豹科技进行删除处理
下一篇: 使用store来优化React组件的方法