Python代码-视频帧批处理工具v2025.03.14

import os
import threading
import tkinter as tk
from tkinter import filedialog, messagebox
from moviepy.video.io.VideoFileClip import VideoFileClip
from moviepy.config import change_settings
import customtkinter as ctk
import sys

def get_ffmpeg_path():
    """获取 ffmpeg 的路径"""
    # 获取当前运行的目录
    current_dir = os.path.dirname(sys.executable) if hasattr(sys, '_MEIPASS') else os.path.dirname(__file__)
    ffmpeg_path = os.path.join(current_dir, "ffmpeg.exe")

    # 检查 ffmpeg 文件是否存在
    if not os.path.exists(ffmpeg_path):
        raise FileNotFoundError(f"FFmpeg 文件不存在: {ffmpeg_path}")
    return ffmpeg_path

# 设置 ffmpeg 路径
change_settings({"FFMPEG_BINARY": get_ffmpeg_path()})

class VideoProcessorApp(ctk.CTk):
    def __init__(self):
        super().__init__()
        self.title("视频帧批处理工具v2025.03.14")
        self.geometry("550x800")

        # 初始化变量
        self.selected_files = []
        self.output_folder = ""
        self.suffix = "_processed"

        # 创建 UI
        self.create_widgets()

    def create_widgets(self):
        """创建界面组件"""
        self.video_label = ctk.CTkLabel(self, text="选择视频文件:", font=("Arial", 16))
        self.video_label.pack(pady=10)

        self.video_listbox = ctk.CTkTextbox(self, width=500, height=100, font=("Arial", 12))
        self.video_listbox.pack(pady=10)

        self.select_videos_button = ctk.CTkButton(self, text="添加视频文件", command=self.select_videos)
        self.select_videos_button.pack(pady=10)

        self.output_folder_label = ctk.CTkLabel(self, text="输出文件夹:", font=("Arial", 16))
        self.output_folder_label.pack(pady=10)

        self.output_folder_entry = ctk.CTkEntry(self, width=400, font=("Arial", 12))
        self.output_folder_entry.pack(pady=10)

        self.select_output_folder_button = ctk.CTkButton(self, text="选择文件夹", command=self.select_output_folder)
        self.select_output_folder_button.pack(pady=10)

        self.suffix_label = ctk.CTkLabel(self, text="添加后缀:", font=("Arial", 16))
        self.suffix_label.pack(pady=10)

        self.suffix_entry = ctk.CTkEntry(self, width=200, font=("Arial", 12))
        self.suffix_entry.insert(0, self.suffix)
        self.suffix_entry.pack(pady=10)

        self.progress_bar = ctk.CTkProgressBar(self, width=500)
        self.progress_bar.pack(pady=20)
        self.progress_bar.set(0)

        self.status_label = ctk.CTkLabel(self, text="状态:等待处理", font=("Arial", 14))
        self.status_label.pack(pady=10)

        self.output_textbox = ctk.CTkTextbox(self, width=500, height=100, font=("Arial", 12))
        self.output_textbox.pack(pady=10)

        self.start_button = ctk.CTkButton(self, text="开始处理", command=self.start_processing)
        self.start_button.pack(pady=10)

        self.exit_button = ctk.CTkButton(self, text="退出", command=self.quit)
        self.exit_button.pack(pady=10)

    def select_videos(self):
        file_paths = filedialog.askopenfilenames(
            title="选择视频文件",
            filetypes=[("视频文件", "*.mp4;*.avi;*.mov;*.mkv"), ("所有文件", "*.*")]
        )
        if file_paths:
            self.selected_files = file_paths
            self.video_listbox.delete("1.0", tk.END)
            for file in file_paths:
                self.video_listbox.insert(tk.END, file + "\n")

    def select_output_folder(self):
        folder_path = filedialog.askdirectory(title="选择输出文件夹")
        if folder_path:
            self.output_folder = folder_path
            self.output_folder_entry.delete(0, tk.END)
            self.output_folder_entry.insert(0, folder_path)

    def start_processing(self):
        if not self.selected_files:
            messagebox.showerror("错误", "请先选择视频文件!")
            return
        if not self.output_folder_entry.get():
            messagebox.showerror("错误", "请先选择输出文件夹!")
            return

        self.suffix = self.suffix_entry.get()
        self.output_folder = self.output_folder_entry.get()
        self.output_textbox.delete("1.0", tk.END)

        threading.Thread(target=self.process_videos).start()

    def process_videos(self):
        self.status_label.configure(text="正在处理视频...")
        self.progress_bar.set(0)

        for i, video_path in enumerate(self.selected_files):
            try:
                filename, ext = os.path.splitext(os.path.basename(video_path))
                output_filename = f"{filename}{self.suffix}{ext}"
                output_path = os.path.join(self.output_folder, output_filename)

                self.process_single_video(video_path, output_path)
                self.output_textbox.insert(tk.END, f"已完成: {output_path}\n")
            except Exception as e:
                self.output_textbox.insert(tk.END, f"处理失败: {video_path}\n错误: {str(e)}\n")

            progress = (i + 1) / len(self.selected_files)
            self.progress_bar.set(progress)
            self.status_label.configure(text=f"正在处理: {i + 1}/{len(self.selected_files)}")

        self.status_label.configure(text="所有视频处理完成!")
        self.output_textbox.insert(tk.END, "所有视频处理完成!\n")
        messagebox.showinfo("完成", "所有视频处理完成!")

    def process_single_video(self, input_path, output_path):
        try:
            video = VideoFileClip(input_path)
            self.output_textbox.insert(tk.END, f"成功加载视频: {input_path}\n")
        except Exception as e:
            self.output_textbox.insert(tk.END, f"加载失败: {input_path}\n错误: {str(e)}\n")
            return

        try:
            if video.duration < 2 / video.fps:
                self.output_textbox.insert(tk.END, f"视频时长过短,无法处理: {input_path}\n")
                return

            fps = video.fps
            duration = video.duration
            first_frame_time = 1 / fps
            last_frame_time = duration - (1 / fps)

            self.output_textbox.insert(tk.END, f"正在裁剪视频: {input_path}\n")
            processed_video = video.subclip(first_frame_time, last_frame_time)

            if processed_video is None:
                self.output_textbox.insert(tk.END, f"裁剪后的视频为空: {input_path}\n")
                return

            self.output_textbox.insert(tk.END, f"正在保存视频: {output_path}\n")
            processed_video.write_videofile(output_path, codec="libx264", audio_codec="aac")
            self.output_textbox.insert(tk.END, f"已完成: {output_path}\n")
        except Exception as e:
            self.output_textbox.insert(tk.END, f"处理失败: {input_path}\n错误: {str(e)}\n")


if __name__ == "__main__":
    app = VideoProcessorApp()
    app.mainloop()

Python代码-文件分类

import os
import shutil

def classify_images(source_folder):
    for filename in os.listdir(source_folder):
        if not filename.lower().endswith(('.jpg', '.jpeg', '.png')):
            continue

        base_name, ext = os.path.splitext(filename)
        last_underscore = base_name.rfind('_')
        if last_underscore == -1:
            print(f"跳过不符合格式的文件: {filename}")
            continue

        main_name = base_name[:last_underscore]
        sequence_number = base_name[last_underscore+1:]

        if not sequence_number.isdigit():
            print(f"跳过序号无效的文件: {filename}")
            continue

        target_folder = os.path.join(source_folder, main_name)
        if not os.path.exists(target_folder):
            os.makedirs(target_folder)
            print(f"创建文件夹: {target_folder}")

        source_path = os.path.join(source_folder, filename)
        target_path = os.path.join(target_folder, filename)
        shutil.move(source_path, target_path)
        print(f"已移动: {filename} -&gt; {target_folder}/")

if __name__ == "__main__":
    source_directory = r"C:\Users\Administrator\Desktop\迅捷视频转换器"  # ← 这是你给的路径
    classify_images(source_directory)
    print("分类完成!")
 

常用Windows镜像文件ED2K&BT

Windows 11 (business editions), version 24H2 (updated Feb 2025) (x64) - DVD (Chinese-Simplified)

ed2k://|file|zh-cn_windows_11_business_editions_version_24h2_updated_feb_2025_x64_dvd_115aa046.iso|6768605184|4C5E8917749DC7A8A93FF11832FB41BC|/
magnet:?xt=urn:btih:8d1f2818ddb49e7f8ac9b810290cea9e56ee3f3b&dn=zh-cn_windows_11_business_editions_version_24h2_updated_feb_2025_x64_dvd_115aa046.iso&xl=6768605184

Windows 11 (consumer editions), version 24H2 (updated Feb 2025) (x64) - DVD (Chinese-Simplified)

ed2k://|file|zh-cn_windows_11_consumer_editions_version_24h2_updated_feb_2025_x64_dvd_3733c10e.iso|6890164224|F17C3C3B426B588BC2A89DDCE7E6AF9C|/
magnet:?xt=urn:btih:cde29068a70ab3275bff4fdfcb7f5c85811641ac&dn=zh-cn_windows_11_consumer_editions_version_24h2_updated_feb_2025_x64_dvd_3733c10e.iso&xl=6890164224

Windows 11 Enterprise LTSC 2024 (x64) - DVD (Chinese-Simplified)

ed2k://|file|zh-cn_windows_11_enterprise_ltsc_2024_x64_dvd_cff9cd2d.iso|5287520256|D6E4FE0BA5FD8A2F22FC9C0326481791|/
magnet:?xt=urn:btih:b84e74c1dbcc88a02c5b24a6f84383f353a2e1dd&dn=zh-cn_windows_11_enterprise_ltsc_2024_x64_dvd_cff9cd2d.iso&xl=5287520256

Windows 10 (business editions), version 22H2 (updated Feb 2025) (x64) - DVD (Chinese-Simplified)

ed2k://|file|zh-cn_windows_10_business_editions_version_22h2_updated_feb_2025_x64_dvd_016e01fc.iso|7005589504|7C2732C85ECF091F1330E60F591B6F65|/
magnet:?xt=urn:btih:94e3836b63ef9f5abac47d99974a94a0e8976efd&dn=zh-cn_windows_10_business_editions_version_22h2_updated_feb_2025_x64_dvd_016e01fc.iso&xl=7005589504

Windows 10 (consumer editions), version 22H2 (updated Feb 2025) (x64) - DVD (Chinese-Simplified)

ed2k://|file|zh-cn_windows_10_consumer_editions_version_22h2_updated_feb_2025_x64_dvd_16fa7261.iso|7182641152|6FF10540756D6C3ABADBC75CE1E1F021|/
magnet:?xt=urn:btih:1d28086b6762c70f21b13b103d943595ea99b8c9&dn=zh-cn_windows_10_consumer_editions_version_22h2_updated_feb_2025_x64_dvd_16fa7261.iso&xl=7182641152

Windows 10 Enterprise LTSC 2021 (x64) - DVD (Chinese-Simplified)

ed2k://|file|SW_DVD9_WIN_ENT_LTSC_2021_64BIT_ChnSimp_MLF_X22-84402.ISO|5044211712|1555B7DCA052B5958EE68DB58A42408D|/
magnet:?xt=urn:btih:366ADAA52FB3639B17D73718DD5F9E3EE9477B40&dn=SW_DVD9_WIN_ENT_LTSC_2021_64BIT_ChnSimp_MLF_X22-84402.ISO&xl=5044211712

Windows Server 2025 (updated Feb 2025) (x64) - DVD (Chinese-Simplified)

ed2k://|file|zh-cn_windows_server_2025_updated_feb_2025_x64_dvd_3733c10e.iso|7930273792|A00322620D24664F050C59ACDB398AA1|/
magnet:?xt=urn:btih:c5712030fff4faa0783d37e1207121067d90af9b&dn=zh-cn_windows_server_2025_updated_feb_2025_x64_dvd_3733c10e.iso&xl=7930273792