隐藏

搭建流媒体推流/拉流服务(RTMP/RTSP/HLS/HTTP-FLV)

发布:2024/11/20 15:25:42作者:管理员 来源:本站 浏览次数:173

一、什么是流媒体


流媒体(streaming media)是指将一连串的媒体数据压缩后,经过网上分段发送数据,在网上即时传输影音以供观赏的一种技术与过程,此技术使得数据包得以像流水一样发送;如果不使用此技术,就必须在使用前下载整个媒体文件。流式传输可传送现场影音或预存于服务器上的影片,当观看者在收看这些影音文件时,影音数据在送达观看者的计算机后立即由特定播放软件播放。用户边下载边观看,而不必等待整个文件下载完毕;通过网络播放流媒体文件时,文件本身不会在本地磁盘中存储,这样就节省了大量的磁盘空间开销。流媒体实际指的是一种新的媒体传送方式,有声音流、视频流、文本流、图像流、动画流等。流媒体服务器广泛应用于视频点播、视频会议、远程教育(直播游戏或者在线课堂时候电脑窗口画面转播给其他人)、远程医疗、在线直播系统中、校园安防接入的摄像头视频流。

二、流媒体传输协议


   RTSP (Real-Time Stream Protocol)由Real Networks 和 Netscape共同提出的,基于文本的多媒体播放控制协议。RTSP定义流格式,流数据经由RTP传输;RTSP实时效果非常好,适合视频聊天,视频监控等方向。一般摄像头都是RTSP格式的。h5原生不支持这种格式。优点,可以控制到视频帧,因此可以承载实时性很高的应用。这个优点是相对于HTTP方式的最大优点。复杂度主要集中在服务器端,可以进行倍速播放功能,其他视频协议都无法支持。 网络延时低,一般在0.5S以内;缺点,就是服务器端的复杂度也比较高,实现起来也比较复杂。ios端不支持该协议,对移动端支持较弱;除了 Firefox 浏览器可以直接播放 RTSP 流之外,几乎没有其他浏览器可以直接播放 RTSP 流。RTSP协议,此协议和RTMP效果差不多,在技术上只是区别于传输数据上占用多少通道、传输格式流不太一样而已,RTSP其实也可以用于直播。但依然是因为市场环境,RTSP目前主要应用在安防监控上,和RTMP一样,早已形成了自己的盈利链。

   RTMP(Real Time Message Protocol) 有 Adobe 公司提出,用来解决多媒体数据传输流的多路复用(Multiplexing)和分包(packetizing)的问题,优势在于低延迟,稳定性高,支持所有摄像头格式,RTMP协议是采用实时的流式传输,所以不会缓存文件到客户端,这种特性说明用户想下载RTMP协议下的视频是比较难的,视频流可以随便拖动,既可以从任意时间点向服务器发送请求进行播放,并不需要视频有关键帧。相比而言,HTTP协议下视频需要有关键帧才可以随意拖动,rtmp协议只支持flashplayer 就是只能在PC端(或安卓环境中安装了flashplayer组件,这种环境比较少)安装了flashplayer的情况下使用,浏览器加载 flash插件就可以直接播放,但是flash已经日落西山了。因此,目前 RTMP 主要用于提取 stream。也就是,当设置解编码器将视频发送到托管平台时,视频将使用 RTMP 协议发送到 CDN,随后使用另一种协议(通常是HLS)传递给播放器。

   HTTP: 当使用http协议的时候视频格式需要是m3u8或HTTP-FLV协议视频流。HLS 协议由三部分组成:HTTP、M3U8、TS。这三部分中,HTTP 是传输协议,M3U8 是索引文件,TS 是音视频的媒体信息m3u8是有延迟的。并不能实时,实时传输方面不如rtmp协议。因为m3u8的直播原理是将直播源不停的压缩成指定时长的ts文件(比如9秒,10秒一个ts文件)并同时实时更新m3u8文件里的列表以达到直播的效果。这样就会有一个至少9,10秒的时间延迟。如果压缩的过小,可能导致客户端网络原因致视频变卡。HTTP-FLV 即将流媒体数据封装成 FLV 格式,然后通过 HTTP 协议传输给客户端 HTTP协议中有个约定:content-length字段,http的body部分的长度服务器回复http请求的时候如果有这个字段,客户端就接收这个长度的数据然后就认为数据传输完成了,如果服务器回复http请求中没有这个字段,客户端就一直接收数据,直到服务器跟客户端的socket连接断开。http-flv直播就是利用第二个原理,服务器回复客户端请求的时候不加content-length字段,在回复了http内容之后,紧接着发送flv数据,客户端就一直接收数据了。


RTMP/RTSP HTTP-FLV HLS

传输协议 TCP HTTP HTTP

视频封装格式 flv flv ts

延时 1-3秒 1-3秒 5-20秒

Web支持 H5 不能直接播放 H5 不能直接播放 支持H5

数据 连续流 连续流 切片文件

优点 基于TCP长连接,不需要多次建连,延时低,通常只有1~3s;技术成熟,配套完善。 flv.js在获取到FLV格式的音视频数据后将 FLV 文件流转码复用成 ISO BMFF(MP4 碎片)片段,再通过Media Source Extensions API 传递给原生HTML5 Video标签进行播放。低延时,整体效果与RTMP非常接近;相较于RTMP协议,能有效避免防火墙和代理的影响。 基于HTTP协议,所以接入CDN较为容易,很少被防火墙拦下,且自带多码率自适应;作为苹果提出的协议,在macOS/iOS下有极大优势,Android中也提供了对应的支持;可以说此项协议用在移动设备上是再合适不过了

缺点 在PC浏览器中只能通过Flash使用,且无法在移动浏览器使用;鉴于Flash即将退出舞台,所以在网页播放端基本不会以RTMP做拉流。 把音视频数据封装成FLV,然后通过HTTP连接传输,与RTMP相比只是传输协议变了。对于网页播放端,本来还是需要Flash才能播放,但「flv.js」的出现又弥补了这个缺陷它的传输特性会让流媒体资源缓存在本地客户端,也就是说保密性不怎么样;直到目前仍然不兼容iOS的浏览器 延时较大,通常不低于10s 。大量的TS片文件,会造成服务器存储和请求的压力


除了HTTP、WebSocket类的传输协议,其他是无法通用地传输到浏览器的,所以,如果要做一款通用的H5视频播放器,基本上就是一款HTTP/WebSocket协议的视频播放器,如果是类似于RTMP、RTSP类型协议的视频源,是不可避免,需要经过服务器转换的

三、推流服务器搭建


方案一:Nginx添加模块nginx-rtmp-module


方案二:Nginx添加模块http-flv-module


nginx-http-flv-module是基于nginx-rtmp-module 的流媒体服务器。它具备了所有nginx-rtmp-module的功能,并且新增多种新功能,功能对比如下。


各位可以根据自己实际情况安装,http-flv-module功能更强大一些,我的项目需要播放HTTP-FLV,所以选择了方案二


nginx添加模块编译,如果已有nginx需要热部署升级,请看传送门http://XXXXXXXXXX[待完成]


// 下载nginx

# mkdir -p /root/nginx

# cd /root/nginx

# yum -y install pcre-devel openssl openssl-devel        //安装依赖

# wget http://nginx.org/download/nginx-1.21.6.tar.gz        //下载nginx包

# tar xf nginx-1.21.6.tar.gz

//下载nginx-http-flv-module

# mkdir -p /opt/nginx-1.21.6/module

# cd /opt/nginx-1.21.6/module

# wget https://github.com/winshining/nginx-http-flv-module/archive/refs/heads/master.zip

# unzip master.zip

# cd /root/nginx/nginx-1.21.6

//安装目录是/opt/nginx-1.21.6,安装模块nginx-http-flv-module-master【重点就是这个】和ssl用于日后配置https证书

# ./configure --prefix=/opt/nginx-1.21.6 --add-module=/opt/nginx-1.21.6/module/nginx-http-flv-module-master --with-http_ssl_module

# make

# make install // 如果你是热部署升级,一定不要执行这个命令

// 修改nginx配置文件 避免粘贴过来格式混乱,在 Vim 视图,输入如下命令:set paste,可以使 vim 进入 paste 模式,这时候再整段复制黏贴,就OK了

# vim /opt/nginx-1.21.6/conf/nginx.conf

//修改完成,检查nginx配置文件是否正确,启动nginx 即可,记得开放防火墙、安全组端口1935 和88

# cd /opt/nginx-1.21.6/sbin

# ./nginx -t

# ./nginx


nginx.config配置如下


#增加如下配置即可

# 推流时会发布到多个子进程

rtmp_auto_push on;

rtmp_auto_push_reconnect 1s;

rtmp {  

   server {  

       listen 1935;  #监听的端口号

       chunk_size 8192; # 单一推流数据包的最大容量

       

       application hls {  # 创建rtmp应用hls

           live on;  # 当路径匹配时,开始播放

           #HLS协议进行m3u8实时直播.如果是http-flv不需要配置下面的

           wait_key on;#保护TS切片

           hls on;  #实时回访

           hls_nested on;#每个流都自动创建一个文件夹

           hls_path /tmp/hls; #媒体块ts的位置

           hls_fragment 5s; #每个ts文件为5s的样子

           hls_playlist_length 30s;  #保存m3u8列表长度时间,默认是30秒,可考虑三小时10800秒

           hls_cleanup on;#是否删除列表中已经没有的媒体块TS文件,默认是开启

           hls_continuous on;#连续模式

      }  

   }

}

http {

   include       mime.types;

   default_type  application/octet-stream;

   sendfile        on;

   server {

       listen       88;

       server_name  localhost;

       error_log logs/rtmp/error.log;# http协议下的访问日志

       access_log  logs/rtmp/access.log;

       location /stat { # 开启这两个页面可以观察rtmp流的统计,不需要可去掉

           rtmp_stat all;

           rtmp_stat_stylesheet stat.xsl;

       }

   location /stat.xsl { # 查看状态的部分,不需要可去掉

       root /opt/nginx-1.19.1-rtmp/nginx-http-flv-module/;

   }

   location /flv_live { # 拉http-flv的配置

           flv_live on;

           chunked_transfer_encoding on;

           add_header 'Access-Control-Allow-Origin' '*';

           add_header 'Access-Control-Allow-Credentials' 'true';

   }

   # 通过http访问的这个路径会被转发到/tmp/hls 寻找对应的m3u8文件和视频片段例如 111.m3u8,111-622.ts,前缀名字为视频上传流的stream_key

   location /hls { # 拉m3u8的配置

       types {

             application/vnd.apple.mpegurl m3u8;

             video/mp2t ts;

           }

       alias /tmp/hls;  

       expires -1;

       add_header 'Cache-Control' 'no-cache';

   }

   location / { # 首页

       root html;

       index index.html index.htm;

   }

   error_page   500 502 503 504  /50x.html;

   location = /50x.html {

           root   html;

   }

 }

}