前端在线预览播放视频方案,dpPlayer
华为云生成obs链接时,可以做配置。
- 视频是用来
预览
的 - 视频是用来
下载
的
一般我们播放本地视频都是使用vedio
标签,但是vedio
标签只支持三种视频格式:MP4、WebM、Ogg,对于在线视频直接使用vedio
不支持播放。
故,上述 2 中的视频,在vedio
中不支持播放,浏览器访问链接,直接就下载了。
先介绍几个概念:
流协议: 流协议就是在两个通信系统之间传输多媒体文件的一套规则,它定义了视频文件将如何分解为小数据包以及它们在互联网上传输的顺序,RTMP与 RTSP 是比较常见的流媒体协议。
HLS: HLS (HTTP Live Streaming)是Apple的动态码率自适应技术。主要用于PC和Apple终端的音视频服务。包括一个m3u(8)的索引文件,TS媒体分片文件和key加密串文件。参考:HLS。简单来说,HLS是一种协议,如果你的视频源是http://xxxx.m3u8这种,就选择这种协议,.m3u8是个文本文件,直播时,他的内容实时变更,内部指向一个或多个.ts文件。
HTTP-FLV: HTTP-FLV 是将音视频数据以 FLV 文件格式进行封装,再将 FLV 格式数据封装在 HTTP 协议中进行传输的一种流媒体传输方式。HTTP-FLV 的实现原理: HTTP-FLV 利用 HTTP/1.1 分块传输机制发送 FLV 数据。虽然直播服务器无法知道直播流的长度,但是 HTTP/1.1 分块传输机制可以不填写 conten-length 字段而是携带 Transfer-Encoding: chunked 字段,这样客户端就会一直接受数据。参考:FLV 和 HTTP-FLV。
简单来说就是你的视频源是直播且是xxxx.flv,就选择这种协议播放。还有个websocket-flv,是基于websocket的。
RTMP与RTSP: 什么是RTMP 和 RTSP?它们之间有什么区别?
H264(AVC)与H265(HEVC): 都是视频编码,是视频压缩格式,由于视频本身的码流太大,所以需要经过压缩然后再通过网络进行传输,其中H265是H264的升级版,很多播放器无法播放H265视频。
xgplayer
vue2的系统,本来用xgplayer
版本:2.32.5
。无奈本地可以展示,测试环境不能用,报错不明显,粗略看了一下是插件底层,内部报错,故放弃xgpalyer
插件。
ps.我在vue3的系统中,用过xgpalyer
插件,挺好用的
优点如下:
- 官网教程非常简单清晰,上手快
- 使用起来体验感很好
- 支持直播点播,支持hls、http+flv、dash、WebRTC直播,还有音乐播放器 。
- 提供在线可调试demo
dpplayer
然后,我就换了 dppalyer
插件来展示。点击查看中文文档
这个插件,我去github查了一下,15k星星,用的人还是挺多,但是,个人感觉不如 xgplayer
好用。
安装npm install dplayer --save
在页面中引用
import DPlayer from 'dplayer';
const dp = new DPlayer(options);
dpplayer
实现是通过生成iframe页面,将视频嵌套到其中。
刚开始给容器写了样式,宽100% 高100%,结果它不能自适应屏幕,很难受。后面我强行定宽420px。高度自动获取当前容器高度,定了一个最大高度。
但其实没有用,它会根据宽度,自己按比例缩放高度。
所以我在视频渲染出来后,自动调了一下全屏功能dpPlayer.fullScreen.request('web');
勉强解决了这个问题。
贴一下我的完整代码
<template>
<div class="vedio-wrapper" :style="{'max-height': winH}">
<el-empty v-if="!player" description="暂无数据"></el-empty>
<div :id="id" allowfullscreen="allowfullscreen" />
</div>
</template>
<script>
import DPlayer from 'dplayer';
import { getParam } from '@/utils/utils'
import {
getBucketObsFileUrl
} from '@/api/common'
export default {
name: 'previewMedia',
components:{},
data() {
return {
winH: '300px',
id: 'dpPlayerDom',
player: null
}
},
created() {
const winH = window.innerHeight
this.winH = winH + 'px'
},
mounted() {
this.getFileUrl()
},
methods: {
async getFileUrl() {
try {
const filePath = getParam('filePath')
const type = getParam('type') ? parseInt(getParam('type')) : 1
if (!filePath) return
const params = {
objectKey: filePath,
type
}
const data = await getBucketObsFileUrl(params);
this.setVedioplayerConfig(data)
} catch (e) {
console.error(e)
}
},
setVedioplayerConfig(url) {
if (!url) return
const tmpConfig = {
container: document.getElementById('dplayer'),
screenshot: false,
video: {
url: url,
thumbnails: 'thumbnails.jpg',
},
contextmenu: []
}
this.$nextTick(() => {
tmpConfig.container = document.getElementById(this.id)
const dpPlayer = new DPlayer(tmpConfig);
this.player = dpPlayer
dpPlayer.fullScreen.request('web');
})
}
}
}
</script>
<style scoped lang="scss">
.vedio-wrapper {
width: 400px;
height: 100%;
margin: 0 auto;
}
</style>
来源:juejin.cn/post/7355456165244239912