优化使用 Flask 构建视频转 GIF 工具
优化使用 Flask 构建视频转 GIF 工具
优化后的项目概述
在优化后的版本中,我们将实现以下功能:
- 可设置每个 GIF 的帧率和大小:用户可以选择 GIF 的帧率和输出大小。
- 改进的用户界面:使用更现代的设计使界面更美观、整洁。
- 自定义生成的 GIF 文件名:用户可以为每个视频设置开始时间和持续时间。
优化后的项目结构
your_project/
│
├── app_plus.py # 优化后的 Flask 应用
├── input_videos/ # 上传视频的文件夹
├── output_gifs/ # 输出 GIF 的文件夹
└── templates/└── index_plus.html # 优化后的 HTML 前端页面
Flask 应用代码 (app_plus.py
)
from flask import Flask, request, render_template, redirect, url_for, send_from_directory
import subprocess
import osapp = Flask(__name__)
app.config['UPLOAD_FOLDER'] = './input_videos/'
app.config['OUTPUT_FOLDER'] = './output_gifs/'# 确保上传和输出文件夹存在
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
os.makedirs(app.config['OUTPUT_FOLDER'], exist_ok=True)def convert_video_to_gif(input_video_path, output_gif_path, start_time, duration, fps, scale):command = ['ffmpeg','-ss', str(start_time),'-t', str(duration),'-i', input_video_path,'-vf', f'fps={fps},scale={scale}:-1:flags=lanczos','-c:v', 'gif',output_gif_path]subprocess.run(command)@app.route('/', methods=['GET', 'POST'])
def index():if request.method == 'POST':video_files = request.files.getlist('video_files')start_times = request.form.getlist('start_times')durations = request.form.getlist('durations')fps = request.form['fps']scale = request.form['scale']custom_name = request.form['custom_name'] # 获取自定义文件名for index, video_file in enumerate(video_files):if video_file:input_video_path = os.path.join(app.config['UPLOAD_FOLDER'], video_file.filename)# 使用用户提供的自定义文件名生成 GIF 文件output_gif_path = os.path.join(app.config['OUTPUT_FOLDER'], f"{custom_name}_{index}.gif")video_file.save(input_video_path)convert_video_to_gif(input_video_path, output_gif_path, start_times[index], durations[index], fps, scale)return redirect(url_for('index')) # 重定向回主页return render_template('index_plus.html')@app.route('/output_gifs/<filename>')
def send_gif(filename):return send_from_directory(app.config['OUTPUT_FOLDER'], filename)if __name__ == '__main__':app.run(debug=True)
HTML 页面代码 (index_plus.html
)
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>视频转GIF工具</title><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css"><style>body {font-family: 'Arial', sans-serif;margin: 0;padding: 0;background-color: #f0f0f0;color: #333;}.container {max-width: 800px;margin: 50px auto;padding: 30px;background: white;border-radius: 10px;box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);text-align: center;}h1 {color: #4CAF50;margin-bottom: 20px;}input[type="file"], input[type="number"], input[type="text"] {margin: 10px 0;padding: 15px;width: calc(100% - 30px);border: 1px solid #ccc;border-radius: 5px;transition: border-color 0.3s;}input[type="file"]:hover, input[type="number"]:hover, input[type="text"]:hover {border-color: #4CAF50;}button {margin: 20px 0;padding: 15px;width: 100%;background-color: #4CAF50;color: white;border: none;border-radius: 5px;cursor: pointer;transition: background-color 0.3s;}button:hover {background-color: #45a049;}footer {margin-top: 30px;font-size: 14px;color: #777;}.video-input {margin-bottom: 20px;border: 1px solid #ccc;border-radius: 5px;padding: 10px;}.video-input div {margin-bottom: 10px;}@media (max-width: 600px) {.container {padding: 20px;}h1 {font-size: 24px;}}</style>
</head>
<body><div class="container"><h1>视频转GIF工具</h1><form action="/" method="post" enctype="multipart/form-data"><div class="video-input"><input type="file" name="video_files" accept="video/*" multiple required><input type="number" name="start_times" placeholder="开始时间(秒)" required><input type="number" name="durations" placeholder="持续时间(秒)" required></div><label for="fps">帧率 (fps):</label><input type="number" name="fps" placeholder="例如: 10" required><label for="scale">输出大小 (宽度):</label><input type="text" name="scale" placeholder="例如: 320" required><label for="custom_name">自定义文件名:</label><input type="text" name="custom_name" placeholder="例如: my_gif" required><button type="submit">转换为 GIF</button></form><footer><p>© 2025 无限大</p></footer></div>
</body>
</html>
说明
-
Flask 应用 (
app_plus.py
):- 设置上传和输出文件夹。
- 提供一个函数
convert_video_to_gif
,用来调用 FFmpeg 生成 GIF 文件。 - 在
/
路由中处理文件上传和 GIF 生成。 - 获取用户输入的自定义 GIF 文件名,生成的文件名为
自定义名字 + 索引 + .gif
以避免重名问题。
-
HTML 界面 (
index_plus.html
):- 创建一个用户输入界面,允许用户上传视频、设置时间参数、帧率和输出大小。
- 添加输入框让用户输入自定义 GIF 文件名。
依赖
确保安装了 Flask 和 FFmpeg:
pip install Flask
并确保 FFmpeg 已正确安装并在系统路径中。
启动和测试
运行 Flask 应用:
python app_plus.py
在浏览器中访问 http://127.0.0.1:5000/
测试功能。
相关文章:
优化使用 Flask 构建视频转 GIF 工具
优化使用 Flask 构建视频转 GIF 工具 优化后的项目概述 在优化后的版本中,我们将实现以下功能: 可设置每个 GIF 的帧率和大小:用户可以选择 GIF 的帧率和输出大小。改进的用户界面:使用更现代的设计使界面更美观、整洁。自定义…...
spring cloud如何实现负载均衡
在Spring Cloud中,实际上并没有直接支持lb:\\这样的URL前缀来自动解析为负载均衡的服务地址。lb:\\这样的表示可能是在某些特定框架、文档或示例中自定义的,但它并不是Spring Cloud官方API或规范的一部分。 Spring Cloud实现负载均衡的方式通常依赖于服…...

leetcode19-删除链表的第n结点
leetcode 19 思路 要删除倒数第n个元素,那么就要找到倒数第n1个元素,那么我们需要两个指针来记录,首先快指针需要先走n1步,然后快慢指针一起进行移动,直到快指针为null的时候,此时慢指针恰好走到倒数第n…...

软件测试—— 接口测试(HTTP和HTTPS)
软件测试—— 接口测试(HTTP和HTTPS) HTTP请求方法GET特点使用场景URL结构URL组成部分URL编码总结 POST特点使用场景请求结构示例 请求标头和响应标头请求标头(Request Headers)示例请求标头 响应标头(Response Header…...
3.1 Go函数调用过程
在 Go 语言中,函数调用的核心机制依赖于内存的栈区分配和指针操作,理解这一原理有助于掌握函数的执行过程。 1. 内存结构概述 在 Go 程序编译成可执行文件并启动后,操作系统会为其分配进程内存,进程内存主要分为以下区域&#x…...

TDengine 做 Apache SuperSet 数据源
Apache Superset 是一个现代的企业级商业智能(BI)Web 应用程序,主要用于数据探索和可视化。它由 Apache 软件基金会支持,是一个开源项目,它拥有活跃的社区和丰富的生态系统。Apache Superset 提供了直观的用户界面…...

08_游戏启动逻辑
1.GameRoot.cs 控制 服务层Svc.cs 和业务层Sys.cs 的初始化 创建脚本GameRoot.cs(游戏入口 已进入就初始化各个系统) 创建资源加载服务.cs Res 将服务层Svc设置成单例类所以需要挂载在GameRoot身上,这样就可以通过GameRoot来调各个服务 接…...

Ardupilot开源无人机之Geek SDK进展2024-2025
Ardupilot开源无人机之Geek SDK进展2024-2025 1. 源由2. 状态3. TODO3.1 【进行中】跟踪目标框3.2 【暂停】onnxruntime版本3.3 【完成】CUDA 11.8版本3.4 【完成】pytorch v2.5.1版本3.5 【未开始】Inference性能3.6 【未开始】特定目标集Training 4. Extra-Work4.1 【完成】C…...
在K8S中,如果后端NFS存储的IP发送变化如何解决?
在Kubernetes中,如果后端NFS存储的IP地址发生了变化,您需要更新与之相关的Peristent Volume(PV)或Persistent Volume Claim(PVC)以及StorageClass中关于NFS服务器IP的配置信息,确保K8S集群内的Pod能够正确连接到新的NFS存储位置。解决方案如下…...

模拟飞行入坑(五) P3D 多通道视角配置 viewgroup
背景: P3D进行多个屏幕显示的时候,如果使用英伟达自带的屏幕融合成一个屏,或者使用P3D单独拉伸窗口,会使得P3D的画面被整体拉伸,又或者,当使用Multichannel进行多个设备联动时,视角同步组合需要配置&#…...
【springboot集成knife4j】
SpringBoot集成knife4j Knife4j是为Java MVC框架集成Swagger生成API文档的一套增强解决方案,它基于Swagger原有的基础上进行了一些改进和增强,提供了更简洁的UI界面,同时支持更多的自用化配置。下面是在Spring Boot项目中集成Knife4j的基本步…...
GPUStack使用
1. 概述 官网:https://github.com/gpustack Open-source GPU cluster manager for running large language models(LLMs) https://github.com/gpustack/gpustack,Manage GPU clusters for running AI models GPUStack 是一个用于运行 AI 模型的开源 GPU 集群管理器。 官…...

如何选择一款助贷获客系统?
做助贷的销售们,一天打几百个电话,跑各种新媒体平台评论区偷流量,每天忙得昏天黑地,也没有多少客户。没有精准数据,助贷销售着急,公司也着急,每天让员工加班找客户,但是巧妇难为无米…...
GDB相比IDE有什么优点
GDB(GNU Debugger)相比于集成开发环境(IDE)具有一些独特的优点,主要体现在其灵活性、可定制性和低级控制能力。具体来说,GDB有以下几个优点: 1. 轻量级且无依赖 GDB是一个命令行工具,不依赖于任何复杂的图形界面或大型库,这使得它非常适合在资源受限的环境中使用,比…...

介绍用于机器学习的 Fashion-MNIST 数据集
介绍用于机器学习的 Fashion-MNIST 数据集 为什么要研究数据集? 让我们首先思考一下为什么要花时间研究数据集的问题。数据是深度学习的主要成分,虽然作为神经网络程序员的任务是让我们的神经网络从我们的数据中学习,但我们仍然有责任了解我…...

【GitHub】登录时的2FA验证
一、如何进行2FA认证 1.在你的浏览器中下载 Authenticator身份验证插件 2.使用身份验证器添加凭证 2.1 使用身份验证器扫描验证二维码 选择扫描二维码...

CSDN年度回顾:技术征途上的坚实步伐
嘿,时光过得可真快呀,就像那匹跑得飞快的白马,嗖的一下,2024 年的日历就这么悄无声息地翻到了最后一页。这会儿我回头看看在 CSDN 上度过的这一年,心里那叫一个感慨万千,满满的都是喜悦,就像心里…...

Kotlin Bytedeco OpenCV 图像图像57 图像ROI
Kotlin Bytedeco OpenCV 图像图像57 图像ROI 1 添加依赖2 测试代码3 测试结果 1 添加依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xmlns"http://maven.apache.o…...

支持大功率输出高速频闪的图像处理用光源控制器
机器视觉系统中的光源控制器在确保图像质量、提高系统稳定性、降低能耗以及方便系统扩展和升级等方面发挥着重要作用。它可提供稳定光源,调节参数,另外具有操作便捷性。 下面我们来看Gardasoft的光源控制器,Gardasoft拥有作为图像处理用LED光…...

《从入门到精通:蓝桥杯编程大赛知识点全攻略》(五)-数的三次方根、机器人跳跃问题、四平方和
本博客将详细探讨如何通过二分查找算法来解决这几个经典问题。通过几个实际的例子,我们将展示如何在这些问题中灵活应用二分查找,优化计算过程,并在面对大数据量时保持高效性。 目录 前言 数的三次方根 算法思路 代码如下 机器人跳跃问题…...

vue中加载Cesium地图(天地图、高德地图)
目录 1、将下载的Cesium包移动至public下 2、首先需要将Cesium.js和widgets.css文件引入到 3、 新建Cesium.js文件,方便在全局使用 4、新建cesium.vue文件,展示三维地图 1、将下载的Cesium包移动至public下 npm install cesium后 2、…...

《100天精通Python——基础篇 2025 第5天:巩固核心知识,选择题实战演练基础语法》
目录 一、踏上Python之旅二、Python输入与输出三、变量与基本数据类型四、运算符五、流程控制 一、踏上Python之旅 1.想要输出 I Love Python,应该使用()函数。 A.printf() B.print() C.println() D.Print() 在Python中想要在屏幕中输出内容,应该使用print()函数…...
C++.OpenGL (9/64)复习(Review)
复习(Review) 核心概念快速回顾 #mermaid-svg-MMSQf7gXQlHqiqfM {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-MMSQf7gXQlHqiqfM .error-icon{fill:#552222;}#mermaid-svg-MMSQf7gXQlHqiqfM .error-text{fill:#…...
HTTP、WebSocket、SSE 对比
特性HTTPWebSocketSSE (Server-Sent Events)通信模式请求-响应(单向)全双工双向通信服务器到客户端的单向通信连接方式短连接(默认)长连接长连接协议基础TCP(HTTP/1.1, HTTP/2)基于HTTP升级基于HTTP数据格式…...
Unity基于GraphView的可视化关卡编辑器开发指南
一、GraphView技术基础与应用场景 1. GraphView核心组件 组件功能描述关卡编辑应用GraphView画布容器关卡拓扑结构编辑区Node基础节点房间/敌人/道具等关卡元素Edge节点连接线路径/依赖关系Port连接端口入口/出口标记Blackboard属性面板元素参数配置Minimap缩略图导航大型关卡…...

智启未来:当知识库遇见莫奈的调色盘——API工作流重构企业服务美学
目录 引言 一、初识蓝耘元生代MaaS平台 1.1 平台架构 1.2 平台的优势 1.3 应用场景 二、手把手教你如何在蓝耘进行注册 (1)输入手机号,将验证码正确填入即可快速完成注册 (2)进入下面的页面表示已经成功注册&…...

光电耦合器:数字时代的隐形守护者
在数字化、自动化高速发展的今天,光电耦合器正以一种低调却不可或缺的方式,悄然改变着我们的生活。它不仅是电子电路中的“安全卫士”,更是连接信号世界的“桥梁”,凭借出色的电气隔离能力,为各类设备提供稳定可靠的信…...
ArcGIS Pro 3.4 二次开发 - 宗地
环境:ArcGIS Pro SDK 3.4 + .NET 8 文章目录 宗地1 宗地1.1 向地图添加宗地图层1.2 获取活动记录1.3 设置活动记录1.4 创建新记录1.5 将标准线要素复制到宗地类型1.6 将宗地线复制到宗地类型1.7 将要素分配给活动记录1.8 创建宗地种子1.9 构建地块1.10 重复地块1.11 设置地块为…...
docker 搭建php 开发环境 添加扩展redis、swoole、xdebug(2)
3、创建compose 的yml文件 version: "3.9" services:#配置nginxnginx:#镜像名称 nginx:latestimage: nginx#自定义容器的名称#container_name: c_nginxports:- "80:80"#lnmp目录和容器的/usr/share/nginx/html目录进行绑定,设置rw权限#将宿主机的~/lnmp/…...

CMake在VS中使用远程调试
选中CMakeLists.txt, 右键-添加调试配置-选中"C\C远程windows调试" 之后将 aunch.vs.json文件改为如下所示: CMake在VS中使用远程调试时,Launch.vs.json中远程调试设置 ,远程电脑开启VS专用的RemoteDebugger {"version": "0.2.1","defaul…...