import tkinter as tk
|
from tkinter import filedialog, messagebox, ttk, Canvas,PhotoImage
|
import os
|
import numpy as np
|
from PIL import Image, ImageTk
|
import vlc
|
import subprocess
|
import functools
|
import cv2
|
import threading
|
from multiprocessing import Pool
|
import time
|
from threading import Thread
|
from queue import Queue
|
|
class LoopVlcPlayer:
|
def __init__(self, canvas):
|
self.player = vlc.Instance()
|
self.canvas = canvas
|
|
# 创建媒体列表播放器和媒体播放器
|
self.listPlayer = self.player.media_list_player_new()
|
self.media_player = self.player.media_player_new()
|
|
# 绑定 media_player 到 Canvas
|
self.media_player.set_hwnd(self.canvas.winfo_id()) # For Windows
|
# 如果运行在 MacOS 或 Linux,请根据平台替换绑定方法:
|
# MacOS: self.media_player.set_nsobject(self.canvas.winfo_id())
|
# Linux: self.media_player.set_xwindow(self.canvas.winfo_id())
|
self.listPlayer.set_media_player(self.media_player)
|
|
def addPlaylist(self, local_path):
|
if not os.path.exists(local_path):
|
raise FileNotFoundError(f"The file {local_path} does not exist.")
|
|
self.media_list = self.player.media_list_new()
|
self.media_list.add_media(local_path)
|
self.listPlayer.set_media_list(self.media_list)
|
self.listPlayer.set_playback_mode(vlc.PlaybackMode.loop)
|
|
self.play()
|
|
def play(self):
|
# 启动播放
|
if self.media_list is None:
|
raise ValueError("No media added to the playlist. Use add_playlist() first.")
|
self.listPlayer.play()
|
|
def stop(self):
|
# 停止播放
|
self.listPlayer.stop()
|
|
def removePlaylist(self):
|
"""
|
停止播放并释放媒体列表资源,允许文件在硬件上被其他程序删除。
|
"""
|
if self.media_list:
|
self.stop()
|
self.media_list.release()
|
self.media_list = None # 释放引用以确保清理生效
|
print("Playlist removed and resources released.")
|
|
|
# Global variables
|
video_files = [] # List of video files
|
current_video_idx = 0 # Index of the current video
|
current_video_path = ""
|
video_player = None
|
thumbnail_images = []
|
split_info = []
|
|
# Create the main window
|
root = tk.Tk()
|
root.title("简易视频拆解工具 0.1")
|
root.state('zoomed') # Fullscreen
|
|
screen_width = root.winfo_screenwidth()
|
screen_height = root.winfo_screenheight()
|
|
|
# Video playing frame
|
video_frame = tk.Frame(root, width=1080, height=1920)
|
video_frame.pack(side=tk.LEFT, padx=0)
|
|
# Frame for thumbnail images
|
thumbnail_frame = tk.Frame(root, width=1080, height=1920)
|
thumbnail_frame.pack_forget()
|
|
# Frame for right-side info and buttons
|
control_frame = tk.Frame(root, width=60, height=200, bg="lightblue")
|
control_frame.pack(side=tk.RIGHT, anchor="ne", padx=5, pady=5)
|
|
|
|
selected_labels = [] # 记录当前选中的标签
|
file_frames = []
|
file_fps = 0
|
file_frame_count = 0
|
file_width =0
|
file_height = 0
|
|
def display_thumbnails(video_file):
|
global selected_labels,file_frames,file_fps,file_frame_count,file_width,file_height
|
selected_labels = []
|
file_frames = []
|
file_fps = 0
|
file_frame_count = 0
|
file_width = 0
|
file_height =0
|
|
row, col = 0, 0
|
max_col = (screen_width - 100) // 90 - 1 # 动态地
|
|
# 创建Canvas和垂直滚动条
|
thumbnail_frame.pack(side=tk.LEFT, padx=0)
|
|
canvas = tk.Canvas(thumbnail_frame, width=screen_width - 100, height=screen_height)
|
canvas.grid(row=0, column=0, sticky='nsew')
|
|
scrollbar = ttk.Scrollbar(thumbnail_frame, orient="vertical", command=canvas.yview)
|
scrollbar.grid(row=0, column=1, sticky='ns')
|
|
canvas.configure(yscrollcommand=scrollbar.set)
|
|
# 创建一个frame作为Canvas的子项来添加缩略图
|
thumbnail_container = tk.Frame(canvas)
|
canvas.create_window((0, 0), window=thumbnail_container, anchor="nw")
|
|
# 启用鼠标滚轮事件来滚动Canvas
|
def on_mouse_wheel(event):
|
"""处理鼠标滚轮事件"""
|
canvas.yview_scroll(int(-1 * (event.delta / 120)), "units")
|
|
# 绑定鼠标滚轮事件
|
canvas.bind_all("<MouseWheel>", on_mouse_wheel)
|
|
"""
|
读取 MP4 视频并将每一帧存储到内存中
|
"""
|
def convert_cv_to_tk_image(cv_image):
|
"""
|
将 OpenCV 图像转换为 Tkinter 可用的图像格式
|
"""
|
pil_image = Image.fromarray(cv2.cvtColor(cv_image, cv2.COLOR_BGR2RGB))
|
# 转换为Tkinter可用的PhotoImage格式
|
return ImageTk.PhotoImage(pil_image)
|
|
def get_thumbnail_width_height(width,height,max_size=120):
|
scale = min(max_size / height, max_size / width)
|
return int(width * scale),int(height * scale)
|
|
def add_label_to_contanier(idx,thumb,row,col):
|
thumb_label = tk.Label(thumbnail_container, image=thumb)
|
thumb_label.image = thumb # 必须保持对图像的引用
|
thumb_label.grid(row=row, column=col, padx=1, pady=1)
|
|
# 将toggle_checkmark的调用用 functools.partial包装,传递idx
|
thumb_label.bind("<Button-1>", functools.partial(toggle_checkmark, label=thumb_label, idx=idx))
|
|
checkmark_label = None
|
if idx == 0: # 默认第一个图片加对号
|
checkmark_label = add_checkmark_icon(thumb_label)
|
selected_labels.append(idx)
|
# 将checkmark_label保存在标签中,后续点击时可以参考
|
thumb_label.checkmark_label = checkmark_label
|
thumbnail_container.update()
|
thumbnail_container.update_idletasks()
|
|
cap = cv2.VideoCapture(video_file)
|
file_frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
|
file_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
file_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
thumbnail_width,thumbnail_height = get_thumbnail_width_height(file_width,file_height)
|
file_fps = cap.get(cv2.CAP_PROP_FPS)
|
frame_idx = 0
|
while True:
|
ret, frame = cap.read()
|
if not ret:
|
break
|
file_frames.append(frame)
|
add_label_to_contanier(frame_idx,convert_cv_to_tk_image(cv2.resize(frame, (thumbnail_width, thumbnail_height))),row,col)
|
frame_idx +=1
|
col += 1
|
if col >= max_col:
|
col = 0
|
row += 1
|
|
cap.release()
|
# 更新Canvas的滚动区域
|
thumbnail_container.update_idletasks()
|
canvas.config(scrollregion=canvas.bbox("all"))
|
|
def toggle_checkmark(event, label, idx):
|
"""切换勾选状态"""
|
checkmark_label = label.checkmark_label
|
# 如果已经有勾选图标,移除它;如果没有,添加它
|
if checkmark_label:
|
# 移除勾选图标
|
if idx == 0 :
|
return
|
checkmark_label.destroy()
|
label.checkmark_label = None
|
# 从选中的标签列表中移除
|
if idx in selected_labels:
|
selected_labels.remove(idx)
|
else:
|
# 添加勾选图标
|
if idx ==file_frame_count-1:
|
return
|
checkmark_label = add_checkmark_icon(label)
|
label.checkmark_label = checkmark_label
|
selected_labels.append(idx)
|
|
#print(selected_labels)
|
|
|
def add_checkmark_icon(thumb_label):
|
"""在图像上添加勾选图标"""
|
checkmark = Image.open("checkmark.png") # 假设你有一个勾选图标
|
checkmark = checkmark.resize((30, 30)) # 调整图标大小
|
checkmark_photo = ImageTk.PhotoImage(checkmark)
|
|
# 创建一个标签来放置勾选图标
|
checkmark_label = tk.Label(thumb_label, image=checkmark_photo, bg='white', width=30, height=30)
|
checkmark_label.image = checkmark_photo # 保持图标的引用
|
# 将勾选图标放在缩略图右上角
|
checkmark_label.place(x=80, y=5, anchor="ne") # 确保图标位置在右上角
|
|
return checkmark_label
|
|
|
def show_large_image(image):
|
# 创建一个新的窗口来显示大图
|
top = tk.Toplevel(root)
|
top.title("Large Image")
|
|
# 使用 PIL 创建 Image 对象
|
image_pil = Image.fromarray(image)
|
image_tk = ImageTk.PhotoImage(image_pil)
|
|
# 在新窗口中显示图片
|
label = tk.Label(top, image=image_tk)
|
label.image = image_tk # 保持对图片的引用
|
label.pack()
|
# 跳转到指定进度
|
|
|
def on_progress_change(event):
|
global loopPlayer
|
total_time = loopPlayer.media_player.get_length() / 1000 # 视频总时长(秒)
|
new_time = (event.x / progress_bar.winfo_width()) * total_time # 计算新的时间
|
loopPlayer.media_player.set_time(int(new_time * 1000)) # 设置新时间(毫秒)
|
|
|
|
def use_video():
|
loopPlayer.stop()
|
video_frame.pack_forget()
|
display_thumbnails(current_video_path)
|
|
|
def toggle_play_pause():
|
global loopPlayer
|
if loopPlayer.listPlayer.is_playing():
|
loopPlayer.listPlayer.pause() # 暂停播放
|
play_pause_button.config(text="播放视频") # 更新按钮文本为播放
|
else:
|
loopPlayer.listPlayer.play() # 播放
|
play_pause_button.config(text="暂停视频") # 更新按钮文本为暂停
|
|
# 更新进度条并增加调试信息
|
|
|
def update_progress():
|
# 确保播放器正在播放
|
global loopPlayer
|
if loopPlayer.media_player.is_playing():
|
current_time = loopPlayer.media_player.get_time() / 1000 # 毫秒转为秒
|
total_time = loopPlayer.media_player.get_length() / 1000 # 毫秒转为秒
|
if total_time > 0:
|
progress_percentage = (current_time / total_time) * 100
|
progress_var.set(progress_percentage)
|
progress_bar.after(10, update_progress)
|
else:
|
progress_bar.after(10, update_progress)
|
|
|
# 视频进度条
|
progress_var = tk.DoubleVar()
|
progress_bar = ttk.Scale(video_frame, variable=progress_var,
|
from_=0, to=100, orient="horizontal", length=800)
|
progress_bar.pack(side=tk.TOP, pady=10)
|
|
canvas = Canvas(video_frame, width=1080, height=1920) # 设置Canvas大小
|
canvas.pack(side=tk.TOP) # Video player area under progress bar
|
|
loopPlayer = LoopVlcPlayer(canvas)
|
|
|
|
|
# 绑定进度条点击事件,跳转到指定时间
|
progress_bar.bind("<ButtonRelease-1>", on_progress_change)
|
|
update_progress()
|
# 设置主窗口
|
# Functions
|
|
output_dir = ""
|
main_folder = ""
|
|
def open_folder():
|
global output_dir,main_folder
|
"""Open folder and get all MP4 files"""
|
main_folder = filedialog.askdirectory()
|
if not main_folder:
|
return
|
|
global video_files
|
video_files = []
|
for root_dir, dirs, files in os.walk(main_folder):
|
for file in files:
|
if file.lower().endswith(".mp4"):
|
video_files.append(os.path.join(root_dir, file))
|
|
if video_files:
|
messagebox.showinfo("Info", f"文件数量:{len(video_files)}")
|
|
root.title("文件夹:"+main_folder+ ",文件数量:"+str(len(video_files)))
|
root.update() # 刷新界面
|
load_video(video_files[0])
|
|
output_dir = os.path.join(main_folder, "ProcessResults")
|
create_folders(output_dir)
|
else:
|
messagebox.showerror("Error", "没有找到MP4文件")
|
|
|
def load_video(video_path):
|
global loopPlayer
|
"""Load video into the player and start playback"""
|
global current_video_path, video_player
|
update_title_add_file_path(video_path)
|
current_video_path = video_path
|
thumbnail_frame.pack_forget()
|
video_frame.pack(side=tk.LEFT, padx=0)
|
loopPlayer.addPlaylist(current_video_path)
|
loopPlayer.play()
|
|
|
|
def delete_video():
|
"""Delete current video and play the next"""
|
global current_video_idx
|
loopPlayer.removePlaylist()
|
update_title_minus_one()
|
if current_video_idx < len(video_files):
|
os.remove(video_files[current_video_idx])
|
current_video_idx += 1
|
if current_video_idx < len(video_files):
|
load_video(video_files[current_video_idx])
|
else:
|
messagebox.showinfo("Info", "处理完毕!")
|
|
|
|
def save_video_slice(fps,width,height,frames_to_save, output_file):
|
"""
|
根据指定的帧范围将视频保存为新的片段
|
"""
|
fourcc = cv2.VideoWriter_fourcc(*'mp4v') # 用于生成 MP4 格式
|
#cv2.VideoWriter_fourcc(*'H264')
|
#cv2.VideoWriter_fourcc(*'avc1')
|
#cv2.VideoWriter_fourcc(*'mp4v')
|
out = cv2.VideoWriter(output_file, fourcc, fps, (width, height))
|
|
# 遍历指定范围的帧并写入到新视频中
|
for frame in frames_to_save:
|
out.write(frame)
|
out.release()
|
|
def save_slice_in_thread(fps, width, height, frames, output_file):
|
save_video_slice(fps, width, height, frames, output_file)
|
|
|
def process_video_slices(save_hook,output_dir,file_basename):
|
"""
|
并发处理多个视频切片并写入文件。
|
|
参数:
|
- frames: 已加载的所有视频帧
|
- slice_ranges: 每个切片的帧范围 [(start1, end1), (start2, end2), ...]
|
- output_dir: 输出视频切片保存的目录
|
- fps: 帧率
|
- width: 视频宽度
|
- height: 视频高度
|
"""
|
global file_frame_count,file_fps,file_width,file_height,selected_labels,file_frames
|
|
def convert_to_ranges(frame_segments, total_frames):
|
ranges = []
|
for i in range(len(frame_segments) - 1):
|
start_frame = frame_segments[i]
|
end_frame = frame_segments[i + 1] - 1 # 不包含end_frame
|
ranges.append([start_frame, end_frame])
|
|
# 处理最后一段
|
last_start_frame = frame_segments[-1]
|
ranges.append([last_start_frame, total_frames]) # 最后一段直到视频结束
|
return ranges
|
|
slice_ranges = convert_to_ranges(selected_labels,file_frame_count)
|
|
threads = []
|
for i, slice_range in enumerate(slice_ranges):
|
# 设置输出路径
|
if save_hook and i == 0:
|
output_file = os.path.join(os.path.join(output_dir, "hook"), f"{file_basename}.mp4")
|
else:
|
output_file = os.path.join(os.path.join(output_dir, "slice"), f"{file_basename}_{i + 1}.mp4")
|
|
slice_frames = file_frames[slice_range[0]:slice_range[1]]
|
t = threading.Thread(target=save_slice_in_thread, args=(file_fps, file_width, file_height, slice_frames, output_file))
|
threads.append(t)
|
t.start()
|
|
# 可选:等待所有线程完成
|
#for t in threads:
|
# t.join()
|
|
|
|
|
|
# 创建线程池
|
'''
|
with ThreadPoolExecutor() as executor:
|
futures = []
|
for i, slice_range in enumerate(slice_ranges):
|
# 设置输出路径
|
if save_hook and i == 0:
|
output_file = os.path.join(os.path.join(output_dir, "hook"), f"{file_basename}_{i + 1}.mp4")
|
else:
|
output_file = os.path.join(os.path.join(output_dir, "slice"), f"{file_basename}_{i + 1}.mp4")
|
|
# 提交任务到线程池
|
futures.append(executor.submit(save_video_slice, slice_range, output_file))
|
|
# 等待所有任务完成
|
for future in futures:
|
future.result() # 获取结果(如有异常会在这里抛出)
|
'''
|
'''
|
for i, slice_range in enumerate(slice_ranges):
|
if save_hook and i==0:
|
output_file = os.path.join(os.path.join(output_dir,"hook"), f"{file_basename}_{i+1}.mp4")
|
else:
|
output_file = os.path.join(os.path.join(output_dir,"slice"), f"{file_basename}_{i+1}.mp4")
|
save_video_slice(file_fps, file_width, file_height,file_frames[slice_range[0]:slice_range[1]], output_file)
|
'''
|
|
|
|
def split_video():
|
"""Delete current video and play the next"""
|
global current_video_idx
|
print(selected_labels)
|
update_title_minus_one()
|
if current_video_idx < len(video_files):
|
target_file = video_files[current_video_idx]
|
|
save_hook_= save_hook.get() == 1
|
save_music_= save_music.get() == 1
|
save_music_without_hook_ = save_music_without_hook.get() == 1
|
|
cut_video_by_frames(save_hook_,save_music_,save_music_without_hook_,target_file,selected_labels,file_frame_count,output_dir)
|
|
current_video_idx += 1
|
if current_video_idx < len(video_files):
|
load_video(video_files[current_video_idx])
|
else:
|
messagebox.showinfo("Info", "处理完成!")
|
thumbnail_frame.pack_forget()
|
|
def even_split_video():
|
"""Delete current video and play the next"""
|
global current_video_idx,file_frame_count,output_dir
|
loopPlayer.stop()
|
update_title_minus_one()
|
if current_video_idx < len(video_files):
|
target_file = video_files[current_video_idx]
|
|
even_split_count_= scale_progress_var.get()
|
scale_save_music_ = scale_save_music.get() == 1
|
|
even_cut_video_by_frames(even_split_count_,scale_save_music_,target_file,output_dir)
|
|
current_video_idx += 1
|
if current_video_idx < len(video_files):
|
load_video(video_files[current_video_idx])
|
else:
|
messagebox.showinfo("Info", "处理完成!")
|
thumbnail_frame.pack_forget()
|
|
|
|
def update_title_minus_one():
|
root.title("文件夹:"+main_folder+ ",文件数量:"+str(len(video_files)-current_video_idx))
|
root.update()
|
|
def update_title_add_file_path(file_path):
|
root.title("文件夹:"+main_folder+ ",文件数量:<"+str(len(video_files)-current_video_idx)+">."+file_path)
|
root.update()
|
|
def get_filename_without_extension(video_path):
|
# 获取文件名,去除路径
|
filename_with_extension = os.path.basename(video_path)
|
# 去除扩展名
|
filename_without_extension = os.path.splitext(filename_with_extension)[0]
|
return filename_without_extension
|
|
def even_cut_video_by_frames(even_split_count_,scale_save_music_,video_path,output_dir):
|
"""
|
将视频按照固定间隔进行平均切割。
|
- output_dir: 输出视频文件的目录
|
"""
|
global file_fps,file_frame_count,file_frames,file_width,file_height
|
|
def split_video_into_slices(total_count, split_count_):
|
# 如果视频帧数小于等于分片数,则不拆分
|
if total_count <= split_count_:
|
return [(0, total_count)] # 返回一个包含整个视频的切片
|
# 计算需要的切片数量
|
slice_count = total_count // split_count_ # 基本的切片数量
|
remaining_frames = total_count % split_count_ # 剩余的帧数
|
|
slices = []
|
# 创建每个切片
|
for i in range(int(slice_count)):
|
start_frame = int(i * split_count_)
|
end_frame = int((i + 1) * split_count_)
|
slices.append((start_frame, end_frame))
|
# 如果有剩余的帧,将其作为最后一个切片
|
if remaining_frames > 0:
|
slices.append((int(slice_count * split_count_), int(slice_count * split_count_ + remaining_frames)))
|
return slices
|
|
if file_frame_count ==0 :
|
cap = cv2.VideoCapture(video_path)
|
file_frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
|
file_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
file_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
file_fps = cap.get(cv2.CAP_PROP_FPS)
|
while True:
|
ret, frame = cap.read()
|
if not ret:
|
break
|
file_frames.append(frame)
|
cap.release()
|
|
file_name_witout_extension = get_filename_without_extension(video_path)
|
if scale_save_music_:
|
output_file = os.path.join(os.path.join(output_dir,"music"), f"{file_name_witout_extension}.wav")
|
command = ["ffmpeg", "-i", video_path, "-vn", "-acodec", "pcm_s16le","-ar", "44100","-ac", "2", output_file]
|
print(" ".join(command))
|
subprocess.Popen(command)
|
|
slice_ranges = split_video_into_slices(file_frame_count,even_split_count_)
|
print("even_slice_ranges")
|
print(slice_ranges)
|
|
threads = []
|
for i, slice_range in enumerate(slice_ranges):
|
output_file = os.path.join(os.path.join(output_dir, "slice"), f"{file_name_witout_extension}_{i + 1}.mp4")
|
slice_frames = file_frames[slice_range[0]:slice_range[1]]
|
t = threading.Thread(target=save_slice_in_thread, args=(file_fps, file_width, file_height, slice_frames, output_file))
|
threads.append(t)
|
t.start()
|
|
# 可选:等待所有线程完成
|
#for t in threads:
|
# t.join()
|
|
|
def cut_video_by_frames(save_hook,save_music,save_music_without_hook,video_path, frame_segments, total_frames, output_dir):
|
"""
|
将视频按照指定的帧切片进行切割。
|
|
参数:
|
- video_path: 输入视频的路径
|
- frame_segments: 切片的帧序号数组,例如:[0, M1, M2, ..., Mlast]
|
- output_dir: 输出视频文件的目录
|
"""
|
global file_fps
|
frame_segments.sort()
|
file_name_witout_extension = get_filename_without_extension(video_path)
|
|
if save_music:
|
output_file = os.path.join(os.path.join(output_dir,"music"), f"{file_name_witout_extension}.wav")
|
if save_music_without_hook:
|
music_start_time = float(frame_segments[1]) / file_fps
|
command = ["ffmpeg", "-i", video_path, "-ss", str(music_start_time), "-vn", "-acodec", "pcm_s16le","-ar", "44100","-ac", "2", output_file]
|
print(" ".join(command))
|
else:
|
command = ["ffmpeg", "-i", video_path, "-vn", "-acodec", "pcm_s16le","-ar", "44100","-ac", "2", output_file]
|
print(" ".join(command))
|
subprocess.Popen(command)
|
if save_hook:
|
output_file = os.path.join(os.path.join(output_dir,"hook"), f"{file_name_witout_extension}.wav")
|
music_start_time = float(frame_segments[1]) / file_fps
|
command = ["ffmpeg", "-i", video_path, "-t", str(music_start_time), "-vn", "-acodec", "pcm_s16le", "-ar", "44100", "-ac", "2", output_file]
|
print(" ".join(command))
|
subprocess.Popen(command)
|
|
process_video_slices(save_hook,output_dir,file_name_witout_extension)
|
|
|
|
|
def create_folders(base_folder):
|
"""Create a folder structure for saving results"""
|
hook_folder = os.path.join(base_folder, "hook")
|
music_folder = os.path.join(base_folder, "music")
|
category_folder = os.path.join(base_folder, "slice")
|
|
if not os.path.exists(hook_folder):
|
os.makedirs(hook_folder)
|
if not os.path.exists(music_folder):
|
os.makedirs(music_folder)
|
if not os.path.exists(category_folder):
|
os.makedirs(category_folder)
|
|
|
# Buttons
|
open_folder_button = tk.Button(control_frame, text="打开文件夹", command=open_folder,width=30)
|
open_folder_button.pack(pady=5)
|
|
# 播放控制按钮(播放/暂停)
|
play_pause_button = tk.Button(control_frame, text="暂停视频", command=toggle_play_pause,width=30)
|
play_pause_button.pack(pady=30)
|
|
|
delete_button = tk.Button(control_frame, text="保留", command=use_video,width=30,bg="green")
|
delete_button.pack(pady=10)
|
|
delete_button = tk.Button(control_frame, text="不保留", command=delete_video,width=30,bg="red")
|
delete_button.pack()
|
|
save_hook = tk.IntVar(value=1) # 默认勾选
|
save_music = tk.IntVar(value=1) # 默认勾选
|
save_music_without_hook = tk.IntVar(value=1)
|
|
# 创建两个 Checkbutton
|
checkbox1 = tk.Checkbutton(control_frame, text="保存Hook视频", variable=save_hook,width=30)
|
checkbox1.pack(pady=30)
|
|
checkbox2 = tk.Checkbutton(control_frame, text="保存音频", variable=save_music,width=30)
|
checkbox2.pack()
|
|
checkbox3 = tk.Checkbutton(control_frame, text="音频(除hook音频)", variable=save_music_without_hook,width=30)
|
checkbox3.pack()
|
|
|
delete_button = tk.Button(control_frame, text="画面拆分", command=split_video,width=30)
|
delete_button.pack(pady=50)
|
|
|
def _on_scale_progress_change(value):
|
# 限制进度条的值为10、20、30、40、50
|
rounded_value = round(float(value) / 5) * 5
|
scale_progress_var.set(rounded_value) # 设置回进度条
|
scale_progress_var = tk.DoubleVar()
|
scale_progress_bar = tk.Scale(control_frame, variable=scale_progress_var, from_=10, to=50, orient="horizontal", length=300,
|
tickinterval=10, showvalue=True, sliderlength=30)
|
scale_progress_bar.pack(pady=30)
|
scale_progress_bar.set(20)
|
|
scale_save_music = tk.IntVar(value=1) # 默认勾选
|
checkbox4 = tk.Checkbutton(control_frame, text="保存音频", variable=scale_save_music,width=30)
|
checkbox4.pack(pady=5)
|
|
even_split_button = tk.Button(control_frame, text="平均拆分", command=even_split_video,width=30)
|
even_split_button.pack(pady=5)
|
|
|
'''
|
menu_bar = tk.Menu(root)
|
file_menu = tk.Menu(menu_bar, tearoff=0)
|
file_menu.add_command(label="打开文件夹", command=open_folder)
|
menu_bar.add_cascade(label="文件", menu=file_menu)
|
root.config(menu=menu_bar)
|
'''
|
|
root.mainloop()
|