优化使用 Flask 构建视频转 GIF 工具

优化使用 Flask 构建视频转 GIF 工具

优化后的项目概述

在优化后的版本中,我们将实现以下功能:

  1. 可设置每个 GIF 的帧率和大小:用户可以选择 GIF 的帧率和输出大小。
  2. 改进的用户界面:使用更现代的设计使界面更美观、整洁。
  3. 自定义生成的 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>

说明

  1. Flask 应用 (app_plus.py)

    • 设置上传和输出文件夹。
    • 提供一个函数 convert_video_to_gif,用来调用 FFmpeg 生成 GIF 文件。
    • / 路由中处理文件上传和 GIF 生成。
    • 获取用户输入的自定义 GIF 文件名,生成的文件名为 自定义名字 + 索引 + .gif 以避免重名问题。
  2. HTML 界面 (index_plus.html)

    • 创建一个用户输入界面,允许用户上传视频、设置时间参数、帧率和输出大小。
    • 添加输入框让用户输入自定义 GIF 文件名。

依赖

确保安装了 Flask 和 FFmpeg:

pip install Flask

并确保 FFmpeg 已正确安装并在系统路径中。

启动和测试

运行 Flask 应用:

python app_plus.py

在浏览器中访问 http://127.0.0.1:5000/ 测试功能。

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

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

相关文章

R 语言 | future 包,非阻塞的执行耗时脚本

目的&#xff1a;有一段代码&#xff0c;后面暂时用不到&#xff0c;但是又很耗时&#xff0c;占了当前R session&#xff0c;难道只能等半个小时&#xff0c;等到它结束才能画图&#xff1f; 可以使用R多线程&#xff0c;在支线中执行耗时任务&#xff0c;同时不阻塞当前R进程…

使用插件SlideVerify实现滑块验证

作者gitee地址&#xff1a;https://gitee.com/monoplasty/vue-monoplasty-slide-verify 使用步骤&#xff1a; 1、安装插件 npm install --save vue-monoplasty-slide-verify 2、在main.js中进行配置 import SlideVerify from vue-monoplasty-slide-verify; Vue.use(SlideV…

Windows配置frp内网穿透实现远程连接

仅个人记录 本文仅介绍客户端的配置 1. 开始 frp分为服务端和客户端&#xff0c;为实现内网穿透需要同时配置服务端和客户端&#xff0c;并且版本保持一致&#xff0c;可以前往 frp github下载 本文使用 0.51.2 版本&#xff0c;从GitHub下载并解压&#xff0c;得到如下文件…

“大模型横扫千军”背后的大数据挖掘--浅谈MapReduce

文章目录 O 背景知识1 数据挖掘2 邦费罗尼原则3 TF.IDF4 哈希函数5 分布式文件系统 一、MapReduce基本介绍1. Map 任务2. 按键分组3. Reduce 任务4. 节点失效处理5.小测验&#xff1a;在一个大型语料库上有100个map任务和若干reduce任务&#xff1a; 二、基于MapReduce的基本运…

第17个项目:Python烟花秀

源码下载地址:https://download.csdn.net/download/mosquito_lover1/90295693 核心源码: import pygame import random import math from PIL import Image import io # 初始化pygame pygame.init() # 设置窗口 WIDTH = 800 HEIGHT = 600 screen = pygame.display.s…

GDB相比IDE有什么优点

GDB(GNU Debugger)相比于集成开发环境(IDE)具有一些独特的优点,主要体现在其灵活性、可定制性和低级控制能力。具体来说,GDB有以下几个优点: 1. 轻量级且无依赖 GDB是一个命令行工具,不依赖于任何复杂的图形界面或大型库,这使得它非常适合在资源受限的环境中使用,比…

JavaScript学习笔记(1)

html 完成了架子&#xff0c; css 做了美化&#xff0c;但是网页是死的&#xff0c;我们需要给他注入灵魂&#xff0c;所以接下来我们需要学习 JavaScript&#xff0c;这门语言会让我们的页面能够和用户进行交互。 一、引入方式 1.内部脚本 将 JS 代码定义在 HTML 页面中 Jav…

如何判断以太坊地址类型?

如何判断以太坊地址类型&#xff1f; 一、账户类型解释 2.1 以太坊外部账户&#xff08;Externally Owned Account&#xff0c;EOA&#xff09; 外部账户&#xff08;EOA&#xff09;是由私钥控制的账户&#xff0c;在以太坊网络中用来发送交易和执行其他操作。EOA 不是智能…

大华前端开发面试题及参考答案 (下)

opacity、display 和 visibility 的区别是什么? 含义与作用 opacity:用于设置元素的透明度,取值范围从 0 到 1,0 表示完全透明(不可见),1 表示完全不透明。它会使元素及其内容包括子元素都按照指定的透明度进行显示,改变的是视觉上的透明程度。display:用于规定元素应…

二十七、资源限制-LimitRange

LimitRange生产必备 在调度的时候 requests 比较重要,在运行时 limits 比较重要。 一、产生原因 生产中只有ResourceQuota是不够的 只配置ResourceQuotas的情况下,pod的yaml文件没有配置resources配置,都是0的话,就可以无限配置,永远达不到limit LimitRange做了什么 如…

docker部署的gitlab迁移

docker部署的gitlab迁移_docker gitlab 迁移-CSDN博客 gitlab-rake gitlab:backup:restore BACKUP 后面一路yes 生活中总是充满了各种选择&#xff0c;点餐纠结&#xff0c;出行选择&#xff0c;聚餐座位&#xff0c;团队投票结果不明&#xff0c;随机抽签一锤定音等等&#xf…

【Pytest】基础到高级功能的理解使用

文章目录 第一部分&#xff1a;Pytest 简介1.1 什么是 Pytest&#xff1f;1.2 Pytest 的历史1.3 Pytest 的核心概念1.4 Pytest 的特点1.5 为什么选择 Pytest&#xff1f; 第二部分&#xff1a;Pytest 的基本使用2.1 安装 Pytest2.2 编写第一个测试用例2.2.1 创建一个简单的测试…

GS论文阅读--GeoTexDensifier

前言 本文是一个关于高斯致密化策略对高斯地图进行优化&#xff0c;他主要关注了几何结构和纹理信息。我最近对于高斯点的分布比较感兴趣&#xff0c;因为高斯点的分布决定了之后重建质量的好坏&#xff0c;初始化高斯很重要&#xff0c;但之后的维护需要致密化与修建策略&…

支持大功率输出高速频闪的图像处理用光源控制器

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

关于opensips的帮助命令的解释

opensips -help以下是 opensips 命令及其选项的中文解释&#xff08;基于 3.6.0-dev 版本&#xff09;&#xff1a; 命令用法 bash复制代码opensips -l 地址 [-l 地址 ...] [选项]选项说明 选项功能-f 文件指定配置文件&#xff08;默认为 /usr/local//etc/opensips/opensips…

centos下设置服务器开机自启动 redis

在客户服务器中&#xff0c;服务器重启&#xff0c;发现 Redis 没有重启&#xff0c; 可以按照类似的步骤来创建自启动脚本&#xff0c;并将它添加到定时任务中。 解决办法&#xff1a; 1. 创建自启动脚本 进入服务器并创建脚本文件&#xff0c;例如 /usr/local/bin/redis_…

链表相交1

给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点&#xff0c;返回 null 。 思路 这一题我不认为很难&#xff0c;去吸收知识就行了&#xff0c;不要总是想着独创。 简单来说&#xff0c;就是求两个链表交点…

Excel 技巧17 - 如何计算倒计时,以及数据条(★)

本文讲如何计算倒计时&#xff0c;以及加数据条。 1&#xff0c;如何计算倒计时 这里也要用公式 D3 - TODAY() 显示为下面这个样子的 然后右键该单元格&#xff0c;选 设置单元格格式 然后点 常规 这样就能显示出还书倒计时的日数了。 下拉适用到其他单元格。 2&#xff0c;…

springboot整合modbus实现通讯

springboot整合modbus4j实现tcp通讯 前言 本文基于springboot和modbus4j进行简单封装&#xff0c;达到开箱即用的目的&#xff0c;目前本方案仅实现了tcp通讯。代码会放在最后&#xff0c;按照使用方法操作后就可以直接使用 介绍 在使用本方案之前&#xff0c;有必要对modb…

iOS-YModel

YModel 是一个高效的 iOS/OSX 的模型转换框架&#xff0c;可以轻松地将 JSON 转换成 Model&#xff0c;或者将 Model 转换成 JSON。以下是详细的使用指南&#xff1a; 导入 YYModel: 确保在你的项目中导入了 YYModel。使用 CocoaPods 的话可以在 Podfile 中加入以下代码&#…