挪动端:https://cloud.tencent.com/developer/ask/24304
pc 端:hls.js 反对 m3u8
视频编码格局
- 视频文件格式(容器格局)
- 视频编解码器(视频编码格局)
- 视频一开始由两个端采集,视频输出口、音频输出口。采集的数据会别离进行相干解决,简而言之就是:将视频 / 音频流通过肯定的伎俩转换为比特流并且压缩,最终,这里将比特流以肯定程序放到一个盒子里进行寄存,从而宣称咱们最终所看到的音视频格局。如:mp3/mp4/flv
罕用直播协定
协定 | 原理 | 传输协定 | 播放器 | 延时 | 兼容 |
---|---|---|---|---|---|
RTMP | 每个时刻的数据收到后立刻转发 | TCP | flash | 1-3s | 须要 flash 播放器,借助 video.js 实现浏览器端播放(pc 端) |
HLS | HTTP Live Streaming , 汇合一段时间的数据 m3u8,生成 ts 切片文件,播放完一个列表,在更新下一个列表 | HTTP | video | 10-30s | 苹果公司实现 IOS 和 高版本 Android 均反对,h5 能够间接播放 |
HTTP-FLV | FLV 是专门针对 Flash 播放器的 | HTTP | 1-3s | h5 反对(须要反对 MSE 的浏览器)mse 兼容状况 |
RTMP 全称 Real Time Messageing Protocol 即时消息传送协定
- Adobe 公司为 flash 播放器和服务器之间音视频传输开发的公有协定,工作在 TCP 之上的明文协定
长处:
RTMP 是转为流媒体开发的协定,对底层优化比其余协定更加优良,同时他 Adobe flash 反对好,基本上所有的编码器(摄像头之类)都反对 RTMP 输入
RTMP 由 TCP 长连贯协定,所以客户端向服务端推流这些操作而言,延时性很低。pc 次要是 windows,windows 的浏览器根本都反对 flash,另外 RTMP 适宜长时间播放,最初 RTMP 的提早绝对较低,个别延时 1 -3s
毛病:
基于 TCP 传输,非公共端口,可能会被防火墙拦挡
另一方面,RTMP 为 Adobe 公有协定,很多设施无奈播放,特地是在 ios 端,须要第三方解码器能力播放
无奈在 ios 的 H5 页面播放,但 ios 原生利用能够本人写解码去解析
FLV (Flash Video) 是 Adobe 的另一种视频格式,是一种在网络上的流媒体数据存储容器格局
长处:
格局绝对简略轻量,不须要很大媒体头部信息
flv 由 The FLV Header,The Flv Body 以及其 Tag 组成。因而加载速度很快。采纳 FLV 格局封装的文件后缀为 .flv
咱们所说的 HTTP-FLV 即流媒体数据封装成 FLV 格局,而后通过 HTTP 协定传输给客户端
HTTP-FLV 依附 MIME 的个性,依据协定中的 Content-Type 来抉择相应的程序去解决相应的内容,使得流媒体能够通过 HTTP 传输
相较于 RTMP 协定,HTTP-FLV 可能好的穿透防火墙,它是基于 HTTP/80 传输
flv.js
愿景:从 flash 视频时代残缺的适度到 h5 时代
原理:用 js 解析 FLV 格局的音视频数据,再通过 Media Source Extensions API 喂给原生 HTML5 标签(H5 原生仅反对播放 mp4、webm、ogg 等,不反对 flv)兼容状况 [https://www.jianshu.com/p/c102ae2a319d](https://www.jianshu.com/p/c102ae2a319d)
参考:用 flv.js 做直播 [https://github.com/gwuhaolin/blog/issues/3](https://github.com/gwuhaolin/blog/issues/3)
原理:[https://www.zhihu.com/question/51997376](https://www.zhihu.com/question/51997376)
Media Source Extensions
在没有 MSE 呈现之前,前端对 video 的操作,仅仅局限在对视频文件的操作,而并不能对视频流做任何相干操作
当初 MSE 提供一些列接口,是开发者能够间接提供 media stream
应用 flv.js 疾速搭建 html5 网页直播:[https://zhuanlan.zhihu.com/p/94440420](https://zhuanlan.zhihu.com/p/94440420)
HLS
它不是一下申请残缺流,由.m3u8 文件和 .ts 播放文件组成,服务器会将承受到的视频流进行缓存,而后缓存到肯定水平后,会将这些视频流编码格式化同时会生成一份 .m3u8 文件和其余很多的.ts 文件
客户端只有不停地按序播放从服务器获取到的文件,从而实现播放音视频
.m3u8 文件只是寄存了一些 ts 文件的配置信息和相干门路,当视频播放时 .m3u8 是动静扭转的,video 标签会解析这个文件
并找到对应的 ts 文件来播放,个别为了加快速度 .m3u8 放在 web 服务器上,ts 放在 cdn 上
m3u8 文件信息
#EXTM3U # m3u 文件头
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:2133 # 第一个 TS 分片的序列号
#EXT-X-TARGETDURATION:6 # 每个分片 TS 的最大时长
#EXTINF:6.375, # 指定每个媒体段 (ts) 的持续时间,仅对前面的 URI 无效
huputv-ali-live.arenacdn.com_SFlDeHJTSU51NTdV_pbk550-1587696415663.ts?auth_key=1587706605-0-0-10fedd520ec472c1a5dc39d0dcf2984f
#EXTINF:6.375,
huputv-ali-live.arenacdn.com_SFlDeHJTSU51NTdV_pbk550-1587696421958.ts?auth_key=1587706605-0-0-c8d8918ccba170a99f518b55aa2ea290
#EXTINF:6.375,
huputv-ali-live.arenacdn.com_SFlDeHJTSU51NTdV_pbk550-1587696428405.ts?auth_key=1587706605-0-0-f00ab35ac2c77091ac1e7ef693cde112
#EXTINF:6.375,
huputv-ali-live.arenacdn.com_SFlDeHJTSU51NTdV_pbk550-1587696434822.ts?auth_key=1587706605-0-0-08051ceb940b5d0a52292ab9c6e510dd
#EXTINF:6.375,
huputv-ali-live.arenacdn.com_SFlDeHJTSU51NTdV_pbk550-1587696441198.ts?auth_key=1587706605-0-0-fba4c6b281980017fa08a6139fc74a9d
#EXTINF:6.375,
huputv-ali-live.arenacdn.com_SFlDeHJTSU51NTdV_pbk550-1587696447480.ts?auth_key=1587706605-0-0-c3b335be3abe37b37af3339875610851
HLS 协定的申请流程
- HTTP 申请 m3u8 的 url(video 标签)
- 服务端返回一个 m3u8 的播放列表,这个播放列表(TS)是实时更新的
- 客户端解析 m3u8 的播放列表,再按序申请每一段 url 获取 ts 流
编码:以 H.264 格局对图像进行编码,以 mp3 或者 HE-AAC 对声音进行编码,最终打包到 MPEG-2 TS(Transport Stream)容器之中
宰割:把编码好的 TS 文件等长切分成后缀为 ts 的小文件,并生成 .m3u8 的纯文本索引
使用方便:客户端应用一个 URL 区下载 m3u8 文件(索引文件确保 ts 文件程序),而后开始下载 ts 文件,下载实现后即开始应用播放器播放
- 长处:
苹果公司开发的协定,ios 全系列产品原生反对,不须要任何插件,Android 也反对
穿透防火墙,基于 HTTP/80 传输,无效防止防火墙拦挡
性能高。通过 HTTP 传输,CDN 反对良好,且自带码率自适应(Apple 在提出 HLS 时,就曾经思考了码率自适应问题)
- 毛病:
实时性差,提早高,HLS 的提早根本在 10s+ 以上
1. TCP 握手
2. m3u8 文件下载
3. m3u8 下的 ts 文件下载, 每个 ts 文件大略寄存 5 -10s 的时长,并且每个 m3u8 文件会寄存 3- 8 个 ts 文件
如果把 ts 文件时长足够小,m3u8 寄存文件足够少,则实践提早会升高,但会减少服务器压力
同时直播会受网络稳定影响较大
文件碎片,个性的双刃剑,ts 切片较小,会造成海量文件,对存储和缓存都有肯定的挑战
- 使用方便:
<video controls autoplay>
<source src="http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8" type="application/vnd.apple.mpegurl" />
<p class="warning">Your browser does not support HTML5 video.</p>
</video>
市面支流 h5 直播平台
声网:webrtc 直播 sdk 兼容状况:
https://docs.agora.io/cn/Interactive%20Broadcast/start_live_web?platform=Web
利用 JSMpeg + socket 进行直播
因为 video 挪动端蹩脚的体验,JSMpeg 另辟蹊径,利用 canvas 渲染视频帧播放视频 audio 播放音频
该计划 能够自在布局
https://github.com/phoboslab/jsmpeg
https://tantao.me/2017/12/23/Canvas%E5%AE%9E%E7%8E%B0%E7%A7%BB%E5%8A%A8%E7%AB%AF%E7%BD%91%E9%A1%B5%E8%A7%86%E9%A2%91%E7%9B%B4%E6%92%AD/
直播整体流程
视频采集端:能够是电脑上音视频输出设施、手机端摄像头、麦克风(RTMP 流传输视频数据)
直播流视频服务端:一台 nginx 服务器,采集视频录制端传输的视频流(H264/ACC 编码),由服务端进行解析编码,推送 RTMP/HLS 格局视频流至视频播放端
视频播放端:能够是电脑上的播放器(QuickTime Player VLC),手机端的 native 播放器,还有就是 H5 的 video 标签
- h5 录制视频,应用 webRTC(web Real-Time Communication)是一个反对网页浏览器进行实时语音或视频对话的完结
- 毛病只在 pc 的 Chrome 上反对较好,挪动端反对不现实
1. 调用 window.navigator.webkitGetUserMedia({video: true, audio: true}, res => console.log(res), err=>console.log(err)) 获取 pc 摄像头视频数据
2. 将获取到的视频数据转换成 window.webkitRTCPeerConnection 一种视频数据流格局
3. 利用 websocket 将视频数据流数据传输到服务端
4. webrtc 采集视频流
<!DOCTYPE html>
<html>
<head>
<title>rtc</title>
</head>
<body>
<video id="webcam"></video>
<img src="">
<canvas style="display:none;"></canvas>
</body>
<script type="text/javascript">
var constraints = {video: true, audio: true};
// function getSnap() {// var video = document.getElementById('webcam');
// var canvas = document.querySelector('canvas');
// var ctx = canvas.getContext('2d');
// var localMediaStream = null;
// function snapshot() {// if (localMediaStream) {// ctx.drawImage(video, 0, 0);
// //“image/webp”对 Chrome 无效,// // 其余浏览器主动降为 image/png
// document.querySelector('img').src = canvas.toDataURL('image/webp');
// }
// }
// video.addEventListener('click', snapshot, false);
// navigator.getUserMedia({video: true}, function(stream) {// // video.src = window.URL.createObjectURL(stream);
// video.srcObject = stream
// video.play();
// localMediaStream = stream;
// }, err => console.log(err));
// }
// getSnap()
function getVideo() {function onSuccess(stream) {var video = document.getElementById('webcam');
video.srcObject = stream;
// 前解决编码(如:美颜、滤镜、AR 特效等,可能须要借助 webassembly 解决)// RTMP 推流
video.play();}
function onError(error) {console.log("navigator.getUserMedia error:", error);
}
navigator.getUserMedia(constraints, onSuccess, onError);
}
// getVideo();
</script>
</html>
IOS 原生利用调用摄像头录制过程
搭建 Nginx+RTMP 直播流服务
- 装置 nginx-rtmp-module 或者 simple-nginx-rtmp-module
- nginx.conf 配置 RTMP/HLS
- 重启 nginx 服务
服务端流转换格局、编码推流
服务端接管到采集视频录制端传输过去的视频流时,须要对其进行编码,推送 RTMP/HLS/FLV 格局视频流至视频播放端
罕用编码库计划:x264 编码 faac 编码 ffmpeg 编码
参考文章:https://www.bilibili.com/read/cv193334/
西瓜视频播放器调研
小程序直播
<live-pusher mode=”HD” url=”rtmp://”>
负责对手机摄像头和麦克风的数据进行采集和编码,并通过 url 参数指定的 rtmp 推流地址上传到云端
<live-player mode=”live”>
小程序外部的一个在线播放器,负责从云端实时拉去音视频数据进行解码和渲染,http-flv 协定播放
mode=”RTC”
RTC 模式:实现端到端可能以很低的时延传输音视频数据,用于实时视频通话
官网文档:https://developers.weixin.qq….
https://developers.weixin.qq….
教程:
https://blog.51cto.com/phperv…
https://zhuanlan.zhihu.com/p/…
支流播放器介绍:
xgplayer、alipayer、ckplayer、clappr
原理:播放 m3u8 或者 flv 格局的直播流(挪动端天生反对 m3u8)底层都是依赖 hls.js 或者 flv.js 将其转码喂给 video 标签
挪动端间接应用 video 标签即可
支流播放器:https://github.com/Tinywan/ht…
参考文章
参看文章:
全面进阶 h5 直播 https://zhuanlan.zhihu.com/p/…
腾讯 Bugly-h5 视频直播哪些事 https://zhuanlan.zhihu.com/p/… 举荐 hls 流
h5 直播起航 https://aotu.io/notes/2016/10…
H5 直播 MSE(Mdia Source Extensions)https://www.jianshu.com/p/1bf…
企鹅直播点播实际 https://zhuanlan.zhihu.com/p/… 优先:webrtc、降级:hls
直播协定抉择 RTMP vs HLS http://www.samirchen.com/ios-…
直播问题踩坑 https://www.cnblogs.com/1wen/…
pc 端 利用 hls.js 播放 m3u8 https://my.oschina.net/yizhic… https://www.zhihu.com/questio…
hls.js 原理:https://juejin.im/entry/5a02d…
花椒直播:flv.js hls.js 剖析 https://zhuanlan.zhihu.com/p/…