FFmpeg的简单使用【Windows】--- 视频倒叙播放

实现功能

点击【选择文件】按钮可以选择视频,当点击【开始处理】按钮之后,会先将视频上传到服务器,然后开始进行视频倒叙播放的处理,当视频处理完毕之后会将输出的文件路径返回,同时在页面中将处理好的视频展示出来。

效果展示

转换成功效果展示
上传成功
处理后

代码实现

说明:

前端代码是使用vue编写的。

后端接口的代码是使用nodejs进行编写的。

前端代码

<template><div id="app"><!-- 显示上传的视频 --><div><h2>将要处理的视频</h2><videov-for="video in uploadedVideos":key="video.src":src="video.src"controlsstyle="width: 200px"></video></div><!-- 上传视频按钮 --><input type="file" @change="uploadVideo" accept="video/*" /><!-- 显示处理后的视频 --><div><h2>已处理后的视频</h2><videov-for="video in processedVideos":key="video.src":src="video.src"controlsstyle="width: 200px"></video></div><button @click="processVideos">开始处理</button></div>
</template><script setup>
import axios from "axios";
import { ref } from "vue";const uploadedVideos = ref([]);
const processedVideos = ref([]);
let videoIndex = 0;const uploadVideo = async (e) => {const files = e.target.files;for (let i = 0; i < files.length; i++) {const file = files[i];const videoSrc = URL.createObjectURL(file);uploadedVideos.value.push({ id: videoIndex++, src: videoSrc, file });}
};const processVideos = async () => {const formData = new FormData();for (const video of uploadedVideos.value) {formData.append("video", video.file); // 使用实际的文件对象}try {const response = await axios.post("http://localhost:3000/user/single/process",formData,{headers: {"Content-Type": "multipart/form-data",},});const processedVideoSrc = response.data.path;processedVideos.value.push({id: videoIndex++,src: "http://localhost:3000/" + processedVideoSrc,});} catch (error) {console.error("Error processing video:", error);}
};
</script>

补充说明:

 accept="video/*":指定了只接受视频文件类型,这将过滤掉非视频文件,使得用户在选择文件时只能看到并选择视频文件。

video/*:是一个通配符,表示所有已知的视频文件类型。如果你只想接受特定的视频格式(例如MP4和WebM),你可以指定他们,如下所示:

accept=".mp4, .webm"

或者,如果你想要更精确地控制,可以使用MIME类型:

accept="video/mp4, video/webm"

后端代码

routers =》users.js

var express = require('express');
var router = express.Router();
const multer = require('multer');
const ffmpeg = require('fluent-ffmpeg');
const path = require('path');
const upload = multer({dest: 'public/uploads/',storage: multer.diskStorage({destination: function (req, file, cb) {cb(null, 'public/uploads'); // 文件保存的目录},filename: function (req, file, cb) {// 提取原始文件的扩展名const ext = path.extname(file.originalname).toLowerCase(); // 获取文件扩展名,并转换为小写// 生成唯一文件名,并加上扩展名const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);const fileName = uniqueSuffix + ext; // 新文件名cb(null, fileName); // 文件名}})
});
const fs = require('fs');// 处理单个视频文件
router.post('/single/process', upload.single('video'), (req, res) => {console.log(req.file)const videoPath = req.file.path;// 使用filename进行拼接是为了防止视频被覆盖const outputPath = `public/processed/reversed_${req.file.filename}`;ffmpeg().input(videoPath).outputOptions(['-vf reverse'// 反转视频帧顺序]).output(outputPath).on('end', () => {res.json({ message: 'Video processed successfully.', path: outputPath.replace('public', '') });}).on('error', (err) => {console.log(err)res.status(500).json({ error: 'An error occurred while processing the video.' });}).run();
});module.exports = router;

multer配置项说明:

  • 配置选项:
    • dest:指定了文件的临时存储路径,如果提供了storage选择,则dest可能不会被使用。
    • storage:使用multer.diskStorage() 来定义文件如何存储在磁盘上。
  • destination函数:
    • 这个函数用于指定文件存储的目录
    • req:请求对象
    • file:包含了关于上传文件的信息
    • cb:回调函数,用于通知multer存储路径
  • filename函数:
    • 这个函数用于生成存储在磁盘上的文件名
    • req:请求对象
    • file:含有文件的相关信息
    • cb:回调函数,用于通知穆拉特人文件名
    • 在这里,我们生成了一个唯一的文件名,该文件名包含当前时间戳和一个随机数,以避免文件名冲突,并保留了原始文件的扩展名。

ffmpeg()说明:

当你调用 ffmpeg() 时,实际上创建了一个 ffmpeg 实例。这个实例可以用来设置输入文件、输出文件以及一系列的处理选项。

ffmpeg() 返回的是一个 Command 对象,这个对象包含了用于设置和执行 ffmpeg 命令的方法。这些方法可以链接起来形成一个流式操作链。

  • .input():指定输入文件路径
  • .output():指定输出文件路径
  • .on()、.once():监听事件,比如完成、错误等
  • .run():执行ffmpeg命令
  • .cancel():取消正在运行的命令
  • .getCommand():获取将要执行的完整命令字符串

典型的ffmpeg命令执行流程

  1. 初始化:创建 ffmpeg 示例并指定输入文件
  2. 设置输出文件:使用 .output() 方法来设置文件路径
  3. 添加命令行参数:使用 .addOption() 或者链式调用 .option() 方法来添加额外的 ffmpeg参数
  4. 监听事件:监听 end error 事件来处理命令执行的结果
  5. 执行命令:调用 .run() 方法来开始执行命令

 

routers =》index.js

var express = require('express');
var router = express.Router();router.use('/user', require('./users'));module.exports = router;

 app.js

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');var indexRouter = require('./routes/index');var app = express();// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));// 使用cors解决跨域问题
app.use(require('cors')());app.use('/', indexRouter);// catch 404 and forward to error handler
app.use(function (req, res, next) {next(createError(404));
});// error handler
app.use(function (err, req, res, next) {// set locals, only providing error in developmentres.locals.message = err.message;res.locals.error = req.app.get('env') === 'development' ? err : {};// render the error pageres.status(err.status || 500);res.render('error');
});module.exports = app;

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

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

相关文章

第二十三篇:网络拥塞了,TCP/IP如何解决的?

一.显示拥塞通知 当发生网络拥塞时&#xff0c;发送主机应该减少数据包的发送量。作为IP上层协议&#xff0c;TCP虽然也能控制网络拥塞&#xff0c;不过它是通过数据包的实际损坏情况来判断是否发生拥塞。然而这种方法不能在数据包损坏之前减少数据包的发送量。 为了解决这个…

【网络安全】CVE-2024-46990: Directus环回IP过滤器绕过实现SSRF

未经许可,不得转载。 文章目录 背景漏洞详情受影响版本解决方案背景 Directus 是一款开源 CMS,提供强大的内容管理 API,使开发人员能够轻松创建自定义应用程序,凭借其灵活的数据模型和用户友好的界面备受欢迎。然而,Directus 存在一个漏洞,允许攻击者绕过默认的环回 IP …

使用libssh2上传下载文件及Makefile编写

使用libssh2上传下载文件及Makefile编写 一、准备工作二、上传和下载文件三、编写Makefilelibssh2是一个开源的SSH库,用于在C/C++程序中实现SSH2协议的功能。通过libssh2,我们可以方便地进行远程登录、执行命令、上传和下载文件等操作。本文将详细介绍如何使用libssh2库上传和…

【网易云音乐】--源代码分享

最近写了一个网易云音乐的音乐实现部分&#xff0c;是通过JavaScript和jQuery实现的&#xff0c;具体效果大家可以参照下面的视频 源代码分享 - git地址: 网易云音乐源代码 下面将着重讲解一下音乐实现部分 视频有点模糊&#xff0c;不好意思&#xff0c;在b站上添加视频的时候…

全能PDF工具集 | PDF Shaper Ultimate v14.6 便携版

软件简介 PDF Shaper是一款功能强大的PDF工具集&#xff0c;它提供了一系列用于处理PDF文档的工具。这款软件使用户能够轻松地转换、分割、合并、提取页面以及旋转和加密PDF文件。PDF Shaper的界面简洁直观&#xff0c;使得即使是新手用户也能快速上手。它支持广泛的功能&…

基于Nodemcu的手机控制小车

基于Nodemcu的手机控制小车 一、项目说明二、项目材料三、代码与电路设计四、轮子和车体五、电路连接六、使用方法 一、项目说明 嗨&#xff0c;机器人项目制造者们&#xff01;在这个项目中&#xff0c;我制作了这辆简单但快速的遥控车&#xff0c;它可以通过智能手机控制&am…

yum仓库安装rabbitmq

yum仓库安装rabbitmq 1、配置yum仓库 vim /etc/yum.repos.d/rabbitmq.repo # In /etc/yum.repos.d/rabbitmq.repo## ## Zero dependency Erlang ##[rabbitmq_erlang] namerabbitmq_erlang baseurlhttps://packagecloud.io/rabbitmq/erlang/el/7/$basearch repo_gpgcheck1 gpg…

智能生成ppt软件哪个好?如何高效生成ppt?

想要快速制作出专业且吸引人的PPT演示文稿吗&#xff1f;ai智能生成ppt工具可以帮你实现这一目标。 无需复杂的设计技巧&#xff0c;也不必花费大量时间&#xff0c;只需几个简单的步骤&#xff0c;就能创造出令人印象深刻的演示文稿。下面是一份免费版教程&#xff0c;让你轻…

PyCharm+ssh跳板机+服务器

PyCharmssh跳板机服务器 文章目录 PyCharmssh跳板机服务器准备工作登录服务器查看CUDA查看conda创建虚拟环境 前言配置ssh免密登录设置ssh隧道配置pycharm测试第一种第二种 服务器空闲查询传输数据 准备工作 登录服务器 直接ssh连接就行,在终端(命令行)直接输入下面命令: 跳…

K8s-services+pod详解1

一、Service 我们能够利用Deployment创建一组Pod来提供具有高可用性的服务。 虽然每个Pod都会分配一个单独的Pod IP&#xff0c;然而却存在如下两问题&#xff1a; Pod IP 会随着Pod的重建产生变化Pod IP 仅仅是集群内可见的虚拟IP&#xff0c;外部无法访问 这样对于访问这…

基于Python Django的在线考试管理系统

&#x1f34a;作者&#xff1a;计算机毕设匠心工作室 &#x1f34a;简介&#xff1a;毕业后就一直专业从事计算机软件程序开发&#xff0c;至今也有8年工作经验。擅长Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等。 擅长&#xff1a;按照需求定制化开发项目…

线程基础学习

线程的实现 通过实现Runnable接口的方式&#xff0c;实现其中的run方法。继承Thread类&#xff0c;然后重写其中的run方法。通过线程池创建线程&#xff0c;默认采用DefaultThreadFactory。有返回值的callable&#xff0c;实现callable接口&#xff0c;实行call方法。 本质上…

【Linux-基础IO】软硬链接+动静态库

一、软硬链接 见一见 软连接 硬连接 通过观察我们发现以下几点&#xff1a; 1.ll - i后&#xff0c;软连接形成的文件有指向&#xff0c;并且软连接的Inode编号与对应文件的Inode编号不一样 2.ll - i后&#xff0c;硬连接形成的文件与对应的文件Inode编号一样 3.软连接…

大佬,简单解释下“嵌入式软件开发”和“嵌入式硬件开发”的区别

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「嵌入式的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;首先&#xff0c;嵌入式硬…

初识数据结构--时间复杂度 和 空间复杂度

数据结构前言 数据结构 数据结构是计算机存储、组织数据的方式(指不仅能存储数据&#xff0c;还能够管理数据-->增删改)。指相互之间存在一种或多种特定关系的数据元素的集合。没有单一的数据结构对所有用途都有用&#xff0c;所以我们要学习各种的数据结构&#xff0c;比…

visual studio使用ssh连接linux虚拟机运行程序

1.vs安装linux组件 2.安装后新建项目 新建后会有一个使用指南 设置网络为桥接网卡后打开虚拟机 使用vs提升的那句话安装工具 sudo apt-get install openssh-server g gdb gdbserver 重启ssh服务 sudo service ssh restart 接着进去打开ssh端口 sudo vi /etc/ssh/sshd_config …

pytest的基础入门

pytest判断用例的成功或者失败 pytest识别用例失败时会报AssertionError或者xxxError错误&#xff0c;当捕获异常时pytest无法识别到失败的用例 pytest的fixture夹具 pytest的参数化 #coding:utf-8 import pytestfrom PythonProject.pytest_test.funcs.guess_point import ge…

小程序知识付费的优势 知识付费服务 知识付费平台 知识付费方法

在信息爆炸的时代&#xff0c;知识如同繁星点点&#xff0c;璀璨而散落。如何在这片知识的海洋中精准捕捞&#xff0c;成为现代人追求自我提升的迫切需求。小程序知识付费&#xff0c;正是这样一座桥梁&#xff0c;它以独特的优势&#xff0c;让智慧触手可及&#xff0c;轻触未…

Miniconda更改虚拟环境创建路径

Miniconda更改虚拟环境创建路径 文章目录 Miniconda更改虚拟环境创建路径前言步骤一 修改配置文件步骤二 提升路径访问权限步骤三 测试配置修改是否生效 前言 在我使用 conda 命令创建新的虚拟环境时&#xff0c;发现创建好的虚拟环境存放路径是在 ../miniconda3/pkgs/ 路径下…

Nginx从入门到实战(八):版本平滑无感知,不停机升级

一、查看旧版本信息 可以通过nginx -V命令&#xff0c;来查看当前nginx的版本信息&#xff0c;和配置参数。 [rootnb001 sbin]# nginx -V -bash: nginx: command not found [rootnb001 sbin]# ./nginx -V nginx version: nginx/1.20.1 built by gcc 4.8.5 20150623 (Red Hat …