前⾔
前不久抽空对⽬前⽐较⽕的视频直播,做了下研究与探索,了解其整体实现流程,以及探讨移动端HTML5直播可⾏性⽅案。
发现⽬前 WEB 上主流的视频直播⽅案有 HLS 和 RTMP,移动 WEB 端⽬前以 HLS 为主(HLS存在延迟性问题,也可以借助 video.js 采⽤RTMP),PC端则以 RTMP 为主实时性较好,接下来将围绕这两种视频流协议来展开H5直播主题分享。
涂布刮刀⼀、视频流协议HLS与RTMP
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 的服务器需要做两件事:
编码:以 H.263 格式对图像进⾏编码,以 MP3 或者 HE-AAC 对声⾳进⾏编码,最终打包到 MPEG-2 TS(Transport Stream)容器之中;分割:把编码好的 TS ⽂件等长切分成后缀为 ts 的⼩⽂件,并⽣成⼀个 .m3u8 的纯⽂本索引⽂件;浏览器使⽤的是 m3u8 ⽂件。m3u8 跟⾳频列表格式 m3u 很像,可以简单的认为 m3u8 就是包含多个 ts ⽂件的播放列表。播放器按顺序逐个播放,全部放完再请求⼀下 m3u8 ⽂件,获得包含最新 ts ⽂件的播放列表继续播,周⽽复始。整个直播过程就是依靠⼀个不断更新的 m3u8 和⼀堆⼩的 ts ⽂件组成,m3u8 必须动态更新,ts 可以⾛ CDN。⼀个典型的 m3u8 ⽂件格式如下: #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 中的索引数,延时确实会减少,但会带来更频繁的缓冲,对服务端的请求压⼒也会成倍增加。所以只能根据实际情况到⼀个折中的点。
对于⽀持 HLS 的浏览器来说,直接这样写就能播放了:
<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。
2. Real Time Messaging Protocol
Real Time Messaging Protocol(简称 RTMP)是 Macromedia 开发的⼀套视频直播协议,现在属于 Adobe。这套⽅案需要搭建专门的 RTMP 流媒体服务如 Adobe Media Server,并且在浏览器中只能使⽤ Flash 实现播放器。它的实时性⾮常好,延迟很⼩,但⽆法⽀持移动端 WEB 播放是它的硬伤。
虽然⽆法在iOS的H5页⾯播放,但是对于iOS原⽣应⽤是可以⾃⼰写解码去解析的, RTMP 延迟低、实时性较好。浏览器端,HTML5 video
标签⽆法播放 RTMP 协议的视频,可以通过 video.js 来实现。
<link href=“dn/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=“dn/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 动画
了解完直播形式之后,接下来整体了解直播流程。
三、直播整体流程
直播整体流程⼤致可分为:
视频采集端:可以是电脑上的⾳视频输⼊设备、或⼿机端的摄像头、或麦克风,⽬前以移动端⼿机视频为主。
直播流视频服务端:⼀台Nginx服务器,采集视频录制端传输的视频流(H264/ACC编码),由服务器端进⾏解析编码,推送RTMP/HLS格式视频流⾄视频播放端。
视频播放端:可以是电脑上的播放器(QuickTime Player、VLC),⼿机端的native播放器,还有就是 H5 的video标签等,⽬前还是以⼿机端的native播放器为主。
(web前端学习交流:328058344 禁⽌闲聊,⾮喜勿进!)
四、H5 录制视频
对于H5视频录制,可以使⽤强⼤的 webRTC (Web Real-Time Communication)是⼀个⽀持⽹页浏览器进⾏实时语⾳对话或视频对话的技术,缺点是只在 PC 的 Chrome 上⽀持较好,移动端⽀持不太理想。
使⽤ webRTC 录制视频基本流程
①调⽤ window.navigator.webkitGetUserMedia()
获取⽤户的PC摄像头视频数据。
②将获取到视频流数据转换成 window.webkitRTCPeerConnection
光子重构(⼀种视频流数据格式)。
③利⽤ WebScoket
将视频流数据传输到服务端。
水稻田
注意:
虽然Google⼀直在推WebRTC,⽬前已有不少成型的产品出现,但是⼤部分移动端的浏览器还不⽀持 webRTC(最新iOS 10.0也不⽀持),所以真正的视频录制还是要靠客户端(iOS,Android)来实现,效果会好⼀些。
WebRTC⽀持度
WebRTC⽀持度
iOS原⽣应⽤调⽤摄像头录制视频流程
①⾳视频的采集,利⽤AVCaptureSession和AVCaptureDevice可以采集到原始的⾳视频数据流。
②对视频进⾏H264编码,对⾳频进⾏AAC编码,在iOS中分别有已经封装好的编码库(x264编码、faac编码、ffmpeg编码)来实现对⾳视频的编码。
③对编码后的⾳、视频数据进⾏组装封包。
④建⽴RTMP连接并上推到服务端。
五、搭建Ng
五、搭建Nginx+Rtmp直播流服务
安装nginx、nginx-rtmp-module
①先clone nginx项⽬到本地:
brew tap homebrew/nginx
②执⾏安装nginx-rtmp-module
brew install nginx-full –with-rtmp-module
2. f配置⽂件,配置RTMP、HLS
查到f配置⽂件(路径/usr/local/etc/f),配置RTMP、HLS。
①在http节点之前添加 rtmp 的配置内容:
②在http中添加 hls 的配置
3. 重启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.1更多命令,请参考:
FFmpeg处理RTMP流媒体的命令⼤全
FFmpeg常⽤推流命令
七、H5 直播视频播放
移动端iOS和 Android 都天然⽀持HLS协议,做好视频采集端、视频流推流服务之后,便可以直接在H5页⾯配置 video 标签播放直播视频。
<video controls preload=“auto” autoplay=“autoplay” loop=“loop” webkit-playsinline>
<source src=“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 上,前端可尽量做到 D
NS 缓存等。
③ H5 直播为了达到更好的实时互动,也可以采⽤RTMP协议,通过video.js 实现播放。
总结
以上所述是⼩编给⼤家介绍的HTML5实现视频直播功能思路详解,希望对⼤家有所帮助,如果⼤家有任何疑问请给我留⾔,⼩编会及时回复⼤家的。在此也⾮常感谢⼤家对⽹站的⽀持!