当前位置: 首页 > news >正文

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;

相关文章:

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

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

5分钟了解docker的Swarm机制

Swarm框架概述 1.1 Swarm的基本概念 在容器化技术的浪潮中&#xff0c;Docker无疑是最为耀眼的明星之一。而作为Docker生态系统中的重要组成部分&#xff0c;Swarm框架则扮演着至关重要的角色。Swarm&#xff0c;顾名思义&#xff0c;就是“群”的意思&#xff0c;它是一个开…...

python实现ppt转pdf

要实现将PPT文件转换为PDF文件&#xff0c;可以使用Python中的python-pptx库来读取PPT文件&#xff0c;并使用reportlab库来生成PDF。又或者&#xff0c;你也可以使用其他库如pypdf和pypptx等进行处理。 以下是一个使用unoconv工具以及Python的示例&#xff0c;可以将PPT转换为…...

VS2017 编译 SQLite3 动态库

首先官方下载源码: Tags sqlite/sqlite (github.com) 1.安装 VS2017 community edition 2.打开VS2017命令行工具 3.安装TCL 开发库,推荐 TCL 9.0 先下载源码: Tcl/Tk 9.0 使用vs2017编译tcl&...

Linux运维_Apache更改默认网站目录

1.首先创建目录 并且在目录下新建测试文件 index.html mkdir -p /home/test/ap_web 直接wget 百度官网 wget www.baidu.com 2.编辑配置文件 /etc/apache2/sites-available/000-default.conf(找到 DocumentRoot)更改为刚刚创建的目录 接着在添加 最终文件: 3.给文件 添加属…...

QT QString学习笔记

1.操作字符串 1.提供双元运算符 “” QString str1"cccc"; str1 str1 "ddddd"; qDebug()<<str1; qDebug()<<qPrintable(str1); 2.提供操作符 append() QString str1 "Good"; QString str2 "bye"; str1.append(str2); …...

4.stm32 GPIO输入

按键简介 按键&#xff1a;常见的输入设备&#xff0c;按下导通&#xff0c;松手断开 按键抖动&#xff1a;由于按键内部使用的是机械式弹簧片来进行通断的&#xff0c;所以在按下和松手的瞬间会伴随有一连串的抖动 传感器模块简介 传感器模块&#xff1a;传感器元件&#…...

GPT系列

GPT&#xff08;Generative Pre-Training&#xff09;&#xff1a; 训练过程分两步&#xff1a;无监督预训练有监督微调 模型结构是decoder-only的12层transformer 1、预训练过程&#xff0c;窗口为k&#xff0c;根据前k-1个token预测第k个token&#xff0c;训练样本包括700…...

Chromium 前端window对象c++实现定义

前端中window.document window.alert()等一些列方法和对象在c对应定义如下&#xff1a; 1、window对象接口定义文件window.idl third_party\blink\renderer\core\frame\window.idl // https://html.spec.whatwg.org/C/#the-window-object// FIXME: explain all uses of [Cros…...

【力扣算法题】每天一道,健康生活

2024年10月8日 参考github网站&#xff1a;代码随想录 1.二分查找 leetcode 视频 class Solution { public:int search(vector<int>& nums, int target) {int left 0;int right nums.size()-1;while(left<right){int middle (leftright)/2;if(nums[middle] …...

Android Camera系列(四):TextureView+OpenGL ES+Camera

别人贪婪时我恐惧&#xff0c;别人恐惧时我贪婪 Android Camera系列&#xff08;一&#xff09;&#xff1a;SurfaceViewCamera Android Camera系列&#xff08;二&#xff09;&#xff1a;TextureViewCamera Android Camera系列&#xff08;三&#xff09;&#xff1a;GLSur…...

03 django管理系统 - 部门管理 - 部门列表

部门管理 首先我们需要在models里定义Dept类 # 创建部门表 class Dept(models.Model):name models.CharField(max_length100)head models.CharField(max_length100)phone models.CharField(max_length15)email models.EmailField()address models.CharField(max_length2…...

L1 Sklearn 衍生概念辨析 - 回归/分类/聚类/降维

背景 前文中我们提到&#xff1a; Scikit-Learn 库的算法主要有四类&#xff1a;分类、回归、聚类、降维&#xff1a; 回归&#xff1a;线性回归、决策树回归、SVM回归、KNN 回归&#xff1b;集成回归&#xff1a;随机森林、Adaboost、GradientBoosting、Bagging、ExtraTrees。…...

【畅捷通-注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…...

TCP IP网络编程

文章目录 TCP IP网络编程一、基础知识&#xff08;TCP&#xff09;1&#xff09;Linux1. socket()2.bind()2.1前提2.2字节序与网络字节序2.3 字节序转换2.4 字符串信息转化成网络字节序的整数型2.5 INADDR_ANY 3.listen()4.accept()5.connect()6.案例小结6.1服务器端6.2 客户端…...

libssh2编译部署详解

libssh2编译部署详解 一、准备工作二、编译libssh2方法一:使用Autotools构建方法二:使用CMake构建三、验证安装四、使用libssh2五、结论libssh2是一个用于实现SSH2协议的开源库,它支持建立安全的远程连接、传输文件等操作。本文将详细介绍如何在Linux系统下编译和部署libssh…...

IPv4数据报的首部格式 -计算机网络

IPv4数据报的首部格式 Day22. IPv4数据报的首部格式 -计算机网络_4字节的整数倍-CSDN博客 IP数据报首部是4字节的整数倍 &#x1f33f;版本&#xff1a; 占4比特&#xff0c;表示IP协议的版本通信双方使用的IP协议必须一致&#xff0c;目前广泛使用的IP协议版本号上4&#xf…...

小米电机与STM32——CAN通信

背景介绍&#xff1a;为了利用小米电机&#xff0c;搭建机械臂的关节&#xff0c;需要学习小米电机的使用方法。计划采用STM32驱动小米电机&#xff0c;实现指定运动&#xff0c;为此需要了解他们之间的通信方式&#xff0c;指令写入方法等。花了很多时间学习&#xff0c;但网络…...

2.2.ReactOS系统KSERVICE_TABLE_DESCRIPTOR结构体的声明

2.2.ReactOS系统KSERVICE_TABLE_DESCRIPTOR结构体的声明 2.2.ReactOS系统KSERVICE_TABLE_DESCRIPTOR结构体的声明 文章目录 2.2.ReactOS系统KSERVICE_TABLE_DESCRIPTOR结构体的声明KSERVICE_TABLE_DESCRIPTOR系统调用表结构体的声明 KSERVICE_TABLE_DESCRIPTOR系统调用表结构体…...

前端接口报500如何解决 | 发生的原因以及处理步骤

接口500&#xff0c;通常指的是服务器内部错误&#xff08;Internal Server Error&#xff09;&#xff0c;是HTTP协议中的一个标准状态码。当服务器遇到无法处理的错误时&#xff0c;会返回这个状态码。这种错误可能涉及到服务器配置、服务器上的应用程序、服务器资源、数据库…...

Windows Cleaner终极指南:一键解决C盘爆红和系统卡顿的开源神器

Windows Cleaner终极指南&#xff1a;一键解决C盘爆红和系统卡顿的开源神器 【免费下载链接】WindowsCleaner Windows Cleaner——专治C盘爆红及各种不服&#xff01; 项目地址: https://gitcode.com/gh_mirrors/wi/WindowsCleaner 你是否经常遇到C盘变红、系统卡顿、开…...

不用Animator!用Playable+Timeline打造Unity自定义动画状态机(含项目代码片段)

突破Animator限制&#xff1a;Playable与Timeline构建Unity高阶动画系统 在Unity游戏开发中&#xff0c;动画系统一直是角色表现的核心。传统Animator虽然入门简单&#xff0c;但当项目复杂度上升时&#xff0c;状态机臃肿、过渡僵硬、调试困难等问题逐渐暴露。许多中高级开发…...

万兆NAS成本大揭秘:用MicroServer Gen8+二手X520网卡搭建全流程(含读写性能实测)

万兆NAS成本大揭秘&#xff1a;用MicroServer Gen8二手X520网卡搭建全流程&#xff08;含读写性能实测&#xff09; 在追求高速网络存储的时代&#xff0c;万兆NAS已成为技术爱好者的新宠。本文将带你深入了解如何以最低成本搭建一套性能不俗的万兆NAS系统&#xff0c;核心硬件…...

贪心算法3(c++)

概念题目最短前缀题目描述 一个字符串的前缀是从该字符串的第一个字符起始的一个子串。例如carbon的字串是:cca,carcarb,carbo,和carbon。我们现在希望能用前缀来缩略的表示单词。例如,carbohydrate通常用carb来缩略表示&#xff0c;现在给你一组单词&#xff0c;要求你找到唯一…...

南北阁Nanbeige 4.1-3B Git版本控制实战:从入门到团队协作

南北阁Nanbeige 4.1-3B Git版本控制实战&#xff1a;从入门到团队协作 本文面向刚接触版本控制的开发者&#xff0c;手把手教你用南北阁Nanbeige 4.1-3B掌握Git核心技能&#xff0c;从基础命令到团队协作全流程。 1. 为什么你需要Git版本控制&#xff1f; 刚开始写代码时&…...

毕业季论文救星:深度解析百考通AI如何智能攻克文献综述与开题报告

又到一年毕业季&#xff0c;无数莘莘学子在为自己学术生涯的“终极答卷”——毕业论文而挑灯夜战。其中&#xff0c;文献综述的浩如烟海与开题报告的千头万绪&#xff0c;无疑是横亘在大多数同学面前的两座大山。你是否也曾面对海量文献不知如何筛选梳理&#xff1f;是否为构建…...

告别pip安装失败:在Jetson Nano(ARM64)上手动编译PyQt5 5.15.2的完整记录

在Jetson Nano&#xff08;ARM64&#xff09;上手动编译PyQt5 5.15.2的完整指南 当你在Jetson Nano这样的ARM64架构设备上尝试用pip安装PyQt5时&#xff0c;很可能会遇到各种兼容性问题。作为一款强大的Python GUI库&#xff0c;PyQt5在嵌入式开发中有着广泛的应用场景&#x…...

Drone流水线进阶玩法:用.drone.yml实现多阶段构建+钉钉通知(2023最新版)

Drone流水线进阶实战&#xff1a;多阶段构建与智能通知全链路设计 当你的团队从单体架构转向微服务时&#xff0c;CI/CD流水线会突然变得复杂起来。上周我接手的一个电商项目就遇到了典型问题&#xff1a;每次代码提交后需要同时处理Java后端的Maven构建、前端Node.js打包、Doc…...

Bud错误处理终极指南:构建健壮Web应用的10个最佳实践

Bud错误处理终极指南&#xff1a;构建健壮Web应用的10个最佳实践 【免费下载链接】bud The Full-Stack Web Framework for Go 项目地址: https://gitcode.com/gh_mirrors/bu/bud Bud作为Go语言的全栈Web框架&#xff0c;其错误处理机制直接影响应用的稳定性和用户体验。…...

GTE-Pro物流应用:运单文本的智能处理

GTE-Pro物流应用&#xff1a;运单文本的智能处理 1. 物流行业的文本处理挑战 每天&#xff0c;物流公司都要处理海量的运单文本和客服对话。这些文本数据里藏着宝贵的信息&#xff0c;但传统的关键词匹配方法往往力不从心。 想象一下这样的场景&#xff1a;一个运单上写着&q…...