前言
直播越来越成为趋势,因为疫情的冲击,不管是直播带货还是直播教育等等,将线上模式推上了巅峰~ 因为业务和兴趣关系,稍微研究了一下在H5中直播的相关知识。 PS:如果你对直播有所了解,可以skip全篇文章啦,本篇文章只涉及到一些直播相关的初级知识。
- 稍微了解一下直播的架构。
- 直播的协议。
- 微信小程序中的直播。
- 本地自己搞一个h5的直播小demo。
直播的架构
如上图:首先推流
就可以简单理解成你的摄像头,负责采集图像,并将数据流推送到服务器。其次拉流
可以理解成你的播放器,负责将图像数据流从服务器上拉取下来。然后就是媒体流服务器
,我们通常都是直接使用第三方的服务器,比方说腾讯云直播,阿里云直播等等,简单绑定域名和申请之后就能够直接使用啦~ 当然在本文最后我们会自己搭建一个非常简单的媒体流服务器。
常见的直播协议
HLS
网上相关信息很多大同小异,总结一下:苹果公司设计的,延迟很大,但是兼容性超强(h5 video标签兼容性)。
该协议原理简单来说,http请求下载playlist文件(.m3u8),里面包含切片文件信息(.ts文件),随后下载ts文件feed给video进行播放
,如上图所示:m3u8文件中包含三个切片.ts
文件,每个文件为targetDuration = 9s
,看到左侧的三个ts文件分别是38,39,40,右侧的三个ts文件是39,40,41,以此类推,新的playlist文件被依次下载,同时新的ts文件被下载到浏览器并进行播放。
HLS这么大的延迟也好理解,因为需要等多个ts切片文件生之后再发给播放器,然而每个ts切片文件都在10s左右,所以这个延迟是模式设计上不可避免的。
RTMP
这个协议也总结下:adobe公司的似有协议(所以浏览器播放都需要插件),必须要flash播放器才能播放,延迟超短,基于TCP长链接,无需多次握手。
虽然该协议的延迟很短很优秀,但是需要flash真的是硬伤,各大浏览器已经对外宣称将不再支持flash,所以此协议到此为止~感兴趣的同学在网上搜一下到处都是。
DASH
dash的兼容性也很强,配上dash.js基本上主流浏览器(支持MEDIA SOURCE EXTENSION的)都能够支持这个协议,延迟也很低,该协议之下也是将流文件变成切片文件,据说youtube和netflix都是用了这个协议,如果你打开network面板的话和HLS很像,一直在不断的下载新文件。
HTTP-FLV
国内的主流直播平台都是用的这个协议,该协议不再是不断下载切片
文件了,而是通过不设置content-length
的header,使得http请求不间断的持续下载
如上图所示是我在B站直播中随便找的一个网络请求,该文件是以.flv
结尾的文件,还可以看到该文件的大小在我截图的瞬间已经达到了40多mb。
HTTP-FLV的协议延时很低,自己用腾讯云亲测能够达到5s以内,另外要说的就是开源库flv.js
,应该是次库开创了国内web直播播放flv格式的先河,这个库也是用到了MEDIA SOURCE EXTENSION
接口,才使得h5标签上能够播放flv文件。
Media Source Extension(MSE)
上文中有两次提到了Media Source Extension
,一个是在h5播放dash
,一个是在播放flv
格式的时候,api结构图如下:
从图中可以得知,MediaSource
中包含SourceBuffer
,而SourceBuffer
中包含了一个个Track
,每一个Track就是我们常说的音轨和视轨,我们可以通过一些提供的接口对Track进行操作,比方说切换Track,播放或者暂停Track甚至跳转到Track的某一帧等(没有深层去了解,因为毕竟了解太多伤身~)。下面的实例代码简单的展示了如何使用MSE:
var vidElement = document.querySelector('video');
if (window.MediaSource) {
var mediaSource = new MediaSource();
vidElement.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', sourceOpen);
} else {
console.log("The Media Source Extensions API is not supported.")
}
function sourceOpen(e) {
URL.revokeObjectURL(vidElement.src);
var mime = 'video/webm; codecs="opus, vp9"';
var mediaSource = e.target;
var sourceBuffer = mediaSource.addSourceBuffer(mime);
var videoUrl = 'droid.webm';
fetch(videoUrl)
.then(function(response) {
return response.arrayBuffer();
})
.then(function(arrayBuffer) {
sourceBuffer.addEventListener('updateend', function(e) {
if (!sourceBuffer.updating && mediaSource.readyState === 'open') {
mediaSource.endOfStream();
}
});
sourceBuffer.appendBuffer(arrayBuffer);
});
}
sourceopen
事件是当我们将mediaSource赋值给video的src标签的时候会被trigger,然后我们在这个事件的回调中去fetch视频流,并将其存放到arrayBuffer中,再appendBuffer到sourceBuffer中。我的理解就是Media Source Extension
这个东西可以将比方的内容变成流然后喂给video标签,使得原本video无法播放的内容变成可以播放。
MediaSource.isTypeSupported('video/mp4; codecs="avc1.42E01E, mp4a.40.2"')
另外这个接口是用来检测检MSE
是否支持某个特定的编码和容器盒子
In Conclusion
微信小程序中的直播
微信小程序中如果你想要植入直播事件很简单的事情,使用live-pusher
组件进行推流,感觉说白了就是打开摄像头进行录影,然后使用live-player
组件进行播放。中间的媒体服务器可以直接使用腾讯云的(毕竟腾讯自家产品),下图分别是生成的拉流和推流地址。
在腾讯云中绑定好直播域名,直接在辅助工具
中输入自定义的AppName
和StreamName
就能够生成相应的推流和拉流地址,然后将生成的推流拉流地址作为live-pusher
和live-player
的url输入就可以啦。这里注意微信小程序只支持rtmp和flv格式的拉流。
本地搭建一个直播demo
推流使用OBS
,这个工具很强大,可以直播你的整个桌面,你的camera,甚至某一个window等等,在设置中有一个Stream
选项,里面输入对应的Server地址就行
媒体服务器
node-media-server
这个媒体服务器充当着上面的腾讯云
中的功能,将你推流上去的数据进行转码之后下发到拉流端,介绍一个node写的服务器叫做node-media-server
:
配置很简单,将端口1936
作为rtmp的推流端口,8002
开启http的拉流端口,然后本地开始使用ffmpeg
进行转码,在8002
上可以拉取到各种协议下的播放流如下图:
NGINX RTMP Module
NGINX的一个模块,具体使用方法不再赘述,以下是该模块的配置:
rtmp {
server {
listen 1935; # Listen on standard RTMP port
chunk_size 4000;
application show {
live on;
# Turn on HLS
hls on;
hls_path /mnt/hls/;
hls_fragment 3;
hls_playlist_length 60;
# disable consuming the stream from nginx as rtmp
deny play all;
}
}
}
拉流播放器
这里就是我们选择播放用的播放器啦,各种各样,可以使用比方说之前提到的flv.js来播放http-flv协议啦,使用dash.js播放dash协议的啦。除了再使用web上的播放器,当然你还可以本地下载一个VLC播放器app,能够播放各种协议的内容~ 到此本地的demo运行起来就可以看到效果啦。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!