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>
相关推荐
晓131334 分钟前
【Cocos Creator 3.x】篇——第一章 简介
前端·javascript·游戏引擎
ZC跨境爬虫1 小时前
跟着 MDN 学JavaScript day_10:数组——数据的有序集合
android·java·开发语言·前端·javascript
晓13131 小时前
【Cocos Creator 2.x】篇——第五章 游戏常用关键技术
前端·javascript·vue.js·游戏引擎
W_LuYi1852 小时前
Tauri + Rust + Vue 3 打造极速轻量桌面应用
java·开发语言·vue.js·rust
qq4356947012 小时前
Vue03
javascript·vue.js
樱花的浪漫2 小时前
Typescript、Zod基础
前端·javascript·人工智能·语言模型·自然语言处理·typescript
用户549591657502 小时前
TinyVue Tree树形控件完全指南
vue.js
竹林8182 小时前
监听智能合约事件,我用 wagmi v2 踩了三天坑,终于找到了稳定方案
前端·javascript
用户852495071842 小时前
Bun 到底是什么?一个比 Node.js "更快更香"的 JS 运行时
javascript·程序员