Js使用ffmpeg进行视频剪辑和画面截取
ffmpeg
使用场景是需要在web端进行视频的裁剪,包括使用 在线视频url
或 本地视频文件
的裁剪,以及对视频内容的截取等功能。
前端进行视频操作可能会导致性能下降,最好通过后端使用java,c++进行处理,本文的案例是备选方案。
注意:
以下所有的使用案例均基于vue3 setup。
同时由于@ffmpeg版本不同会导致使用的api不同,使用案例前需要注意@ffmpeg版本问题
。
如果使用的是0.12+需要使用新的api,详情请看 文档
npm
npm install @ffmpeg/ffmpeg@^0.10.0npm install @ffmpeg/core@^0.10.0
在线视频url剪辑
<script setup>
// "@ffmpeg/core": "^0.10.0",
// "@ffmpeg/ffmpeg": "^0.10.0",import { ref, onMounted, onUnmounted } from 'vue'
import { createFFmpeg, fetchFile } from '@ffmpeg/ffmpeg';const ffmpeg = createFFmpeg({ log: true });
const fileType = ref("") // 视频文件类型/*** 根据在线的视频地址截取片段* @param {String} url 在线视频链接* @param {Number|String} startTime 截取开始时间* @param {Number|String} endTime 截取结束时间* @param {Function} callBack 回调函数*/
const videoCut = async (url, startTime, endTime, callBack) => {if (!ffmpeg.isLoaded()) {await ffmpeg.load();}if(!url) return;fileType.value = url.split(".").pop()const inputName = `input.${fileType.value}`;const outputName = `output.${fileType.value}`;// 将输入文件保存到虚拟文件系统await ffmpeg.FS('writeFile', inputName, await fetchFile(url));// 运行 FFmpeg 命令try {await ffmpeg.run('-ss', `${startTime}`,'-t', `${endTime - startTime}`,'-i', inputName,'-vcodec', 'copy','-acodec', 'copy',outputName);// 读取输出文件let arrayBuffer = ffmpeg.FS('readFile', outputName).buffer; // 读取缓存// 创建下载链接并通过回调下载保存到本地const fileUrl = URL.createObjectURL(new Blob([arrayBuffer])); // 转为Blob URLcallBack && callBack(fileUrl)// 释放内存ffmpeg.FS('unlink', inputName);ffmpeg.FS('unlink', outputName);} catch (e) { }
}const downloadFile = (url, fileName = `clip.${fileType.value}`) => {const link = document.createElement('a');link.href = url;link.download = fileName;link.click();
}onMounted(() => {videoCut("https://视频.mp4", 0, 3, downloadFile)
})onUnmounted(() => {ffmpeg.exit();
})
</script>
本地视频文件剪辑
<template><input type="file" @change="fileChange">
</template><script setup>
import { ref, onUnmounted } from 'vue'
import { createFFmpeg, fetchFile } from '@ffmpeg/ffmpeg';const ffmpeg = createFFmpeg({ log: true });
const fileType = ref("") // 视频文件类型const fileChange = (e) => {if (!e.target.files[0]) return;const file = e.target.files[0];fileType.value = file.name.split(".").pop()videoCut(file, 0, 3, downloadFile)
}/*** 根据选择的视频文件截取片段* @param {File} file 选择的视频文件* @param {Number|String} startTime 截取开始时间* @param {Number|String} endTime 截取结束时间* @param {Function} callBack 回调函数*/
const videoCut = async (file, startTime, endTime, callBack) => {if (!ffmpeg.isLoaded()) {await ffmpeg.load();}if(!file) return;const inputName = `input.${fileType.value}`;const outputName = `output.${fileType.value}`;const orgFileBuffer = await file.arrayBuffer()// 将输入文件保存到虚拟文件系统await ffmpeg.FS('writeFile', inputName, await fetchFile(new Blob([orgFileBuffer])));try {await ffmpeg.run('-ss', `${startTime}`,'-t', `${endTime - startTime}`,'-i', inputName,'-vcodec', 'copy','-acodec', 'copy',outputName);// 读取输出文件let arrayBuffer = ffmpeg.FS('readFile', outputName).buffer; // 读取缓存// 创建下载链接并通过回调下载保存到本地const fileUrl = URL.createObjectURL(new Blob([arrayBuffer])); // 转为Blob URLcallBack && callBack(fileUrl)// 释放内存ffmpeg.FS('unlink', inputName);ffmpeg.FS('unlink', outputName);} catch (e) {}
}const downloadFile = (url, fileName = `clip.${fileType.value}`) => {const link = document.createElement('a');link.href = url;link.download = fileName;link.click();
}onUnmounted(() => {ffmpeg.exit();
})
</script>
获取视频画面截图
<template><input type="file" @change="fileChange">
</template><script setup>
import { ref, onUnmounted } from 'vue'
import { createFFmpeg, fetchFile } from '@ffmpeg/ffmpeg';const ffmpeg = createFFmpeg({ log: true });
const fileType = ref("") // 视频文件类型const fileChange = (e) => {if (!e.target.files[0]) return;const file = e.target.files[0];fileType.value = file.name.split(".").pop()// 由于这里一秒截取一帧 ,截取5次, 所以如果视频不足5秒会导致截取和读取失败// 回调中是base64图片组成的数组,需要在前面拼接 "data:image/png;base64," ,然后在img的src中赋值即可videoFrame(file, 5, 1, (data) => console.log(data))
}/*** 根据选择的视频文件获取视频截图* @param {File} file 选择的视频文件* @param {Number|String} count 截取图片的次数* @param {Number|String} interval 截取图片的间隔* @param {Function} callBack 回调*/
const videoFrame = async (file, count, interval, callBack) => {if (!ffmpeg.isLoaded()) {await ffmpeg.load();}if(!file) return;const inputName = `input.${fileType.value}`;const orgFileBuffer = await file.arrayBuffer()// 将输入文件保存到虚拟文件系统await ffmpeg.FS('writeFile', inputName, await fetchFile(new Blob([orgFileBuffer])));try {await ffmpeg.run("-i",inputName,"-r",`${interval}`,"-ss","0","-vframes",`${count}`,"-f","image2","-s","88*50","image-%02d.png");const baseArr = []for (let i = 0; i < count; i++) {let temp = i + 1;if (temp < 10) {temp = "0" + temp;}baseArr.push(arrayBufferToBase64(ffmpeg.FS("readFile", "image-" + temp + ".png")));}callBack && callBack(baseArr)// 释放内存ffmpeg.FS('unlink', inputName);} catch (e) {}
}const arrayBufferToBase64 = (array) => {array = new Uint8Array(array);var length = array.byteLength;var table = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'];var base64Str = "";for (var i = 0; length - i >= 3; i += 3) {var num1 = array[i];var num2 = array[i + 1];var num3 = array[i + 2];base64Str +=table[num1 >>> 2] +table[((num1 & 0b11) << 4) | (num2 >>> 4)] +table[((num2 & 0b1111) << 2) | (num3 >>> 6)] +table[num3 & 0b111111];}var lastByte = length - i;if (lastByte === 1) {var lastNum1 = array[i];base64Str +=table[lastNum1 >>> 2] + table[(lastNum1 & 0b11) << 4] + "==";} else if (lastByte === 2) {// eslint-disable-next-line no-redeclarevar lastNum1 = array[i];var lastNum2 = array[i + 1];base64Str +=table[lastNum1 >>> 2] +table[((lastNum1 & 0b11) << 4) | (lastNum2 >>> 4)] +table[(lastNum2 & 0b1111) << 2] +"=";}return base64Str
}onUnmounted(() => {ffmpeg.exit();
})
</script>
相关文章:
![](https://www.ngui.cc/images/no-images.jpg)
Js使用ffmpeg进行视频剪辑和画面截取
ffmpeg 使用场景是需要在web端进行视频的裁剪,包括使用 在线视频url 或 本地视频文件 的裁剪,以及对视频内容的截取等功能。 前端进行视频操作可能会导致性能下降,最好通过后端使用java,c进行处理,本文的案例是备选方…...
![](https://www.ngui.cc/images/no-images.jpg)
Linux基本命令,基础知识
进到当前用户目录:cd ~ 回到上级目录:cd .. 查看当前目录层级:pwd 创建目录:mkdir mkdir ruanjian4/linux/zqm41 -p级联创建文件夹(同时创建多个文件夹需要加-p) 查看详细信息:ls -l (即 ll) 查看所有详细信息:ls -al 隐藏文件是以.开头的 查看:l…...
![](https://img-blog.csdnimg.cn/c4419d29224a4a5d89d5d67e2cc7adee.png)
【Android知识笔记】进程通信(三)
在上一篇探索Binder通信原理时,提到了内存映射的概念,其核心是通过mmap函数,将一块 Linux 内核缓存区映射到一块物理内存(匿名文件),这块物理内存其实是作为Binder开辟的数据接收缓存区。这里有两个概念,需要理解清楚,那就是操作系统中的虚拟内存和物理内存,理解了这两…...
![](https://img-blog.csdnimg.cn/f9ac09c83c204c879e780adfb5fe8e42.jpeg)
云上亚运:所使用的高新技术,你知道吗?
作者简介:一名云计算网络运维人员、每天分享网络与运维的技术与干货。 公众号:网络豆云计算学堂 座右铭:低头赶路,敬事如仪 个人主页: 网络豆的主页 目录 前言 一.什么是云上亚运会 二.为什么要使用云…...
![](https://www.ngui.cc/images/no-images.jpg)
数据结构简述,时间、空间复杂度,学习网站推荐
目录 IT 学习路线 相关坚韧大厚书 相关有趣/耐看书或视频 数据结构与算法学习网站推荐 刷题 时间、空间复杂度 数据结构简述 基本概念 数据结构与算法简述和CS综述整理。本文非基础的教程,本文会列出大量学习和参考网站。老惯例,一个文章是一个集…...
![](https://img-blog.csdnimg.cn/64d16f8ab2d0479487db576704bcf802.png)
在线安装qt5.15之后任意版本
下载qt现在安装包: window安装包链接 进入cmd,用命令行打开安装包,并指定组件下载地址(这个是关键,之前用的是腾讯镜像,出现了版本灰色无法选中问题) .\qt-unified-windows-x64-4.6.1-online…...
![](https://img-blog.csdnimg.cn/97da92f9982b488480f143ec5ec36e28.png)
【kafka实战】01 3分钟在Linux上安装kafka
本节采用docker安装Kafka。采用的是bitnami的镜像。Bitnami是一个提供各种流行应用的Docker镜像和软件包的公司。采用docker的方式3分钟就可以把我们想安装的程序运行起来,不得不说真的很方便啊,好了,开搞。使用前提:Linux虚拟机&…...
![](https://www.ngui.cc/images/no-images.jpg)
yum安装mysql8
记录一下安装过程用于后面项目参考 目录 说明安装步骤yum安装默认目录修改默认的数据目录必要的my.cnf属性修改卸载Mysql 说明 一般情况下都是docker安装,部分特殊情况下,例如老外的项目部分禁用docker,那一般二进制安装或者yum直接安装。 …...
![](https://www.ngui.cc/images/no-images.jpg)
十五)Stable Diffusion使用教程:另一个线稿出3D例子
案例:黄金首饰出图 1)线稿,可以进行色阶加深,不易丢失细节; 2)文生图,精确材质、光泽、工艺(抛光、拉丝等)、形状(包括深度等,比如镂空)和渲染方式(3D、素描、线稿等)提示词,负面提示词; 3)seed调-1,让ai随机出图; 4)开启controlnet,上传线稿图,选择cann…...
![](https://www.ngui.cc/images/no-images.jpg)
2023icpc网络预选赛I. Pa?sWorD(dp)
题目给定字符串长度n以及字符串s 其中出现小写字母可以代表小写字母和大写字母 比如a可以代表a和A 出现?可以代表26个小写字母和26个大写字母和10个数字 出现大写字母和数字就是原本的数 同时要求大写字母,小写字母,数字一定都存在替换完的字符串中…...
![](https://img-blog.csdnimg.cn/17483394b4564f0281567dffe3cc065f.png#pic_center)
maven本地安装jar包
在实际开发中,有些jar包不能通过公共库下载,只能本地安装。可以按照以下步骤操作: 1、安装命令 mvn install:install-file -DgroupIdcom.chinacreator.sm -DartifactIdfbm-sm-common -Dversion0.0.1 -Dpackagingjar -Dfile../newJar/fbm-sm…...
![](https://www.ngui.cc/images/no-images.jpg)
QT中的inherits
目录 简介: 实例: 简介: 在Qt中,可以使用inherits函数来判断一个对象是否属于某个类或其派生类。inherits函数是QObject类的成员函数,因此只能用于继承自QObject的类的对象。 以下是inherits函数的一般用法…...
![](https://img-blog.csdnimg.cn/70a775d4b47446f3af099f4c2d344f1a.png)
全国职业技能大赛云计算--高职组赛题卷①(容器云)
全国职业技能大赛云计算--高职组赛题卷①(容器云) 第二场次题目:容器云平台部署与运维任务1 Docker CE及私有仓库安装任务(5分)任务2 基于容器的web应用系统部署任务(15分)任务3 基于容器的持续…...
![](https://img-blog.csdnimg.cn/06e5055b4aa247b4a50cf640eddb734a.png)
基于springboot+vue的入校申报审批系统
博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容:毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…...
![](https://img-blog.csdnimg.cn/0753a5bcc2924a0fb0398e6337c5a387.jpeg)
安卓逆向 - EdXposed LSPosed VirtualXposed
一、引言 接上篇:安卓逆向 - Xposed入门教程_小馒头yy的博客-CSDN博客 我们介绍了Xposed入门安装使用,但是只支持到Android 8,并且安装模块需要重启。今天我们来看看Xposed的其他版本。 二、各种Xposed框架对比 1、Xposed 只支持到安卓8&…...
![](https://img-blog.csdnimg.cn/c35fcf25899f4d1bba3ed5388bb07722.png)
Linux三大搜索指令的区别
find:可以在指定的路径下进行文件的搜索 —— 真的在磁盘文件中查找 例如find /usr/bin/ -name ls which 可以在指令路径下,/usr/bin,搜索指令文件 例如:which ls whereis:在系统特定的路径下查找,既可以找到可执行程序ÿ…...
![](https://img-blog.csdnimg.cn/fa1dd3eb2b3840c690facfaa2e1ef6d6.png)
C++ -- 特殊类设计
目录 设计一个类,不能被拷贝 C98的做法 C11的做法 设计一个类,只能在堆上创建对象 实现方式1 实现方式2 设计一个类,只能在栈上创建对象 实现方式1 方式1的优化 实现方式2 设计一个类,不能被继承 设计模式 什么是设计…...
![](https://img-blog.csdnimg.cn/5cf9efcf177d41de9f5b72a141c0fc3d.jpeg)
指针和数组笔试题的透析
指针---进阶篇(三) 一、前言二、一维数组例题透析:三、指针笔试题1.例一:2.例二:3.例三:4.例四:5.例五:6.例六: 一、前言 那么好了好了,宝子们,从…...
![](https://img-blog.csdnimg.cn/c43225a23880429286d0da2e846e8274.gif#pic_center)
「UG/NX」Block UI 超级点SuperPoint
✨博客主页何曾参静谧的博客📌文章专栏「UG/NX」BlockUI集合📚全部专栏「UG/NX」NX二次开发「UG/NX」BlockUI集合「VS」Visual Studio「QT」QT5程序设计「C/C+&#...
![](https://www.ngui.cc/images/no-images.jpg)
Linux——kafka常用命令
一、Kafka的常用命令包括: 1. 启动Zookeeper服务 前台启动: ./bin/zookeeper-server-start.sh config/zookeeper.properties 后台启动: ./bin/zookeeper-server-start.sh -daemon config/zookeeper.properties 2. 停止Zookeeper服务 .…...
![](https://img-blog.csdnimg.cn/img_convert/7662998e1b2db3053ce703c00ec8fa0d.gif)
GLTF编辑器如何快速重置模型原点
1、什么是模型原点? 模型原点是三维建模中的概念,它是指在一个虚拟三维空间中确定的参考点。模型原点通常位于模型的几何中心或基本组件的中心位置。如图所示: 可以看到模型的原点在模型的几何中心 2、模型原点的作用 知道了什么是模型原点&…...
![](https://img-blog.csdnimg.cn/db2aaf039c194ff69b47779c0cdd49ad.png)
【STL】vector常见用法及模拟实现(附源码)
目录 前言1. vector介绍及使用1.1vector的介绍1.2 vector的使用1.2.1 构造函数 1.2.2 vector对象遍历1.2.3 reserve和resize1.2.4 insert和erase 2. vector模拟实现2.1 vector迭代器失效问题2.2 模拟实现reserve函数浅拷贝问题2.3模拟实现源码2.3.1 vector.h2.3.2 test.cpp 前言…...
![](https://www.ngui.cc/images/no-images.jpg)
深度学习保姆级教学
文章目录 前言1.深度学习概论2.神经网络1.基础原理2.损失函数3.SoftMax4.前向传播5.反向传播1.反向传播介绍 6 卷积神经网络应用1.检测任务2.超分辨率重构3.医学检测4.无人驾驶5. 人脸识别 6.卷积网络和传统区别7.卷积神经网络1.卷积做了什么?2.节点网络1.Alexnet2.…...
![](https://www.ngui.cc/images/no-images.jpg)
计算机视觉的优势和挑战
计算机视觉(CV)是一项快速发展的技术,它具有许多优势和挑战。以下是一些可能的例子: 优势: 1. 自动化:CV技术可以自动化任务,例如图像分类、目标检测和跟踪,从而提高生产力和减少人…...
![](https://img-blog.csdnimg.cn/img_convert/8f9ac24f7314580e4e12449aa9ea3cb6.png)
群晖管家+内网穿透实现公网远程访问本地黑群晖
白嫖怪狂喜!黑群晖也能使用群晖管家啦! 文章目录 白嫖怪狂喜!黑群晖也能使用群晖管家啦!1.使用环境要求:2.下载安装群晖管家app3.随机地址登陆群晖管家app4.固定地址登陆群晖管家app 自己组装nas的白嫖怪们虽然也可以通…...
![](https://www.ngui.cc/images/no-images.jpg)
Essential C++【读书笔记 思考总结】
本篇博客是学习过程中的笔记、思考和总结。原文链接: 3 泛型编程风格 Generic Programming3.1 指针的算术运算3.2 了解 Iterator(泛型指针)3.3 所有容器的共通操作 3 泛型编程风格 Generic Programming STL的主要组件:Container&…...
![](https://img-blog.csdnimg.cn/46b6fcb2fa604c86ae2a666c14d9072a.png)
深度学习实战基础案例——卷积神经网络(CNN)基于Xception的猫狗识别|第2例
文章目录 一、环境准备二、数据预处理三、构建模型四、实例化模型五、训练模型5.1 构建训练函数5.2 构建测试函数5.3 开始正式训练 六、可视化精度和损失七、个体预测总结 今天使用轻量级的一个网络Xception做一个简单的猫狗识别案例,我的环境具体如下: …...
![](https://www.ngui.cc/images/no-images.jpg)
Linux Systemd 配置开机自启
博文目录 文章目录 Systemd操作方式配置方式配置示例参考 Systemd Systemd 是一个用于启动、管理和监控 Linux 系统的初始化系统。它是许多现代 Linux 发行版中默认的初始化系统,取代了传统的 SysVinit 和 Upstart。 Systemd 的引入在 Linux 社区引起了一些争议&…...
![](https://img-blog.csdnimg.cn/4cc67de337524376ad7507e4384a31b8.png)
华为云云耀云服务器L实例评测|轻量级应用服务器对决:基于 fio 深度测评华为云云耀云服务器L实例的磁盘性能
本文收录在专栏:#云计算入门与实践 - 华为云 专栏中,本系列博文还在更新中 相关华为云云耀云服务器L实例评测文章列表如下: 华为云云耀云服务器L实例评测 | 从零开始:云耀云服务器L实例的全面使用解析指南华为云云耀云服务器L实…...
![](https://img-blog.csdnimg.cn/85a22603c7f94fcaa97da85ca010f49f.png)
卸载Visual Studio 2010学习版 —— 卸载VCExpress
目录 最初安装Visual Studio 2010学习版是因为计算机二级 C语言考试而装,现如今考完试后便可卸载掉了,安装简便而卸载却没有uninstall.exe文件。故本文提供卸载方式。 进入到程序目录,找到setup.exe文件,也可以在程序目录搜索set…...
![](/images/no-images.jpg)
济南seo网站优化/百度网盘下载慢
密码一会被盗 一会404 密码cookie也记不住 擦 还技术网站 完全没落了!!!...
![](https://images2018.cnblogs.com/blog/339342/201805/339342-20180504202430550-365649759.png)
老闵行房价/搜索引擎营销优化诊断训练
最近因需要,翻出几年前的Leapmotion感测器,准备用Unity3D做个互动APP,于是连上官网下载SDK。等下载下来一安装调试,瞬间傻眼,居然要求VR设备。我们Lab倒是不缺VR,有几套VIVE,不过不能保证甲方也…...
![](/images/no-images.jpg)
美丽阿坝网站怎么做/最好的优化公司
参考文章: 1. hadoop mapper和reduce数量设置 https://447214075.iteye.com/blog/2153694 2.Hive中如何确定map数 源码级别 文章揭示了不同 InputFormat 下的划分标准 https://blog.csdn.net/wuliusir/article/details/45010129 Hive 中 Mapper 与 Reducer 的个…...
![](http://img4.cache.netease.com/men/2014/7/30/201407301529323a27f.jpg)
用dw做网站 主题是哪个/外包seo服务收费标准
史上最强型人养成秘籍: 90 天肥仔变型男实录[12P] 这是一篇最近很火的帖子。主人公B.K ,是一个从来没有看见过自己腹肌的三十三岁中年普通男人,就是因为青春易逝的危机感,让他下定决心给自己一个交代!于是用了九十天&a…...
![](/images/no-images.jpg)
企业网站建设套餐/搜索引擎关键词优化
目录 0. 相关文章链接 1. 如何确定 FE 进程启动成功 2. 如何确定 BE 进程启动成功 3. 搭建系统后,如何确定 FE、BE 连通性正常 4. Doris 各节点认证机制 5. BE 进程文件句柄数 0. 相关文章链接 数据库 文章汇总 1. 如何确定 FE 进程启动成功 FE 进程启动后…...
![](http://img2.tuicool.com/UJ77ryN.jpg!web)
用qq邮箱做网站/南京广告宣传公司seo
网站技术高速发展的今天,缓存技术已经成为大型网站的一个关键技术,缓存设计好坏直接关系的一个网站访问的速度,以及购置服务器的数量,甚至影响到用户的体验。网站缓存按照存放的地点不同,可以分为客户端缓存、服务端缓…...