flv视频格式批量截取封面图(不占内存版)--其他视频格式也通用
- 需求(实现的效果)
- 功能实现
- html
- css
- js
需求(实现的效果)
批量显示视频,后端若返回有imgUrl,则直接显示图1,
若无,则需要根据视频地址自己截取,截取中显示图2,
截取过程中如图3,截取完直接返回图片信息,如图1格式,未返回的仍显示加载动画,如图2
功能实现
需要使用插件播放、截取flv格式视频。当前使用的是mpegts.js
具体使用可移步 vue使用mpegts.js教程
html
<div
:key="ind"
v-for="(ite, ind) in objects"
class="description-content"
>
<div
v-if="ite.fileUrl"
class="imgurlExit"
>
<!-- 显示图片封面背景 -->
<img
v-if="ite.imgUrl"
:src="ite.imgUrl"
class="descriptionImg"
/>
<!-- 无图片、纯黑背景 -->
<div
class="descriptionImg"
v-else
></div>
<!-- 播放图标 -->
<a-icon
type="play-circle"
class="centerIcon"
v-if="ite.imgUrl"
/>
<!-- 加载动画 -->
<img
src="@/assets/images/initImg.gif"
class="centerIcon"
v-else
/>
</div>
<div
class="descriptionImg"
v-else
>
未抓取到视频
</div>
</div>
css
.description-content {
width: 220px;
margin: 0 20px;
margin-top: 20px;
.imgurlExit {
position: relative;
height: 180px;
.centerIcon {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
color: #fff;
font-size: 40px;
}
}
.descriptionImg {
width: 220px;
height: 180px;
background: #000;
color: #fff;
font-weight: 800;
text-align: center;
line-height: 180px;
border-radius: 10px;
}
}
js
mpegts.js具体使用可移步 vue使用mpegts.js教程
import mpegts from "mpegts.js";
// 获取数据时进行判断 item.fileUrl存在且item.imgUrl不存在时。生成图片信息并返回更新数据
async getData() {
const res = await getList({});
if (res.success) {
this.objects = res.data; //objects 为data中定义的数据
this.$nextTick(() => {
this.objects.map((item) => {
if (item.fileUrl && !item.imgUrl) {
this.getImage(item.fileUrl).then((res) => {
item.imgUrl = res;
});
}
});
});
}
},
// 获取视频的图片
getImage(url) {
return new Promise((resolve, reject) => {
const extension = url.split("."); //获取类型
const videoElement = document.createElement("video");
videoElement.muted = true; // 静音
videoElement.autoplay = true; // 自动播放
if (mpegts.isSupported()) {
// mpegts 具体用法可移步首页教程
const flvPlayer = mpegts.createPlayer(
{
type: extension[extension.length - 1],
url,
isLive: true,
isAutoPlay: true,
isContinue: true,
lazyLoad: true,
hasAudio: false,
},
{
enableWorker: true,
enableStashBuffer: false,
stashInitialSize: 128,
}
);
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load(); //加载
setTimeout(() => {
flvPlayer
.play()
.then(() => {
this.destory(flvPlayer);
})
.catch((err) => {
this.destory(flvPlayer);
console.log("err", err);
});
});
}
// 监听视频数据加载事件
videoElement.addEventListener("loadeddata", function () {
// 播放及暂停
const canvasElement = document.createElement("canvas");
const ctx = canvasElement.getContext("2d");
canvasElement.width = 220;
canvasElement.height = 180;
// 绘制当前帧到 canvas
if (ctx) {
ctx.drawImage(videoElement, 0, 0, canvasElement.width, canvasElement.height);
}
const imageDataUrl = canvasElement.toDataURL();
resolve(imageDataUrl);
videoElement.pause();
// 移除video元素 注 document.createElemet创建的元素需要挂载到具体的dom才可以进行删除
document.body.appendChild(videoElement);
document.body.appendChild(canvasElement);
document.body.removeChild(videoElement);
document.body.removeChild(canvasElement);
});
});
},
// 销毁 mpegts 对象
destory(player) {
if (player) {
try {
player.pause();
player.unload();
player.detachMediaElement();
player.destroy();
player = null;
} catch (e) {
// console.log(e);
}
}
},