吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 325|回复: 11
收起左侧

[资源求助] 有没有能把一个视频批量转化成gif动图的软件

[复制链接]
liangwenyu 发表于 2025-5-1 13:49
25吾爱币
如题,目前我能找到的只有选定一段时间转化的,或者是手动转化,实在太麻烦了 ,不知道有没有批量转化的工具(pc)

最佳答案

查看完整内容

按你的要求做了一份,可以先看看 https://wwph.lanzout.com/iGQ4G2v4dfxe 解压密码:52pojie

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
grrr_zhao + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

baishi123 发表于 2025-5-1 13:49
liangwenyu 发表于 2025-5-2 10:13
比如一个6分钟的视频我选择5秒后,他就产出压缩过的72个gif,或者我可以同时在一个视频里截取多段片段同 ...

按你的要求做了一份,可以先看看

https://wwph.lanzout.com/iGQ4G2v4dfxe
解压密码:52pojie

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
shuisanyue + 1 + 1 谢谢@Thanks!好软件……

查看全部评分

flyer_2001 发表于 2025-5-1 14:13
liunianwen 发表于 2025-5-1 15:14
没见过这种工具,市面上常见的都是批量转gif格式的工具,没见过将一个视频拆分为多个gif格式的工具,这种一般要定制软件吧
bgwu666 发表于 2025-5-1 18:47
可以具体描述一下需求吗?
baishi123 发表于 2025-5-1 20:14
可以详细说一下需求,可以按你的需求先做一个简陋的
bgwu666 发表于 2025-5-1 21:05
我用Python做了一个批量视频转换为GIF的工具,不知道功能是否契合,下面是源代码,如果不方便的话,这里提供一份打包成了exe程序的网盘链接:https://wwsv.lanzoul.com/iqqii2v1mc3c
[Python] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
import os
import tkinter
import moviepy
from tkinter import Tk
from tkinterdnd2 import TkinterDnD, DND_FILES
import threading
from tkinter.ttk import Progressbar
from tkinter import messagebox
from datetime import datetime
 
video_files = []
 
def convert_video_to_gif(input_video_path, segment_duration=5, fps=15, resolution=(640, 480), lock_aspect_ratio=True,
                         progress_callback=None, log_callback=None, stop_event=None):
    try:
        # 自动检测视频时长
        video = moviepy.VideoFileClip(input_video_path)
        video_duration = video.duration
        video_width, video_height = video.size  # 获取源视频的分辨率
 
        # 将源视频分辨率作为默认值
        default_resolution = (video_width, video_height)
 
        # 计算分段的起始时间和结束时间
        segments = []
        start_time = 0
        while start_time < video_duration:
            if stop_event and stop_event.is_set():
                log_callback("处理已停止")
                return
            end_time = min(start_time + segment_duration, video_duration)
            segments.append((start_time, end_time))
            start_time = end_time
 
        # 根据设置锁定宽高比
        if lock_aspect_ratio:
            aspect_ratio = video_width / video_height
            resolution = (resolution[0], int(resolution[0] / aspect_ratio))  # 根据宽度计算高度
 
        # 为每个段落生成GIF
        output_dir = "output_gifs"
        os.makedirs(output_dir, exist_ok=True)
 
        base_filename = os.path.splitext(os.path.basename(input_video_path))[0]
 
        total_segments = len(segments)
 
        for i, (start_time, end_time) in enumerate(segments):
            if stop_event and stop_event.is_set():
                log_callback("处理已停止")
                return
 
            log_msg = f"正在处理第 {i + 1} 个分段: {start_time} 秒到 {end_time} 秒"
            if log_callback:
                log_callback(log_msg)
 
            # 截取视频并调整分辨率和帧率
            segment_clip = video.subclipped(start_time, end_time)
            segment_clip = segment_clip.resized(new_size=resolution)
            segment_clip = segment_clip.with_fps(fps)
 
            # 自动生成输出文件名
            output_filename = f"{base_filename}_segment_{i + 1}_{int(start_time)}-{int(end_time)}.gif"
            output_path = os.path.join(output_dir, output_filename)
 
            # 将视频段保存为GIF
            segment_clip.write_gif(output_path)
            log_msg = f"GIF已保存为: {output_path}"
            if log_callback:
                log_callback(log_msg)
 
            # 更新进度条
            if progress_callback:
                progress_callback(i + 1, total_segments)
 
        log_msg = "转换完成!"
        if log_callback:
            log_callback(log_msg)
 
    except Exception as e:
        log_msg = f"处理视频 {input_video_path} 时出错: {e}"
        if log_callback:
            log_callback(log_msg)
 
 
def on_drop(event):
    # 获取拖放的文件路径
    global video_files
    video_files = event.data.split()
    # 获取第一个视频文件的分辨率并填充到输入框
    video_file = video_files[0]
    video = moviepy.VideoFileClip(video_file)
    video_width, video_height = video.size  # 获取源视频分辨率
 
    resolution_width.delete(0, tkinter.END)
    resolution_width.insert(tkinter.END, str(video_width))
    resolution_height.delete(0, tkinter.END)
    resolution_height.insert(tkinter.END, str(video_height))
 
    log_callback("视频文件已加载,请点击开始按钮进行转换")
 
 
def on_start_processing():
    stop_event.clear()  # 清除停止标志
    if not video_files:
        log_callback("请拖动视频文件到窗口中")
        return
 
    resolution_width_value = int(resolution_width.get())
    resolution_height_value = int(resolution_height.get())
    if resolution_width_value <= 0 or resolution_height_value <= 0:
        messagebox.showerror("输入错误", "分辨率必须大于零")
        return
 
    try:
        fps_value = int(fps_entry.get())
        if fps_value <= 0:
            raise ValueError("帧率必须大于零")
    except ValueError:
        messagebox.showerror("输入错误", "请输入有效的帧率值(整数)")
        return
 
    # 获取分段秒数
    try:
        segment_duration_value = int(segment_duration_entry.get())  # 获取分段秒数
        if segment_duration_value <= 0:
            raise ValueError("分段秒数必须大于零")
    except ValueError:
        messagebox.showerror("输入错误", "请输入有效的分段秒数(整数)")
        return
 
    # 获取是否保持宽高比
    lock_aspect_ratio = lock_aspect_ratio_var.get()
 
    # 初始化进度条
    progressbar["value"] = 0
 
    # 启动线程处理视频
    threading.Thread(target=process_videos,
                     args=(video_files, resolution_width_value, resolution_height_value, fps_value, lock_aspect_ratio,
                           segment_duration_value, stop_event)).start()
 
 
def process_videos(video_files, resolution_width, resolution_height, fps_value, lock_aspect_ratio, segment_duration_value, stop_event):
    for video_file in video_files:
        if stop_event.is_set():
            log_callback("处理已停止")
            break
        log_callback(f"开始处理视频: {video_file}")
        convert_video_to_gif(
            video_file,
            segment_duration=segment_duration_value,  # 使用用户输入的分段秒数
            fps=fps_value,
            resolution=(resolution_width, resolution_height),
            lock_aspect_ratio=lock_aspect_ratio,
            progress_callback=update_progress,
            log_callback=log_callback,
            stop_event=stop_event
        )
 
 
def update_progress(current, total):
    # 更新进度条
    progressbar["value"] = (current / total) * 100
    root.update_idletasks()
 
 
def log_callback(log_msg):
    # 将日志信息插入到Text控件
    log_text.config(state=tkinter.NORMAL)  # 允许修改Text控件
    log_text.insert(tkinter.END, log_msg + "\n")
    log_text.yview(tkinter.END)  # 滚动到最新内容
    log_text.config(state=tkinter.DISABLED)  # 禁止修改Text控件
 
 
def stop_processing():
    stop_event.set()  # 设置停止标志
 
 
# 创建TkinterDnD窗口并启用拖放功能
root = TkinterDnD.Tk()
root.title("批量视频转换为GIF")
root.geometry("600x600")
 
# 创建进度条
progressbar = Progressbar(root, orient="horizontal", length=300, mode="determinate")
progressbar.pack(padx=10, pady=10)
 
label = tkinter.Label(root, text="请拖动视频文件到这里", width=40, height=10)
label.pack(padx=10, pady=10)
 
# 创建分辨率和帧率的输入框
frame_controls = tkinter.Frame(root)
frame_controls.pack(padx=10, pady=10)
 
tkinter.Label(frame_controls, text="宽度:").grid(row=0, column=0)
resolution_width = tkinter.Entry(frame_controls)
resolution_width.grid(row=0, column=1)
 
tkinter.Label(frame_controls, text="高度:").grid(row=1, column=0)
resolution_height = tkinter.Entry(frame_controls)
resolution_height.grid(row=1, column=1)
 
lock_aspect_ratio_var = tkinter.IntVar(value=1# 默认选中保持比例
lock_aspect_ratio_check = tkinter.Checkbutton(frame_controls, text="保持宽高比", variable=lock_aspect_ratio_var)
lock_aspect_ratio_check.grid(row=2, column=0, columnspan=2)
 
tkinter.Label(frame_controls, text="帧率:").grid(row=3, column=0)
fps_entry = tkinter.Entry(frame_controls)
fps_entry.grid(row=3, column=1)
fps_entry.insert(tkinter.END, "15"# 默认帧率
 
tkinter.Label(frame_controls, text="分段秒数:").grid(row=4, column=0)
segment_duration_entry = tkinter.Entry(frame_controls)
segment_duration_entry.grid(row=4, column=1)
segment_duration_entry.insert(tkinter.END, "5"# 默认分段秒数为5秒
 
# 创建日志显示框
log_text = tkinter.Text(root, width=70, height=10)
log_text.pack(padx=10, pady=10)
log_text.config(state=tkinter.DISABLED)  # 禁止编辑
 
# 创建开始和停止按钮
button_frame = tkinter.Frame(root)
button_frame.pack(padx=10, pady=10)
 
start_button = tkinter.Button(button_frame, text="开始", command=on_start_processing)
start_button.grid(row=0, column=0, padx=5)
 
stop_button = tkinter.Button(button_frame, text="停止", command=stop_processing)
stop_button.grid(row=0, column=1, padx=5)
 
# 设置拖放事件
def on_drop_with_default_resolution(event):
    global video_files
    # 获取第一个文件路径并加载视频获取分辨率
    video_file = event.data.split()[0]
    video = moviepy.VideoFileClip(video_file)
    video_width, video_height = video.size  # 获取源视频分辨率
 
    # 将源视频的分辨率作为默认值
    resolution_width.delete(0, tkinter.END)
    resolution_width.insert(tkinter.END, str(video_width))
    resolution_height.delete(0, tkinter.END)
    resolution_height.insert(tkinter.END, str(video_height))
 
    # 将视频文件路径添加到 video_files 列表
    video_files.append(video_file)  # 修正:append 到列表
 
    # 更新日志显示
    log_callback("视频文件已加载,请点击开始按钮进行转换")
 
 
# 创建停止事件
stop_event = threading.Event()
 
root.drop_target_register(DND_FILES)
root.dnd_bind('<<Drop>>', on_drop_with_default_resolution)
 
# 启动Tkinter事件循环
root.mainloop()
 楼主| liangwenyu 发表于 2025-5-2 10:12
bgwu666 发表于 2025-5-1 18:47
可以具体描述一下需求吗?

比如一个6分钟的视频我选择5秒后,他就产出压缩过的72个gif,或者我可以同时在一个视频里截取多段片段同时生成gif
 楼主| liangwenyu 发表于 2025-5-2 10:13
baishi123 发表于 2025-5-1 20:14
可以详细说一下需求,可以按你的需求先做一个简陋的

比如一个6分钟的视频我选择5秒后,他就产出压缩过的72个gif,或者我可以同时在一个视频里截取多段片段同时生成gif
 楼主| liangwenyu 发表于 2025-5-2 23:25
baishi123 发表于 2025-5-2 17:52
按你的要求做了一份,可以先看看

https://wwph.lanzout.com/iGQ4G2v4dfxe

我去大佬牛逼
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-5-23 06:42

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表