Vue3 视频播放与截图功能实现

视频播放

使用 HTML5<video> 标签实现,src 改成你自己的视频路径。

html 复制代码
<video
  ref="videoRef"
  class="video-element"
  src="@/assets/video/1.mp4"
  autoplay
  loop
  muted
></video>

video 标签基本属性

属性 说明
src 视频文件路径(支持相对/绝对路径)
autoplay 自动播放(部分浏览器需配合muted属性)
controls 显示默认播放控制条
width/height 设置视频显示尺寸
muted 静音播放
loop 循环播放
preload 预加载策略(auto/metadata/none)

视频截图功能实现

思路

  1. 视频帧捕获 :首先,通过 <video> 元素获取当前播放的视频帧画面,浏览器会将视频解码为连续的图像帧,我们可以通过 <video> 标签的API访问当前显示的帧。
  2. Canvas 绘制转换 :创建一个与视频尺寸相同的 Canvas 画布,使用 Canvas 2D 上下文(Context2D)的 drawImage() 方法将视频帧绘制到画布上。
  3. Base64 编码输出 :调用 CanvastoDataURL() 方法,将绘制好的图像数据转换为 Base64 编码的图片 URL。该方法支持指定输出格式(如 PNG/JPEG)和质量参数,转换后的数据可以直接用作图片源或下载保存。

代码实现

html 复制代码
<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>
javascript 复制代码
<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>
scss 复制代码
<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>
相关推荐
天若有情6731 小时前
程序员原创|借鉴JS事件冒泡,根治电脑文件混乱的“冒泡整理法”
开发语言·javascript·windows·ecmascript·电脑·办公·日常
FYKJ_20103 小时前
springboot校园兼职平台--附源码02041
java·javascript·spring boot·python·eclipse·django·php
用户6688599847667 小时前
Vue 3.0安装与使用
vue.js
空中海8 小时前
01 React Native 基础、核心组件与布局体系
javascript·react native·react.js
前端之虎陈随易10 小时前
2年没用Nodejs了,Bun很香
linux·前端·javascript·vue.js·typescript
好运的阿财11 小时前
OpenClaw工具拆解之host_workspace_write+host_workspace_edit
前端·javascript·人工智能·机器学习·ai编程·openclaw·openclaw工具
XiYang-DING11 小时前
JavaScript
开发语言·javascript·ecmascript
空中海12 小时前
02 React Native状态、导航、数据流与设备能力
javascript·react native·react.js
空中海13 小时前
02 状态、Hooks、副作用与数据流
开发语言·javascript·ecmascript
空中海13 小时前
04 React Native工程化、质量、发布与生态选型
javascript·react native·react.js