跨服战场

【前端】Vue3 获取视频首帧和时长

导读: 最近在做前端工作项目中做了一个功能,要求可以从本地选取或拖拽视频文件,校验是否是 mp4 文件,并执行相关上传操作。

由于还是前端小白,此处动动手指,敲敲键盘,记录一下~

效果图

实现思路

该功能依托的环境是 Vue 3.4.21、Element Plus 2.5.6、Pinia 2.0.32;

此处的弹框是借助了 Element Plus 的 el-dialog 小组件;

此处的从本地选择文件和拖拽文件功能是借助了 Element Plus 的 el-upload 小组件;

当选择完文件会进行一波文件的基础信息校验,只有当文件符合规则再添加到对应的数组中去;

紧接着在每个文件 item 的 onMounted 生命周期钩子函数中去处理本地视频的相关信息;

通过手动创建 video 视频标签元素,播放视频文件:

如果可以播放 oncanplay 方法有回调,即代表视频可以播放,进而通过 canvas 绘制首帧图片;

即使可以播放,实际上也要进行筛选,因为音频文件通过 video 标签实际上也是可以播放的,只不过没有视频轨道而已,所以就需要进行过滤;

如果不可以播放,则在 onerror 方法中会有对应回调信息,代表当前文件不支持播放。

在 oncanplay 方法回调中可以通过 video.duration 获取视频时长;

通过 canvas 的绘制获取首帧图片。

实现代码(核心代码)

vue

复制代码

实现代码(完整)

上传弹框界面

vue

复制代码

// UploadDialog.vue ------------------

上传弹框单个文件 Item

vue

复制代码

// UploadItem.vue -------------

数据状态管理 Pinia

vue

复制代码

// src/stores/index.ts -----------

import { createPinia } from 'pinia'

const store = createPinia()

export default store

vue

复制代码

// src/stores/modules/upload.ts ---------

import { defineStore } from 'pinia'

import { uploadImage, upload } from '@/utils/sup-new'

import { $message } from '@/utils/message'

export const useUploadStore = defineStore('upload', {

state: (): UploadState => {

return {

preUploadList: [],

uploadList: [],

}

},

getters: {},

actions: {

// 判断一个文件名称是否包含指定特殊字符

handleIsValidFileName(name: string): boolean {

// 匹配规则:以.mp4结尾,且字符串只包含数字、中文、字母、-、_、(、)、(、)

const pattern = /^[\u4e00-\u9fa5\w\d\-_()()]*\.mp4$/

return pattern.test(name)

},

// 获取视频文件尺寸信息

handleGetFileSize(size: number, isUnit = false) {

const KB = 1024

const MB = 1024 * 1024

const GB = 1024 * 1024 * 1024

if (!size) return '0'

if (size < MB) return (size / KB).toFixed(1) + (isUnit ? 'KB' : '')

if (size < GB) return (size / MB).toFixed(1) + (isUnit ? 'MB' : '')

return (size / GB).toFixed(1) + (isUnit ? 'G' : '')

},

// 上传图片文件

handleUploadImageFile(file: VideoItem, duration: number) {

uploadImage(file, (res) => {

...

})

},

// 取消上传

handleCancelVideoFiles(files: VideoItem[]) {

if (files.length < 1) return

files.forEach((item) => {

if (item.uploadInfo && item.uploadInfo.source) {

item.uploadInfo.source.cancel()

item.uploadInfo.source = null

}

})

},

// 上传视频文件

handleUploadVideFiles(files: VideoItem[]) {

if (files.length < 1) return

if (!this.isHaveInValidFiles) return

...

},

}

})

参考链接

Vue 官网

Pinia 官网

Element Plus 官网

el-dialog

el-upload

W3school 官网

HTM - video 标签

HTML - canvas 绘图

版权声明

原文作者 :苜蓿鬼仙(苜蓿、jijiucheng)

原文链接 :GitHub.io - 苜蓿鬼仙 - 【前端】Vue3 获取视频首帧和时长

发表日期:2024/04/19 23:00:00

更新日期:2024/04/19 23:00:00

GitHub :GitHub - jijiucheng

个人博客 :GitHub.io - 苜蓿鬼仙

小专栏 :小专栏 - 苜蓿鬼仙

掘金 :掘金 - 苜蓿鬼仙

微博 :微博 - 苜蓿鬼仙

公众号 :[微信 - 苜蓿小站](#微信 - 苜蓿小站 "#")

小程序 :[微信 - 苜蓿小站](#微信 - 苜蓿小站 "#")