如何利用纯前端技术,实现一个网页版视频编辑器?

纯网页版视频编辑器

  • 一、前言
  • 二、功能实现
  • 三、所需技术
  • 四、部分功能实现
    • 4.1 素材预设
    • 4.2 多轨道剪辑

一、前言

介绍:本篇文章打算利用纯前端的技术,来实现一个网页版的视频编辑器。为什么突然想做一个这么项目来呢,主要是最近一直在利用手机剪映来剪辑一些照片或者视频之类的,在剪辑的过程中,突然想到,有没有一种纯网页版的视频剪辑网站呢?于是搜了下,大多为 sass 成熟版(需要花钱的那种),然后再加上最近一直在看前端技术,于是就打算利用现学的前端技术,来实现一个纯前端的纯网页版的视频编辑器demo。

先给大家看下整体效果图:

在这里插入图片描述
tips:整体看上去像模像样的。

二、功能实现

这里就先简单列下具体的功能包括哪些:

  • 支持深色模式(白天/黑夜)

  • 支持云素材(暂为mock模拟)以及本地上传素材

  • 支持拖拽添加资源

  • 支持多轨道

  • 支持表单调整资源位置、属性

  • 支持音视频裁剪

  • 支持手动添加贴图、文字

  • 支持时间轴缩放(ctrl+滚轮),最多显示30帧

  • 支持播放预览

  • 支持导出

  • 支持操作撤销、重做功能

  • 支持持久化存储功能

三、所需技术

这里也先简单列下项目中具体用到的技术包括哪些:

  • axios(^1.4.0)
  • element-plus(^2.3.4)
  • mockjs (^1.1.0)
  • pinia (^2.1.3)
  • vue(^3.2.47)
  • typescript(^5.0.2)
  • vite(^4.3.2)

插件包括:

  • commitlint(^17.6.3)
  • ffmpeg(^0.11.6)核心插件
  • cross-env(^7.0.3)
  • eslint(^8.40.0)
  • husky(^8.0.3)
  • postcss(^8.4.23)
  • prettier(^2.8.8)
  • stylelint(^15.6.1)
  • types/node(^20.1.4)
  • element-plus(^2.1.0)

四、部分功能实现

4.1 素材预设

素材预设功能,我们这里是利用了 mock 技术,来代替后端传输的数据。

先利用mock 来模拟一些素材或者进行预设,比如:

const mockMethods: MockMethod[] = [{url: '/api/getResources',method: 'get',response: ({ query }) => {const type = query.typelet data: ResourcesList = []if (type === 'video') {data = [{title: '转场',type: 'video',items: [{name: '故障雪花屏.mp4',format: 'mp4',cover: '/image/video/故障雪花屏.jpg',source: '/video/故障雪花屏.mp4',width: 1920,height: 1080,fps: 30,frameCount: 30,time: 1000}]}]} else if (type === 'audio') {data = [{title: '旋律',type: 'audio',items: [{cover: '/image/audio/Charms.jpg',time: 244000,format: 'mp3',name: 'Charms.mp3',singer: 'Abel Korzeniowski',source: '/audio/Abel Korzeniowski - Charms.mp3'}]}]} else if (type === 'text') {data = [{title: '热门',type: 'text',items: [{name: 'CherryBombOne.ttf',templateId: 0,source: '/text/CherryBombOne-Regular.ttf',format: 'truetype'}}]} else if (type === 'image') {data = [{title: '热门',type: 'image',items: [{name: '666.gif',cover: '/image/image/666.gif',source: '/image/image/666.gif',format: 'gif',width: 199,height: 200,sourceFrame: 8}},{title: '经典',type: 'image',items: [{name: '喇叭.gif',cover: '/image/image/喇叭.gif',source: '/image/image/喇叭.gif',format: 'gif',width: 199,height: 200,sourceFrame: 6},{name: '马赛克.gif',cover: '/image/image/马赛克.gif',source: '/image/image/马赛克.gif',format: 'gif',width: 199,height: 200,sourceFrame: 6},{name: '马赛克小人.gif',cover: '/image/image/马赛克小人.gif',source: '/image/image/马赛克小人.gif',format: 'gif',width: 199,height: 200,sourceFrame: 6},{name: '闪光.gif',cover: '/image/image/闪光.gif',source: '/image/image/闪光.gif',format: 'gif',width: 199,height: 200,sourceFrame: 6}]}return {code: 200,data}}}
]export default mockMethods

代码写完后,不要忘记把素材也要放到项目文件夹里

在这里插入图片描述

4.2 多轨道剪辑

什么是多轨道剪辑?

多轨道编辑即是将不同的素材放置在不同的轨道上,通过调整它们在时间线上的位置和长度,达到叠加、剪辑和混合的效果。 我们可以通过拖拽素材到时间线上的不同轨道来进行多轨道编辑。

通常情况下,视频素材放置在视频轨道上,音频素材放置在音频轨道上。这样,我们可以通过调整素材在时间线上的位置和长度来控制视频和音频的播放顺序、时长和重叠关系

从技术角度来实现的话,这里就通过用 ffmpeg 技术,来实现 多轨道剪辑功能。

  1. 首先创建一个任务队列对象,来存储多轨道的数据,比如视频、音乐、文本等等素材轨道。
  private ffmpeg: FFmpegprivate taskQueue = reactive<Task[]>([]) // 任务队列private running = ref(false) // 运行状态public showLog = truepublic playTimeCache = new Map()public audioCache: string[] = []public baseCommand = new Command()
  1. 然后我们可以对其创建任务,并判断任务队列中是否有执行任务的命令,如果有则返回任务存在,如果没有则返回 undefined。
 createTask(commands: string[]) {const task = this.existTask(commands)if (task) {return task.instance} else {const callbacks = {}const instance = new Promise((resolve, reject) => {Object.assign(callbacks, {resolve,reject})})this.taskQueue.push({instance,commands,...callbacks} as Task)return instance}}
  1. 用户把素材资源从本地拖拽到页面内,需要获取到文件内容
 // 获取文件BlobgetFileBlob(filePath: string, fileName: string, format: string) {const fileBuffer = this.getFileBuffer(filePath, fileName, format)return new Blob([fileBuffer], {type: FileTypeMap[format as keyof typeof FileTypeMap]})}
  1. 最重要最核心的音频合成功能:
// 音频合成async mergeAudio(start: number,itemList: TrackItem[],fileName: string,filePath: string) {const { commands } = this.baseCommand.mergeAudio(this.pathConfig,start,itemList)if (this.audioCache.indexOf(commands.join('')) > -1) return falsethis.audioCache = [commands.join('')]if (this.fileExist(filePath, fileName)) this.rmFile(filePath)return this.createTask(commands)}
  1. 获取视频每一帧
 // 获取视频帧图片getFrame(videoName: string, frameIndex: number) {const framePath = `${this.pathConfig.framePath}${videoName}`const fileName = `/pic-${frameIndex}`// return this.getFileBlob(framePath, fileName, 'jpg')return this.getFileBuffer(framePath, fileName, 'jpg')}

目前只是一个简易的demo,如果有需要的话,可以私戳后台,谢谢。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/821631.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenCV基本图像处理操作(四)——傅立叶变换

傅里叶变换的作用 高频&#xff1a;变化剧烈的灰度分量&#xff0c;例如边界 低频&#xff1a;变化缓慢的灰度分量&#xff0c;例如一片大海 滤波 低通滤波器&#xff1a;只保留低频&#xff0c;会使得图像模糊 高通滤波器&#xff1a;只保留高频&#xff0c;会使得图像细节…

Golang | Leetcode Golang题解之第31题下一个排列

题目&#xff1a; 题解&#xff1a; func nextPermutation(nums []int) {n : len(nums)i : n - 2for i > 0 && nums[i] > nums[i1] {i--}if i > 0 {j : n - 1for j > 0 && nums[i] > nums[j] {j--}nums[i], nums[j] nums[j], nums[i]}reverse…

【架构-15】NoSQL数据库

NoSQL&#xff08;Not Only SQL&#xff09;数据库是一类非关系型数据库&#xff0c;与传统的关系型数据库&#xff08;如MySQL、Oracle&#xff09;相对而言。NoSQL数据库的设计目标是针对大规模数据和高并发访问的需求&#xff0c;具有高可扩展性、高性能和灵活的数据模型。 …

Day 14 网络协议

常见网络设备&#xff1a;交换机 路由器 中继器 多协议网关&#xff08;路由器的前身&#xff09; 交换机&#xff1a;用于连接统一网络的设备&#xff0c;实现内网设备通信。 从广义上分为&#xff1a;局域网交换机&#xff0c;广域网交换机 从网络构成分为&#xff1a;接…

Jenkins配置windows/linux从节点

背景&#xff1a; 环境&#xff1a;jenkins环境&#xff08;Ubuntu&#xff09; 节点机器&#xff1a;Linux、Windows 前置条件&#xff1a; 节点机器&#xff1a;安装java、allure、python 1 Linux节点管理机器添加 1.1 系统管理->节点列表->New Node 1.2 节点配置…

【MySQL】MySQL锁(二)表锁与行锁测试

MySQL锁&#xff08;二&#xff09;表锁与行锁测试 上篇文章我们简单的了解了一大堆锁相关的概念&#xff0c;然后只是简单的演示了一下 InnoDB 和 MyISAM 之间 表锁 与 行锁 的差别。相信大家还是意犹未尽的&#xff0c;今天我们就来用代码说话&#xff0c;实际地操作一下&…

ES链接报connection reset by peer

这里写自定义目录标题 ES链接报connection reset by peer解决方法主要是删除node.lock文件重启es服务问题解决 ES链接报connection reset by peer 问题描述服务端报错connection reset by peer 在服务器上去curl返回的也是connection reset by peer 链接重置&#xff0c;说明e…

「GO基础」文件名规范、关键字与标识符

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

一键升级 package.json 下所有依赖的版本

命令&#xff1a; npx npm-check-updates -u这个命令会生成一个新的package.json文件&#xff0c;其中包含了所有依赖项的最新版本。然后&#xff0c;你可以运行npm install来安装这些更新后的依赖项。 请注意&#xff0c;在更新依赖项之前&#xff0c;最好备份你的项目&…

元数据管理Atlas

文章目录 一、Atlas概述1、Atlas入门2、Atlas架构原理 二、Atlas安装1、安装环境准备1.1 安装Solr-7.7.31.2 Atlas2.1.0安装 2、Atlas配置2.1 Atlas集成Hbase2.2 Atlas集成Solr2.3 Atlas集成Kafka2.4 Atlas Server配置2.5 Kerberos相关配置2.6 Atlas集成Hive 3、Atlas启动 三、…

ARM的学习

键控灯 mykey.h #ifndef __MYKEY_H__ #define __MYKEY_H__ #include "stm32mp1xx_gpio.h" #include "stm32mp1xx_gic.h" #include "stm32mp1xx_rcc.h" #include "stm32mp1xx_exti.h" void key1_int_config(); void key2_int_config(…

用海外云手机高效率运营TikTok!

很多做国外社媒运营的公司&#xff0c;想要快速引流&#xff0c;往往一个账号是不够的&#xff0c;多数都是矩阵养号的方式&#xff0c;运营多个TikToK、Facebook、Instagram等账号&#xff0c;慢慢沉淀流量变现&#xff0c;而他们都在用海外云手机这款工具&#xff01; 海外云…

使用EasyExcel和POI操作Excel实现文件上传和下载

使用easyExcel实现文件读写 实现流程 1.导入依赖 2.定义数据模型 3.定义监听器 4.读取或写入数据 5.释放资源 实现 导入依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.3</…

知识管理系统(KMS):一文扫盲,能和chatGPT相融吗?

一、什么是KMS&#xff0c;有什么作用 KMS&#xff08;Knowledge Management System&#xff09;知识管理系统是一种用于组织、存储、共享和利用知识的软件系统或平台。它旨在帮助组织有效地管理和利用内部和外部的知识资源&#xff0c;以支持决策、创新和持续学习。 KMS知识管…

华为云CodeArts IDE For Python 快速使用指南

CodeArts IDE 带有 Python 扩展&#xff0c;为 Python 语言提供了广泛的支持。Python 扩展可以利用 CodeArts IDE 的代码补全、验证、调试和单元测试等特性&#xff0c;与多种 Python 解释器协同工作&#xff0c;轻松切换包括虚拟环境和 conda 环境的 Python 环境。本文简要概述…

数据治理——元数据管理实施步骤

一、元数据管理概述 1.1 数据管理面临的问题 数据治理的概念是对数据数据管理的管理&#xff0c;在数据管理的过程中遇到的问题有&#xff1a; 1.1.1 数据不可理解 海量数据&#xff0c;标准不统一&#xff0c;各系统、各部门对统一指标和概念的解释不一致&#xff0c;统计口…

python机器学习库中Scikit-learn和TensorFlow如何选择?

在Python机器学习库中&#xff0c;Scikit-learn和TensorFlow是两个非常流行的选择&#xff0c;但它们各自有不同的特点和适用场景。以下是根据搜索结果的一些考虑因素&#xff0c;帮助你做出选择&#xff1a; 1. 项目需求&#xff1a; 如果你的项目主要涉及传统的机器学习算…

OpenCV基本图像处理操作(三)——图像轮廓

轮廓 cv2.findContours(img,mode,method) mode:轮廓检索模式 RETR_EXTERNAL &#xff1a;只检索最外面的轮廓&#xff1b;RETR_LIST&#xff1a;检索所有的轮廓&#xff0c;并将其保存到一条链表当中&#xff1b;RETR_CCOMP&#xff1a;检索所有的轮廓&#xff0c;并将他们组…

魔方网表 存在 mailupdate.jsp接口 任意文件上传漏洞

声明&#xff1a; 本文仅用于技术交流&#xff0c;请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任。 简介 魔方网表mailupdate.jsp接口存在任意文件上传漏洞 …

数据仓库—维度建模—事实表设计

事实表 事实表是数据仓库中的核心表,用于记录与业务过程相关的事实信息,是进行数据分析和挖掘的主要数据来源。 在ER模型中抽象出了有实体、关系、属性三种类别,在现实世界中,每一个操作型事件,基本都是发生在实体之间的,伴随着这种操作事件的发生,会产生可度量的值,…