前端视频直播技术总结及video.js在h5页⾯中的应⽤
全⼿打原创,转载请标明出处:,多谢,=。=~
(如果对你有帮助的话请帮我点个赞啦)
⽬前有⼀个需求是在移动端上内嵌h5实现点位的视频直播,直播项⽬采⽤Vue编写,后端主要输出 RTMP 和 HLS 协议的直播流,本⽂主要总结⼀下整体开发的技术选型以及开发过程中的思考与学习总结。
流媒体传输
我的困惑:什么是流媒体,以及其传输⽅式是怎样的?
流媒体
流媒体是指采⽤流式传输⽅式在 Internet 上播放的媒体格式,例如⾳频、视频等多媒体⽂件。
流式传输⽅式
流式传输⽅式是将多媒体⽂件经过特殊压缩后分成⼀个个压缩包,再由服务器向客户端连续、实时传送。
⽤户不必像⾮流式传输那样等待整个⽂件全部下载完毕后才能播放,⽽是只需要经过⼏秒钟或⼏⼗秒的启动延时即可对压缩的⾳视频⽂件进⾏播放,剩余的部分将继续下载,直⾄播放完毕。
流媒体传输协议
常⽤的流媒体传输协议主要有 HTTP渐进式下载和实时流媒体协议两类。
HTTP渐进式下载:仅能传输完整的⾳视频⽂件,在给定时刻,⽤户只能观看已下载的那部分,⽽不能跳到还未下载的部分。HTTP边下载边播放,严格意义上讲,不是直播协议。他的原理是先下载⽂件的基本信息,⾳频视频的时间戳,再下载⾳视频数据,以播放mp4为例,先下载⽂件头,根据⽂件头指引下载⽂件尾,然后再下载⽂件的⾳视频数据。
实时流媒体协议:可⽤于实况直播,也可传输完整的⾳视频⽂件。例如RTSP/RTP、RTMP、HLS、HTTP-FLV。
RTSP协议
既可以基于UDP传输也可以基于TCP传输,是纯粹的传输控制协议,它本⾝与它负载的媒体数据不相关,RTSP协议需要⾃定义客户端向服务器发送RTSP命令。其视频数据由RTP传输,视频质量由RTCP控制,视频控制(如播放、暂停等)由RTSP提供。
常⽤直播流协议
我的困惑:哪些流媒体传输协议⽤于直播,不同类型之间⼜有什么区别?
RTMP(Real Time Messaging Protocol)
协议⽐较全能,既可以⽤来推送,⼜可以⽤来直播。其核⼼理念是将⼤块的视频帧和⾳频帧“剁碎”,然后以⼩数据包的形式在互联⽹上进⾏传输,且⽀持加密,因此隐私性相对⽐较理想,但拆包组包的过程⽐较复杂,所以在海量并发时容易出现⼀些不可预期的稳定性问题。
HLS(HTTP Live Streaming)
苹果推出的解决⽅案,将视频分成 5-10 秒的视频⼩分⽚,然后⽤ M3U8 索引表进⾏管理。由于客户端下载到的视频都是 5-10 秒的完整数据,故视频的流畅性很好,但也同样引⼊了很⼤的延迟(HLS 的⼀般延迟在 10-30s 左右)。相⽐于 FLV,HLS 在iPhone 和⼤部分Android ⼿机浏览器上的⽀持⾮常给⼒,所以常⽤于 QQ 和朋友圈的 URL 分享。
HTTP-FLV(Flash Video)
由 Adobe 公司主推,格式极其简单,只是在⼤块的视频帧和⾳视频头部加⼊⼀些标记头信息,由于这
种极致的简洁,在延迟表现和⼤规模并发⽅⾯都很成熟。唯⼀的不⾜就是在⼿机浏览器上的⽀持⾮常有限,但是⽤作⼿机端 APP 直播协议却异常合适。
RTMP、HLS、HTTP-FLV 协议对⽐如下图所⽰:
我的困惑: 想要实现直播,需要经历怎样的过程?
如果⽤⼀句话描述整体过程,其实就是直播时,主播端将直播流推向服务器,⽤户端发起请求从服务器拉视频流过来解码播放,流程如下图
所⽰:第⼀部分就是视频主播端的操作:视频采集处理后推流到流媒体服务器。⾸先从前端采集设备中获得原始的⾳频、视频数据;
为了增强额外效果,对⾳频进⾏混⾳、降噪等处理,可为视频打上时间戳、添加Logo ⽔印或增加滤镜;随后对⾳频、视频进⾏编码,通过编码压缩满⾜其在互联⽹上实时传输的需求;
编码后就可以把各种多媒体内容(视频、⾳频、字幕等)盛放在同⼀个容器⾥,也就是所谓的封装,使得不同多媒体内容可同步播放,与此同时还提供了索引;
最后就是通过流传输协议将封装好的内容推送到流媒体服务器上;
第⼆部分就是流媒体服务器:负责把从第⼀部分接收到的流进⾏处理并分发给⽤户。
流媒体服务器的主要功能是对流媒体内容进⾏采集(接收推流)、缓存、调度和传输播放(以流式协议实现⽤户分发)。
典型的流媒体服务器:微软的Windows Media Service (WMS ):它采⽤MMS 协议接收、传输视频,采⽤Windows Media Player (WMP )作为前端播放器;
RealNetworks 公司的Helix Server :采⽤RTSP/RTP 协议接收、传输视频,采⽤Real Player 作为播放前端播放器;
Adobe 公司的Flash Media Server :采⽤RTMP (RTMPT/RTMPE/RTMPS )协议接收、传输视频,采⽤Flash Player 作为前端播放器;
直播原理
第三部分就是⽤户:只需要拥有⽀持对应流媒体传输协议的播放器即可。
这⼀部分其实就是我们前端需要实现的,如何在移动端的内嵌h5页⾯中实现直播流的播放。所以我们只需要关注后端是通过什么协议给我们返回直播流以及我们如何有效的播放就可以了~
客户端直播插件
我的困惑:除了采⽤h5原⽣的 <video></<video> 标签,我们还能⽤什么插件实现视频直播,不同插件之间有什么区别?
经过我暴风式搜索后到三款常⽤并且⽀持实时流媒体播放的客户端插件(hls.js、video.js、vue-video-player),下⾯我们⼀个个道来。
hls.js
hls.js是⼀个可以实现HTTP实时流媒体客户端的js库,主要依赖于 <video></<video> 标签和 Media Source Extensions API。它的⼯作原理是将MPEG2传输流和AAC/MP3流转换成ISO BMFF (MP4)⽚段。由于hls.js是基于标准的 <video></<video> 标签实现播放,所以它不需要额外的播放器。
优点:包⽐较⼩,很纯净,UI可以根据⾃⼰的业务⾃⾏扩展,功能可以根据需求进⾏封装,⽐较灵活,⽽且专业直播HLS协议流。
缺点:对于常规的通⽤性播放器没有封装好的UI,功能上也需要⾃⼰调API实现,协议单⼀,只⽀持HLS。
video.js
video.js是⼀个基于h5的⽹络视频播放器,⽀持h5视频、现代流媒体格式(MP4、WebM、HLS、DASH等)以及YouTube、Vimeo,甚⾄连flash也⽀持(通过插件实现,后⾯会详细说明),可在桌⾯端或移动端实现视频播放。
优点:⽀持多种格式的流媒体播放,浏览器不⽀持时可实现优雅降级;专门有⼀套针对直播流的UI;插件机制强⼤,⽬前社区已有数百个⽪肤和插件供下载;兼容性好,⼏乎⽀持所有桌⾯及移动端的浏览器。
缺点:包⽐较⼤,实现hls直播的时候其实是内嵌了hls.js的代码,由于封装好UI和功能,使其不够灵活,修改UI时需要通过插件实现。
vue-video-player
vue-video-player其实就是将video.js集成到了Vue中,在Vue项⽬中使⽤起来会更⽅便。
移动端内嵌h5实现视频直播
1、技术选型:
传输协议——由于后端⽀持同时返回HLS协议和RTMP协议的直播流,结合考虑HLS协议的⾼延时问题和RTMP协议的兼容性问题,本项⽬决定采⽤向下兼容的⽅式实现,默认使⽤RTMP协议直播,当浏览器不⽀持时降级使⽤HLS协议播放。
直播插件——本项⽬基于Vue实现,并且业务逻辑为常规直播操作,⽆特殊需求,从开发效率、稳定性及兼容性出发,决定采⽤vue-video-player插件实现。
2、vue-video-player安装与引⼊:
CDN:
<link rel="stylesheet" href="path/to/video.js/dist/video-js.css"/>
<script type="text/javascript" src="path/to/video.min.js"></script>
<script type="text/javascript" src="path/to/vue.min.js"></script>
<script type="text/javascript" src="path/to/dist/vue-video-player.js"></script>
<script type="text/javascript">
Vue.use(window.VueVideoPlayer)
</script>
NPM(⽀持全局/按需引⼊): npm install vue-video-player --save
全局引⼊
import Vue from 'vue'
import VueVideoPlayer from 'vue-video-player'
/
/ 引⼊videojs样式
import 'video.js/dist/video-js.css'
// ⾃定义样式引⼊,并为<video-player>添加对应类名即可,例如vjs-custom-skin
// import 'vue-video-player/src/custom-theme.css'
Vue.use(VueVideoPlayer, /* {
options: 全局默认配置,
events: 全局videojs事件
} */)
按需引⼊
// 引⼊videojs样式
import 'video.js/dist/video-js.css'
import { videoPlayer } from 'vue-video-player'
export default {
components: {
videoPlayer
}
}
3、video.js插件扩展:当已有插件(video.js插件集合:)⽆法满⾜需求时可对已有插件进⾏扩展或⾃⾏开发video.js插件import videojs from 'video.js'
// videojs plugin
const Plugin = Plugin('plugin')
class ExamplePlugin extends Plugin {
//
}
// videojs language
videojs.addLanguage('es', {
Pause: 'Pausa',
//
})
// more
//
具体实现⽅式可参见:
4、视频直播关键代码:
options :
playsinline :设置播放器在移动设备上不全屏 [ Boolean, default: false ]
customEventName :⾃定义状态变更时的事件名 [ String, default: 'statechanged' ]
<template>
<video-player
class="video-player-box"
ref="videoPlayer"
:options="playerOptions"
:playsinline="true"
customEventName="customstatechangedeventname" @play="onPlayerPlay($event)"
@pause="onPlayerPause($event)"
@ended="onPlayerEnded($event)"
@waiting="onPlayerWaiting($event)"
@playing="onPlayerPlaying($event)"
@loadeddata="onPlayerLoadeddata($event)"
@timeupdate="onPlayerTimeupdate($event)"
@canplay="onPlayerCanplay($event)"
@canplaythrough="onPlayerCanplaythrough($event)" @statechanged="playerStateChanged($event)"
@ready="playerReadied">
</video-player>
</template>
原生js和js的区别
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论