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

纯网页版视频编辑器

  • 一、前言
  • 二、功能实现
  • 三、所需技术
  • 四、部分功能实现
    • 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.hqwc.cn/news/624666.html

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

相关文章

ssm 体检预约管理系统开发mysql数据库web结构java编程计算机网页源码eclipse项目

一、源码特点 ssm 体检预约管理系统是一套完善的信息系统&#xff0c;结合springMVC框架完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&#xff0c; 系统主要采用B/S…

快速删除node_modules依赖包的命令rimraf

1、安装rimraf npm install -g rimraf 2、使用命令删除node_modules rimraf node_modules *** window系统&#xff0c;使用命令很快就删除node_modules ***

RabbitMQ交换机的类型

交换机类型 可以看到&#xff0c;在订阅模型中&#xff0c;多了一个exchange角色&#xff0c;而且过程略有变化&#xff1a; Publisher&#xff1a;生产者&#xff0c;不再发送消息到队列中&#xff0c;而是发给交换机 Exchange&#xff1a;交换机&#xff0c;一方面&#xff…

JVM常见面试题

1. 什么是JVM JVM指的是Java虚拟机&#xff0c;本质上是一个运行在计算机上的程序&#xff0c;他的职责是运行Java字节码文件&#xff0c;作用是为了支持跨平台特性JVM的功能有三项&#xff1a;第一是解释执行字节码指令&#xff1b;第二是管理内存中对象的分配&#xff0c;完…

NetworkX、igraph、Gephi三大主流复杂网络建模与分析工具有什么区别?

★ 导言 ★ 本期给大家介绍NetworkX、igraph、Gephi三大主流复杂网络建模与分析工具的功能,并给出它们之间的区别与联系。 ★ 正文 ★ 正文开始之前,先附上三个工具的官方网址: NetworkX:https://networkx.org/ igraph:https://igraph.org/ Gephi:

eclipse中tomcat环境配置,2024年最新Web前端面试选择题

先自我介绍一下&#xff0c;小编浙江大学毕业&#xff0c;去过华为、字节跳动等大厂&#xff0c;目前阿里P7 深知大多数程序员&#xff0c;想要提升技能&#xff0c;往往是自己摸索成长&#xff0c;但自己不成体系的自学效果低效又漫长&#xff0c;而且极易碰到天花板技术停滞…

ChatGPT实用指南2024

随着ChatGPT技术的演进&#xff0c;越来越多的人开始在工作中利用此工具。以下是关于ChatGPT的实用指南&#xff0c;适合不太熟悉此技术的朋友参考。 一、ChatGPT概述 1. ChatGPT是什么&#xff1f; ChatGPT是基于OpenAI开发的GPT大型语言模型的智能对话工具。它能够通过自然语…

# RAG | Langchain # Langchain RAG:打造Markdown文件的结构化分割解决方案

【文章简介】 在信息技术的现代背景下&#xff0c;高效地处理和分析文本数据对于知识获取和决策支持至关重要。Markdown文件因其易读性和高效性&#xff0c;在文档编写和知识共享中占据了重要地位。然而&#xff0c;传统的文本处理方法往往忽视了Markdown的结构化特性&#xff…

Linux基础|线程池Part.1|线程池的定义和运行逻辑

线程池的定义和运行逻辑 多线程的问题&#xff1a; 如果并发的线程数量很多&#xff0c;并且每个线程都是执行一个时间很短的任务就结束了&#xff0c;这样频繁创建线程就会大大降低系统的效率&#xff0c;因为频繁创建线程和销毁线程需要时间。 那么一个很自然的想法就出现了…

Django中的实时通信:WebSockets与异步视图的结合【第167篇—实时通信】

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在现代Web应用程序中&#xff0c;实时通信已经成为了必不可少的功能之一。无论是在线聊天、…

vue快速入门(二十七)axios库的下载与使用

注释很详细&#xff0c;直接上代码 上一篇 新增内容 axios.js文件的下载与导入axios请求的使用与解析赋值 官网不科学上网太慢&#xff0c;csdn资源审核太慢&#xff0c;so我传自己主机了&#xff08;访问不了我&#xff09; axios.js文件 自己下载一下吧 源码 <!DOCTYPE h…