视频播放
使用 HTML5 的 <video> 标签实现,src 改成你自己的视频路径。
<video
ref="videoRef"
class="video-element"
src="@/assets/video/1.mp4"
autoplay
loop
muted
></video>
video 标签基本属性
视频截图功能实现
思路
1. 视频帧捕获:首先,通过 <video> 元素获取当前播放的视频帧画面,浏览器会将视频解码为连续的图像帧,我们可以通过 <video> 标签的API访问当前显示的帧。
2. Canvas 绘制转换:创建一个与视频尺寸相同的 Canvas 画布,使用 Canvas 2D 上下文(Condext2D)的 drawImage() 方法将视频帧绘制到画布上。
3. Base64 编码输出:调用 Canvas 的 toDataUrl() 方法,将绘制好的图像数据转换为 Base64 编码的图片URL 。该方法支持指定输出格式(如 PNG/JPEG)和质量参数,转换后的数据可以直接用作图片源或下载保存。
代码实现
<template>
<div class="video-container">
<!-- 视频播放器 -->
<div class="video-wrapper">
<video
ref="videoRef"
class="video-element"
src="@/assets/video/1.mp4"
autoplay
controls
></video>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from "vue";
import { ElMessage } from "element-plus";
const videoRef = ref(null);
const screenshotUrl = ref(""); // 截图后的图片URL
// 截图功能
const scanImage = () => {
if (!videoRef.value) return;
try {
// 创建canvas元素
const canvas = document.createElement("canvas");
const video = videoRef.value;
// 设置canvas尺寸与视频相同
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
// 绘制当前视频帧到canvas
const ctx = canvas.getContext("2d");
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
// 转换为DataURL
screenshotUrl.value = canvas.toDataURL("image/png");
ElMessage.success("截图成功!");
} catch (error) {
console.error("截图失败:", error);
ElMessage.error("截图失败: " + error.message);
}
};
// 快捷键支持 (F9截图)
const handleKeyDown = (e) => {
if (e.key === "F9") {
e.preventDefault();
scanImage();
}
};
// 添加事件监听
onMounted(() => {
window.addEventListener("keydown", handleKeyDown);
});
// 移除事件监听
onBeforeUnmount(() => {
window.removeEventListener("keydown", handleKeyDown);
});
</script>
<style lang="scss" scoped>
.video-container {
padding: 20px;
max-width: 800px;
margin: 0 auto;
}
.video-wrapper {
position: relative;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
background: #000;
}
.video-element {
width: 100%;
display: block;
}
.screenshot-controls {
position: absolute;
bottom: 20px;
right: 20px;
z-index: 10;
}
.screenshot-result {
display: flex;
justify-content: center;
align-items: center;
min-height: 300px;
}
.screenshot-image {
max-width: 100%;
border: 1px solid #ebeef5;
border-radius: 4px;
}
.empty-tip {
color: #909399;
font-size: 14px;
text-align: center;
padding: 20px;
}
</style>