Vue 视频截取第一帧图片-组件

  • Post author:
  • Post category:vue




Video to Image

关于vue下视频截取第一帧网上方法众多, 我这边总结了一下并且归纳成组件, 希望对为此困扰的你提供一些帮助, 仅需要做一点点的修改页,本文内的代码可以复制后直接使用 !



开发前准备


  1. 确定为vue环境且不是Vue 1;
  2. 本组件附带了转成图片后的上传功能, 确定您安装了axios, 若不需要, 可以返回图片的file或blob



开始使用

我是把组件代码存放在

@/components/videoToImg

当然您可以自行修改

在需要此功能的使用的vue文件内写入以下



引入

import videotoimg from '@/components/videoToImg'



载入组件

components: {
    videotoimg
},



使用

<videotoimg :fileObj="fileObj" @uploadSuccess='onSuccess'></videotoimg>
// 对应数据
> data:
fileObj = {
   src: blob:http://192.168.3.15:9528/c1df8e08-039b-4da8-a653-4b93f3747d36, // 选取的视频文件
   videoW: number, // 视频宽度 单位为px
   videoH: number, // 视频高度 单位为px
};
// 这里是视频上传成功后返回给你的参数
> methods:
onSuccess: url => { url = { imgUrl: "/upload/image/20201124/1331153160697417728.jpg" }}



组件文件

这里我将文件命名为

@/components/videoToImg/index.vue

<template>
  <div  style="height: 1px; overflow:hidden; opacity: 0">
    <div id="videoArea"></div>
    <img :src="imgSrc" />
    <div>
      <div @click="cutPicture">截图 {{ videoW }}</div>
    </div>
    <canvas
      id="myCanvas"
      :width="videoW + 'px'"
      :height="videoH + 'px'"
    ></canvas>
  </div>
</template>

<script>
import { getRequestHeader } from "@/utils/auth"; // 这里是获取我自己的请求头 可以忽略 或者删除
import axios from "axios";
export default {
  props: {
    fileObj: {
      type: Object,
      default: {},
      require: true,
    },
  },
  name: "videotoimg",
  watch: {
    fileObj: {
      handler(newVal, oldVal) {
        console.log(newVal, oldVal);
        this.onClean();
        this.videoW = newVal.videoW;
        this.videoH = newVal.videoH;
        this.cutPicture();
      },
    },
  },
  data() {
    return {
      imgSrc: "",
      videoW: "",
      videoH: "",
      headers: getRequestHeader(),
      uploadUrl: process.env.BASE_API + "v1/general/resource/upload_video", // 截取后上传的地址
    };
  },
  methods: {
    onClean() {
      this.imgSrc = "";
      this.videoW = "";
      this.videoH = "";
    },
    cutPicture() {
      let area = document.querySelector("#videoArea");

      area.innerHTML = `
        <video src="${this.fileObj.src}" controls style="width: ${this.videoW}px"></video>
      `;

      const that = this;
      setTimeout(() => {
        var v = document.querySelector("video");
        let canvas = document.getElementById("myCanvas");
        var ctx = canvas.getContext("2d");
        ctx.drawImage(v, 0, 0, this.videoW, this.videoH);
        var oGrayImg = canvas.toDataURL("image/jpeg");
        that.imgSrc = oGrayImg;

        var arr = oGrayImg.split(","),
          mime = arr[0].match(/:(.*?);/)[1],
          bstr = atob(arr[1]),
          n = bstr.length,
          u8arr = new Uint8Array(n);
        while (n--) {
          u8arr[n] = bstr.charCodeAt(n);
        }
        var file = new File([u8arr], "videoimg.jpg", { type: mime });
        console.info(file); // 注意: 如果你不需上传,这里就可以拿到图片的ile了
        that.update(file); 
      }, 1000);
    },
    update(file) {
      // 上传照片
      // 这里很简单 就是上传的逻辑 根据自己需要进行修改
      let self = this;
      let param = new FormData();
      param.append("resourceFile", file); 
      let config = {
        headers: { "Content-Type": "multipart/form-data", ...self.headers },
      }; // 添加请求头
      axios.post(self.uploadUrl, param, config).then((res) => {
        if (res.data.code === 200) {
          self.$emit("uploadSuccess", { imgUrl: res.data.data }); // 回传数据!
        }
      });
    },
  },
};
</script>



写在最后

首先感谢你认真看完了这篇文章!

如果使用过程中有疑问可以随时来问, 一般看到我这边都会尽快回复的, 之前从上家公司个跳槽了, 最近在新公司比较忙. 之发前的无感打印我还是会定期维护, 感谢大家关注~~



版权声明:本文为gpj065原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。