Flv.js
HTTP-FLV: 基于HTTP流式IO传输FLV,依赖浏览器支持播放FLV。
WebSocket-FLV: 基于WebSocket传输FLV,依赖浏览器支持播放FLV。WebSocket建立在HTTP之上,建立WebSocket连接前还要先建立HTTP连接。
HLS: Http Live Streaming,苹果提出基于HTTP的流媒体传输协议。HTML5可以直接打开播放。
RTP: 基于UDP,延迟1秒,浏览器不支持。
在支持浏览器的协议里,延迟排序是:
RTMP = HTTP-FLV = WebSocket-FLV < HLS
而性能排序恰好相反:
RTMP > HTTP-FLV = WebSocket-FLV > HLS
也就是说延迟小的性能不好。
代码如下(示例):
<div class="mainContainer">
<video name="videoElement" class="centeredVideo" id="videoElement" autoplay></video>
<div class="btnList">
<div class="playbtn" @click="flvPLayOrPause()">
<i v-if="pauseOrPlay" class="el-icon-video-play"></i>
<i v-else class="el-icon-video-pause"></i>
</div>
</div>
</div>
代码如下(示例):
flvInit() {
let flvurl = this.configflv.flvurl
let flvtype = this.configflv.flvtype
let videoElement = document.getElementById("videoElement");
let flvPlayer = flvjs.createPlayer(
{
type: flvtype,
isLive: true,
hasAudio: false,
hasVideo: true,
withCredentials: false,
cors: true,
url: flvurl
},
{
enableWorker: true,
//lazyLoadMaxDuration: 3 * 60,
//seekType: 'range',
//fixAudioTimestampGap: false,
enableStashBuffer: false,
autoCleanupSourceBuffer: true
}
);
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
this.flvPlayer = flvPlayer
videoElement.play();
},
FLV里所包含的视频编码必须是H.264,音频编码必须是AAC或MP3, IE11和Edge浏览器不支持MP3音频编码,所以FLV里采用的编码最好是H.264+AAC,这个让音视频服务兼容不是问题。
对于录播,依赖 原生HTML5 Video标签 和 Media Source Extensions API
对于直播,依赖录播所需要的播放技术,同时依赖 HTTP FLV 或者 WebSocket 中的一种协议来传输FLV。其中HTTP FLV需通过流式IO去拉取数据,支持流式IO的有fetch或者stream
flv.min.js 文件大小 164Kb,gzip后 35.5Kb,flash播放器gzip后差不多也是这么大。
由于依赖Media Source Extensions,目前所有iOS和Android4.4.4以下里的浏览器都不支持,也就是说目前对于移动端flv.js基本是不能用的。
PC端
优先使用 HTTP-FLV,因为它延迟小,性能也不差1080P都很流畅。
不支持 flv.js 就使用 Flash播放器播 RTMP 流。Flash兼容性很好,但是性能差默认被很多浏览器禁用。
不想用Flash兼容也可以用HLS,但是PC端只有Safari支持HLS
移动端
优先使用 HTTP-FLV,因为它延迟小,支持HTTP-FLV的设备性能运行 flv.js 足够了。
不支持 flv.js 就使用 HLS,但是 HLS延迟非常大。
HLS 也不支持就没法直播了,因为移动端都不支持Flash。
代码如下(示例):
<template>
<div class="mainContainer">
<video name="videoElement" class="centeredVideo" id="videoElement" autoplay></video>
<div class="btnList">
<div class="playbtn" @click="flvPLayOrPause()">
<i v-if="pauseOrPlay" class="el-icon-video-play"></i>
<i v-else class="el-icon-video-pause"></i>
</div>
</div>
</div>
</template>
<script>
import flvjs from 'flv.js'
export default {
name: "flv-media",
props: {
configflv: {
type: Object,
default: () => {
return {};
}
}
},
watch:{
configflv: {
handler(newval, oldval) {
if(newval.flvurl && newval.flvurl!=""){
this.flvInit()
}
}
}
},
data() {
return {
flvPlayer: null, // flv实例
pauseOrPlay: false,
};
},
methods: {
flvInit() {
let flvurl = this.configflv.flvurl
let flvtype = this.configflv.flvtype
let videoElement = document.getElementById("videoElement");
let flvPlayer = flvjs.createPlayer(
{
type: flvtype,
isLive: true,
hasAudio: false,
hasVideo: true,
withCredentials: false,
cors: true,
url: flvurl
},
{
enableWorker: true,
//lazyLoadMaxDuration: 3 * 60,
//seekType: 'range',
//fixAudioTimestampGap: false,
enableStashBuffer: false,
autoCleanupSourceBuffer: true
}
);
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
this.flvPlayer = flvPlayer
videoElement.play();
},
flvPLayOrPause(){
let videoElement = document.getElementById("videoElement");
let pauseOrPlay = this.pauseOrPlay
if(pauseOrPlay){
videoElement.play();
}else{
videoElement.pause();
}
this.pauseOrPlay = !this.pauseOrPlay
},
destroyFlv(){
// this.flvPlayer.pause();
// this.flvPlayer.unload();
this.flvPlayer.detachMediaElement();
this.flvPlayer.destroy();
this.flvPlayer = null;
}
},
beforeDestroy(){
this.destroyFlv()
}
};
</script>
<style scoped>
.mainContainer {
width: 100%;
height: 100%;
background-color: #222;
}
.centeredVideo {
width: 100%;
height: calc(100% - 36px);
}
.btnList {
width: 100%;
height: 36px;
background-color: #666;
}
.playbtn{
width: 36px;
height: 36px;
margin: 0 auto;
text-align: center;
line-height: 36px;
background-color: #999;
}
.playbtn i{
color: #cccccc;
font-size: 30px;
}
</style>