前不久抽空对目前比较火的视频直播,作了下研究与探索,了解其总体实现流程,以及探讨移动端HTML5直播可行性方案。css
发现目前 WEB 上主流的视频直播方案有 HLS 和 RTMP,移动 WEB 端目前以 HLS 为主(HLS存在延迟性问题,也能够借助 video.js 采用RTMP),PC端则以 RTMP 为主实时性较好,接下来将围绕这两种视频流协议来展开H5直播主题分享。html
1. HTTP Live Streaming前端
HTTP Live Streaming(简称 HLS)是一个基于 HTTP 的视频流协议,由 Apple 公司实现,Mac OS 上的 QuickTime、Safari 以及 iOS 上的 Safari 都能很好的支持 HLS,高版本 Android 也增长了对 HLS 的支持。一些常见的客户端如:MPlayerX、VLC 也都支持 HLS 协议。
HLS 协议基于 HTTP,而一个提供 HLS 的服务器须要作两件事:ios
浏览器使用的是 m3u8 文件。m3u8 跟音频列表格式 m3u 很像,能够简单的认为 m3u8 就是包含多个 ts 文件的播放列表。播放器按顺序逐个播放,所有放完再请求一下 m3u8 文件,得到包含最新 ts 文件的播放列表继续播,周而复始。整个直播过程就是依靠一个不断更新的 m3u8 和一堆小的 ts 文件组成,m3u8 必须动态更新,ts 能够走 CDN。一个典型的 m3u8 文件格式以下:nginx
#EXTM3U #EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=200000 gear1/prog_index.m3u8 #EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=311111 gear2/prog_index.m3u8 #EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=484444 gear3/prog_index.m3u8 #EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=737777 gear4/prog_index.m3u8
能够看到 HLS 协议本质仍是一个个的 HTTP 请求 / 响应,因此适应性很好,不会受到防火墙影响。但它也有一个致命的弱点:延迟现象很是明显。若是每一个 ts 按照 5 秒来切分,一个 m3u8 放 6 个 ts 索引,那么至少就会带来 30 秒的延迟。若是减小每一个 ts 的长度,减小 m3u8 中的索引数,延时确实会减小,但会带来更频繁的缓冲,对服务端的请求压力也会成倍增长。因此只能根据实际状况找到一个折中的点。git
对于支持 HLS 的浏览器来讲,直接这样写就能播放了:github
<video src=”./bipbopall.m3u8″ height=”300″ width=”400″ preload=”auto” autoplay=”autoplay” loop=”loop” webkit-playsinline=”true”></video>
注意:HLS 在 PC 端仅支持safari浏览器,相似chrome浏览器使用HTML5 video
标签没法播放 m3u8 格式,可直接采用网上一些比较成熟的方案,如:sewise-player、MediaElement、videojs-contrib-hls、jwplayer。web
2. Real Time Messaging Protocolchrome
Real Time Messaging Protocol(简称 RTMP)是 Macromedia 开发的一套视频直播协议,如今属于 Adobe。这套方案须要搭建专门的 RTMP 流媒体服务如 Adobe Media Server,而且在浏览器中只能使用 Flash 实现播放器。它的实时性很是好,延迟很小,但没法支持移动端 WEB 播放是它的硬伤。
虽然没法在iOS的H5页面播放,可是对于iOS原生应用是能够本身写解码去解析的, RTMP 延迟低、实时性较好。
浏览器端,HTML5 video
标签没法播放 RTMP 协议的视频,能够经过 video.js 来实现。浏览器
<link href=“http://vjs.zencdn.net/5.8.8/video-js.css” rel=“stylesheet”> <video id=“example_video_1″ class=“video-js vjs-default-skin” controls preload=“auto” width=“640” height=“264” loop=“loop” webkit-playsinline> <source src=“rtmp://10.14.221.17:1935/rtmplive/home” type=‘rtmp/flv’> </video> <script src=“http://vjs.zencdn.net/5.8.8/video.js”></script> <script> videojs.options.flash.swf = ‘video.swf’; videojs(‘example_video_1′).ready(function() { this.play(); }); </script>
3. 视频流协议HLS与RTMP对比
目前直播展现形式,一般以YY直播、映客直播这种页面居多,能够看到其结构能够分红三层:
① 背景视频层
② 关注、评论模块
③ 点赞动画
而现行H5相似直播页面,实现技术难点不大,其能够经过实现方式分为:
① 底部视频背景使用video视频标签实现播放
② 关注、评论模块利用 WebScoket 来实时发送和接收新的消息经过DOM 和 CSS3 实现
③ 点赞利用 CSS3 动画
了解完直播形式以后,接下来总体了解直播流程。
3、直播总体流程
直播总体流程大体可分为:
(web前端学习交流群:328058344 禁止闲聊,非喜勿进!)
对于H5视频录制,可使用强大的 webRTC (Web Real-Time Communication)是一个支持网页浏览器进行实时语音对话或视频对话的技术,缺点是只在 PC 的 Chrome 上支持较好,移动端支持不太理想。
注意:
虽然Google一直在推WebRTC,目前已有很多成型的产品出现,可是大部分移动端的浏览器还不支持 webRTC(最新iOS 10.0也不支持),因此真正的视频录制仍是要靠客户端(iOS,Android)来实现,效果会好一些。
brew tap homebrew/nginx
② 执行安装nginx-rtmp-module
brew install nginx-full –with-rtmp-module
2. nginx.conf配置文件,配置RTMP、HLS
查找到nginx.conf配置文件(路径/usr/local/etc/nginx/nginx.conf),配置RTMP、HLS。
① 在http节点以前添加 rtmp 的配置内容:
② 在http中添加 hls 的配置
重启nginx服务,浏览器中输入 http://localhost:8080,是否出现欢迎界面肯定nginx重启成功。
nginx -s reload
当服务器端接收到采集视频录制端传输过来的视频流时,须要对其进行解析编码,推送RTMP/HLS格式视频流至视频播放端。一般使用的常见编码库方案,如x264编码、faac编码、ffmpeg编码等。
鉴于 FFmpeg 工具集合了多种音频、视频格式编码,咱们能够优先选用FFmpeg进行转换格式、编码推流。
1.安装 FFmpeg 工具
brew install ffmpeg
2.推流MP4文件
视频文件地址:/Users/gao/Desktop/video/test.mp4
推流拉流地址:rtmp://localhost:1935/rtmplive/home,rtmp://localhost:1935/rtmplive/home
//RTMP 协议流 ffmpeg -re -i /Users/gao/Desktop/video/test.mp4 -vcodec libx264 -acodec aac -f flv rtmp://10.14.221.17:1935/rtmplive/home //HLS 协议流 ffmpeg -re -i /Users/gao/Desktop/video/test.mp4 -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -q 10 rtmp://10.14.221.17:1935/hls/test
注意:
当咱们进行推流以后,能够安装VLC、ffplay(支持rtmp协议的视频播放器)本地拉流进行演示
3.FFmpeg推流命令
① 视频文件进行直播
ffmpeg -re -i /Users/gao/Desktop/video/test.mp4 -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -q 10 rtmp://192.168.1.101:1935/hls/test ffmpeg -re -i /Users/gao/Desktop/video/test.mp4 -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -q 10 rtmp://10.14.221.17:1935/hls/test
② 推流摄像头+桌面+麦克风录制进行直播
ffmpeg -f avfoundation -framerate 30 -i “1:0″ \-f avfoundation -framerate 30 -video_size 640x480 -i “0” \-c:v libx264 -preset ultrafast \-filter_complex ‘overlay=main_w-overlay_w-10:main_h-overlay_h-10′ -acodec libmp3lame -ar 44100 -ac 1 -f flv rtmp://192.168.1.101:1935/hls/test
更多命令,请参考:
FFmpeg处理RTMP流媒体的命令大全
FFmpeg经常使用推流命令
移动端iOS和 Android 都自然支持HLS协议,作好视频采集端、视频流推流服务以后,即可以直接在H5页面配置 video 标签播放直播视频。
<video controls preload=“auto” autoplay=“autoplay” loop=“loop” webkit-playsinline> <source src=“http://10.14.221.8/hls/test.m3u8″ type=“application/vnd.apple.mpegurl” /> <p class=“warning”>Your browser does not support HTML5 video.</p> </video>
本文从视频采集上传,服务器处理视频推流,以及H5页面播放直播视频一整套流程,具体阐述了直播实现原理,实现过程当中会遇到不少性能优化问题。
① H5 HLS 限制必须是H264+AAC编码。② H5 HLS 播放卡顿问题,server 端能够作好分片策略,将 ts 文件放在 CDN 上,前端可尽可能作到 DNS 缓存等。③ H5 直播为了达到更好的实时互动,也能够采用RTMP协议,经过video.js实现播放。