如何利用纯前端技术,实现一个网页版视频编辑器?
纯网页版视频编辑器
- 一、前言
- 二、功能实现
- 三、所需技术
- 四、部分功能实现
- 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 技术,来实现 多轨道剪辑功能。
- 首先创建一个任务队列对象,来存储多轨道的数据,比如视频、音乐、文本等等素材轨道。
private ffmpeg: FFmpegprivate taskQueue = reactive<Task[]>([]) // 任务队列private running = ref(false) // 运行状态public showLog = truepublic playTimeCache = new Map()public audioCache: string[] = []public baseCommand = new Command()
- 然后我们可以对其创建任务,并判断任务队列中是否有执行任务的命令,如果有则返回任务存在,如果没有则返回 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}}
- 用户把素材资源从本地拖拽到页面内,需要获取到文件内容
// 获取文件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]})}
- 最重要最核心的音频合成功能:
// 音频合成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)}
- 获取视频每一帧
// 获取视频帧图片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,如果有需要的话,可以私戳后台,谢谢。
相关文章:
如何利用纯前端技术,实现一个网页版视频编辑器?
纯网页版视频编辑器 一、前言二、功能实现三、所需技术四、部分功能实现4.1 素材预设4.2 多轨道剪辑 一、前言 介绍:本篇文章打算利用纯前端的技术,来实现一个网页版的视频编辑器。为什么突然想做一个这么项目来呢,主要是最近一直在利用手机…...
stm32实现hid键盘
前面的cubelmx项目配置参考 stm32实现hid鼠标-CSDN博客https://blog.csdn.net/anlog/article/details/137814494?spm1001.2014.3001.5502两个项目的配置完全相同。 代码 引用 键盘代码: 替换hid设备描述符 先屏蔽鼠标设备描述符 替换为键盘设备描述符 修改宏定…...
【单例模式】饿汉式、懒汉式、静态内部类--简单例子
单例模式是⼀个单例类在任何情况下都只存在⼀个实例,构造⽅法必须是私有的、由⾃⼰创建⼀个静态变量存储实例,对外提供⼀个静态公有⽅法获取实例。 目录 一、单例模式 饿汉式 静态内部类 懒汉式 反射可以破坏单例 道高一尺魔高一丈 枚举 一、单例…...
windows关闭Windows Search功能
我发现windows最恶心的功能就是自动更新和搜索。自动更新就是个毒瘤,得到了全世界的人讨厌。 而搜索功能难用、慢和造成卡死,根本没有存在的必要。并且他的windows search filter服务会在每次移动大量文件后建立索引,持续的占用cpu和硬盘的资…...
政安晨:【深度学习神经网络基础】(九)—— 在深度学习神经网络反向传播训练中理解梯度
目录 简述 理解梯度 什么是梯度 计算梯度 政安晨的个人主页:政安晨 欢迎 👍点赞✍评论⭐收藏 收录专栏: 政安晨的机器学习笔记 希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在评论区提出指正! 简述 在深度…...
免费的 ChatGPT、GPTs、AI绘画(国内版)
🔥博客主页:白云如幻❤️感谢大家点赞👍收藏⭐评论✍️ ChatGPT3.5、GPT4.0、GPTs、AI绘画相信对大家应该不感到陌生吧?简单来说,GPT-4技术比之前的GPT-3.5相对来说更加智能,会根据用户的要求生成多种内容甚…...
UniApp 微信小程序:在 onLaunch 中等待异步方法执行完成后,再调用页面中的接口
最近遇到了一个问题:在 App.vue 中的 onLaunch 中调用登录接口时,由于异步登录尚未完成就调用了 index 页面的接口,导致 token 异常。如何确保页面在 App 中的 onLaunch 执行完毕后再继续执行呢? 在网上查阅了一些资料,…...
【招贤纳士】长期有效
【招贤纳士】长期有效,有意者联系 一、SLAM算法工程师工作内容:任职资格: 二、规划算法工程师工作内容:任职资格: 三、感知算法工程师岗位职责:任职要求:加分项: 四、传感器系统工程…...
华为配置静态ARP示例
华为配置静态ARP示例 组网图形 图1 配置静态ARP组网图 静态ARP简介配置注意事项组网需求配置思路操作步骤配置文件相关信息 静态ARP简介 静态ARP表项是指网络管理员手工建立IP地址和MAC地址之间固定的映射关系。 正常情况下网络中设备可以通过ARP协议进行ARP表项的动态学习&…...
LRTimelapse for Mac:专业延时摄影视频制作利器
LRTimelapse for Mac是一款专为Mac用户设计的延时摄影视频制作软件,它以其出色的性能和丰富的功能,成为摄影爱好者和专业摄影师的得力助手。 LRTimelapse for Mac v6.5.4中文激活版下载 这款软件提供了直观易用的界面,用户可以轻松上手&#…...
Java复习第十九天学习笔记(Cookie、Session登录),附有道云笔记链接
【有道云笔记】十九 4.7 Cookie、Session登录 https://note.youdao.com/s/VwpxfEim 一、会话技术简介 生活中会话 我: 小张,你会跳小苹果码? 小张: 会,怎么了? 我: 公司年会上要表演节目&a…...
HBase的数据模型与架构
官方文档:Apache HBase – Apache HBase™ Homehttps://hbase.apache.org/ 一、HBase概述 1.概述 HBase的技术源自Google的BigTable论文,HBase建立在Hadoop之上,是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,用于…...
卷积神经网络的结构组成与解释(详细介绍)
文章目录 前言 1、卷积层 2、激活层 3、BN层 4、池化层 5、FC层(全连接层) 6、损失层 7、Dropout层 8、优化器 9、学习率 10、卷积神经网络的常见结构 前言 卷积神经网络是以卷积层为主的深层网络结构,网络结构包括有卷积层、激活层、BN层、…...
使用ansible的连通性检查的关键参数
使用ansible进行ping命令的时候发现有些不通 ansible cba -m ping 10.1.1.1 | FAILED! > {"msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this h…...
Jenkins用maven风格build报错解决过程记录
1、Jenkins2.453新建项目,构建风格选的maven 2、自由风格构建部署没有任何问题,但是maven风格build一直失败,报错如下图 3、解决方案:在系统管理–系统配置–Maven项目配置,删除全局MAVEN_OPT的路径信息,…...
Web3.0与AI的交融:开启智能互联网新时代
目前有140 多个 Web3 AI 概念项目,覆盖了基础设施、数据、预测市场、计算与算力、教育、DeFi & 跨链、安全、NFT & 游戏 & 元宇宙、搜索引擎、社交 & 创作者经济、AI 聊天机器人、DID & 消息传递、治理、医疗、交易机器人等诸多方向。持续关注…...
自动化_Ansible学习笔记
文章目录 Ansible 介绍配置文件主配置文件优先级 常用命令ansible-playbook ad-hocinventory 主机清单Playbook 剧本YAML格式 ansible 模块介绍模块对应功能Commands modules(命令模块)command (命令)shell (外壳) 官方帮助文档 模块索引playbook 开头示例系统类setup (收集远程…...
用于密集视觉冲击的紧凑三维高斯散射Compact 3D Gaussian Splatting For Dense Visual SLAM
Compact 3D Gaussian Splatting For Dense Visual SLAM 用于密集视觉冲击的紧凑三维高斯散射 Tianchen Deng 邓天辰11Yaohui Chen 陈耀辉11Leyan Zhang 张乐妍11Jianfei Yang 杨健飞22Shenghai Yuan 圣海元22Danwei Wang 王丹伟22Weidong Chen 陈卫东11 Abstract 摘要 …...
ChatGPT揭秘:高效论文写作的秘籍
ChatGPT无限次数:点击直达 ChatGPT揭秘:高效论文写作的秘籍 引言 在当今信息爆炸的时代,高效撰写论文对于研究者和学术工作者至关重要。随着人工智能技术的不断发展,ChatGPT等自然语言处理工具的出现为论文写作提供了全新的思路和工具。本文…...
电脑不能上网,宽带调制解调器出现问题如何处理
目录 一、问题说明 二、解决方案 一、问题说明 内网的设备能互联,内网的各个设备无法连外网。 电脑在检测网络时,出现以下提示: 二、解决方案 首先重启光猫(我们是电信宽带)。 如果还是有问题,再重启…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
