首先,要感谢 DEV Club 能给我一个这么好的平台,在那里学到大牛们分享的技术.这次感谢的是吕鸣,吕哥的这么好的分享.从中学到很多,在这做个摘抄笔记.这是吕哥的博客,大家可以去学习哦! http://www.nihaoshijie.com.cn
1.移动视频直播的发展,大家看下面这张图
可以看到,直播从PC到一直发展到移动端,越来越多的直播类app上线,同时移动直播进入了前所未有的爆发阶段,但是对于大多数移动直播来说,还是要以Native客户端实现为主,但是H5在移动直播端也承载着不可替代的作用,例如H5有着传播快,易发布的优势,同时最为关键的时H5同样可以播放直播视频。大家可以看下面这张大概的实现图
完整的直播可以分为以下几块:
1) 视频录制端:一般是电脑上的音视频输入设备或者手机端的摄像头或者麦克风,目前以移动端的手机视频为主。
2) 视频播放端:可以是电脑上的播放器,手机端的native播放器,还有就是h5的video标签等,目前还是已手机端的native播放器为主。
3) 视频服务器端:一般是一台nginx服务器,用来接受视频录制端提供的视频源,同时提供给视频播放端流服务。
大家可以看下大致的结构图:
2.怎样使用H5录制视频:
对于H5视频录制,可以使用强大的webRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音对话或视频对话的技术,缺点是只在PC的chrome上支持较好,移动端支持不太理想。使用webRTC录制视频基本流程是:
1)调用window.navigator.webkitGetUserMedia()获取用户的PC摄像头视频数据。
2)将获取到视频流数据转换成window.webkitRTCPeerConnection(一种视频流数据格式)。
3)利用webscoket将视频流数据传输到服务端
由于许多方法都要加上浏览器前缀,所以很多移动端的浏览器还不支持webRTC,所以真正的视频录制还是要靠客户端(ios,android)来实现,效果会好一些。
3.H5播放直播视频:
对于视频播放,可以使用HLS(HTTP Live Streaming)协议播放直播流,ios和android都天然支持这种协议,配置简单,直接使用video标签即可。
下面是简单的代码使用video播放直播视频:
4.下面说一下什么是HLS协议:
简单讲就是把整个流分成一个个小的,基于HTTP的文件来下载,每次只下载一些,前面提到了用于H5播放直播视频时引入的一个.m3u8的文件,这个文件就是基于HLS协议,存放视频流元数据的文件。
每一个.m3u8文件,分别对应若干个ts文件,这些ts文件才是真正存放视频的数据,m3u8文件只是存放了一些ts文件的配置信息和相关路径,当视频播放时,.m3u8是动态改变的,video标签会解析这个文件,并找到对应的ts文件来播放,所以一般为了加快速度,.m3u8放在web服务器上,ts文件放在cdn上。
.m3u8文件,其实就是以UTF-8编码的m3u文件,这个文件本身不能播放,只是存放了播放信息的文本文件,打开之后就是这个样子
这个是ts文件,就是存放视频的文件:
5.接下来是HLS的请求流程:
1) http请求m3u8的url。
2) 服务端返回一个m3u8的播放列表,这个播放列表是实时更新的,一般一次给出5段数据的url。
3) 客户端解析m3u8的播放列表,再按序请求每一段的url,获取ts数据流。
大概是这个流程:
6.关于HLS直播延时:
更多关于延迟的问题可以参考苹果官方地址:https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StreamingMediaGuide/FrequentlyAskedQuestions/FrequentlyAskedQuestions.html
但是H5直播视频却有一些不可替代的优势:
1)传播性好,利于分享等操作。
2)可以动态发布,有利于实时迭代产品需求并迅速上线。
3)不用安装app,直接打开浏览器即可
7.下面说一下怎样利用ios来采集(录制)音视频数据
关于音视频采集录制,首先明确下面几个概念:
视频编码:所谓视频编码就是指通过特定的压缩技术,将某个视频格式的文件转换成另一种视频格式文件的方式,我们使用的iphone录制的视频,必须要经过编码,上传,解码,才能真正的在用户端的播放器里播放。
编解码标准:视频流传输中最为重要的编解码标准有国际电联的H.261、H.263、H.264,其中HLS协议支持H.264格式的编码。
音频编码:同视频编码类似,将原始的音频流按照一定的标准进行编码,上传,解码,同时在播放器里播放,当然音频也有许多编码标准,例如PCM编码,WMA编码,AAC编码等等,这里我们HLS协议支持的音频编码方式是AAC编码。
利用ios上的摄像头,进行音视频的数据采集,主要分为以下几个步骤:
1) 音视频的采集,ios中,利用AVCaptureSession和AVCaptureDevice可以采集到原始的音视频数据流。
2) 对视频进行H264编码,对音频进行AAC编码,在ios中分别有已经封装好的编码库来实现对音视频的编码。
3) 对编码后的音、视频数据进行组装封包;
4) 建立RTMP连接并上推到服务端。
下面是具体的采集音视频数据的流程:
8.关于RTMP:
Real Time Messaging Protocol(简称 RTMP)是 Macromedia 开发的一套视频直播协议,现在属于 Adobe。和HLS一样都可以应用于视频直播,区别是RTMP基于flash无法在ios的浏览器里播放,但是实时性比HLS要好。所以一般使用这种协议来上传视频流,也就是视频流推送到服务器。
下面是HLS和RTMP的对比:
9.下面说一下推流
所谓推流,就是将我们已经编码好的音视频数据发往视频流服务器中,在ios代码里面一般常用的是使用rtmp推流,可以使用第三方库librtmp-iOS进行推流,librtmp封装了一些核心的api供使用者调用。例如推流api等等,配置服务器地址,即可将转码后的视频流推往服务器。
那么如何搭建一个推流服务器呢
简单的推流服务器搭建,由于我们上传的视频流都是基于rtmp协议的,所以服务器也必须要支持rtmp才行,大概需要以下几个步骤:
1) 安装一台nginx服务器。
2) 安装nginx的rtmp扩展,目前使用比较多的是https://github.com/arut/nginx-rtmp-module
3) 配置nginx的conf文件
4) 重启nginx,将rtmp的推流地址写为rtmp://ip:1935/hls/mystream,其中hls_path表示生成的.m3u8和ts文件所存放的地址,hls_fragment表示切片时长,mysteam表示一个实例,即将来要生成的文件名可以先自己随便设置一个。更多配置可以参考:https://github.com/arut/nginx-rtmp-module/wiki/
下面是nginx的配置文件
10.直播中的用户交互:
对于直播中的用户交互大致可以分为:
1)送礼物
2)发表评论或者弹幕
对于弹幕来说,要稍微复杂一些,可能需要关注以下几点:
对于送礼物,在H5端可以利用dom和css3实现送礼物逻辑和一些特殊的礼物动画,实现技术难点不大。
1) 弹幕实时性,可以利用webscoket来实时发送和接收新的弹幕并渲染出来。
3) 对于不支持webscoket的浏览器来说,只能降级为长轮询或者前端定时器发送请求来获取实时弹幕。
3)弹幕渲染时的动画和碰撞检测(即弹幕不重叠)等等
11.最后讲一下目前较为成熟的直播产品,大致都是以server端和H5和Native(android,ios)搭配实现直播:
基本是下图这个套路:
所以H5在整个直播中,还是有着重要的地位的!
最后,根据本次分享的内容,吕哥这边实现了一个ios端录制,推流,NGINX接收流,同时分发的HLS直播流的一整套demo,感兴趣的同学可以看下面这个链接https://github.com/lvming6816077/LMVideoTest
下面互动问答:
A0:移动端这边怎么进行编码转码?用ffmpeg编译时很麻烦
答:关于ios这边,其实不用关心转码问题,因为已经有了很多开源的库提供给我们了例如x264编码:https://github.com/kewlbear/x264-ios
faac编码:https://github.com/fflydev/faac-ios-build
A1.您介绍的都是native 播放和还有 h5的 video 标签播放, iOS端有没有考虑过整个用原生的 oc或者 swift 实现?
答:关于播放端,其实真正体验好的还是要用native来实现的,而且native实现可以用rtmp来播放直播,延迟会好很多,H5来播直播主要是考虑到易传播性好。