From 4c5a1f2f09f6906bf26a783d2fa345a5886a2335 Mon Sep 17 00:00:00 2001
From: wangzhibo <wangzhibo@shsening.com>
Date: 星期三, 04 十二月 2024 09:49:30 +0800
Subject: [PATCH] modified split using cv2

---
 __pycache__/cv2.cpython-310.pyc |    0 
 test/t_ffmpeg.py                |    3 
 test/pipe_test.py               |   60 +
 pipe_sample.txt                 |    1 
 test/pygame_test.py             |  107 ++
 test/sence_detect_demo.py       |   70 +
 test/tk.py                      |   77 +
 video-splitor.py                |  694 +++++++++++++++++
 videosplitorV0.1.spec           |   42 
 test/refresh.py                 |   24 
 test/pi.py                      |   70 +
 README.md                       |   26 
 VLC.zip                         |    0 
 /dev/null                       |  467 -----------
 test/pipe_test copy.py          |   71 +
 test/ffmpeg_read_cv2_write.py   |   74 +
 cv2_player.py                   |  114 ++
 test/scene_detect_demo.py       |   69 +
 test/t_ssim.py                  |   66 +
 test/ffplay_test.py             |   94 ++
 test/vlc_test.py                |  106 ++
 test/loop.py                    |   33 
 test/test_cv.py                 |   94 ++
 23 files changed, 1,866 insertions(+), 496 deletions(-)

diff --git a/README.md b/README.md
index 490c1c2..8b33d20 100644
--- a/README.md
+++ b/README.md
@@ -21,4 +21,28 @@
 
 鎵撳寘 exe
 
-1銆乸yinstaller videosplitorV0.1.spec
\ No newline at end of file
+1銆乸yinstaller videosplitorV0.1.spec
+
+
+
+
+PS. 娣诲姞鏈湴鏂囦欢澶瑰埌杩滅▼ git server锛�
+
+1. 鍒濆鍖栨湰鍦� Git 浠撳簱
+cd /path/to/your/folder
+git init
+
+2. 娣诲姞鏂囦欢鍒� Git 浠撳簱
+git add .
+
+3. 鎻愪氦鏂囦欢鍒版湰鍦� Git 浠撳簱
+git commit -m "Initial commit"
+
+4. 杩炴帴鍒拌繙绋� Git 浠撳簱
+git remote add origin ssh://wangzhibo@192.168.0.75:29418/Python_Video_Splitor.git
+
+5. 鎺ㄩ�佹湰鍦颁唬鐮佸埌杩滅▼浠撳簱
+git push -u origin master
+
+6. 楠岃瘉鎺ㄩ�佺粨鏋�
+git remote -v
diff --git a/VLC.zip b/VLC.zip
new file mode 100644
index 0000000..d1978eb
--- /dev/null
+++ b/VLC.zip
Binary files differ
diff --git a/__pycache__/cv2.cpython-310.pyc b/__pycache__/cv2.cpython-310.pyc
new file mode 100644
index 0000000..b2b9eff
--- /dev/null
+++ b/__pycache__/cv2.cpython-310.pyc
Binary files differ
diff --git a/build.bat b/build.bat
deleted file mode 100644
index 646ce91..0000000
--- a/build.bat
+++ /dev/null
@@ -1 +0,0 @@
-pyinstaller --name=瑙嗛鍒嗘V0.1 --clean --onefile -y tkv.py --icon ./main.ico
\ No newline at end of file
diff --git a/cv2_player.py b/cv2_player.py
new file mode 100644
index 0000000..a74fdee
--- /dev/null
+++ b/cv2_player.py
@@ -0,0 +1,114 @@
+import cv2
+import tkinter as tk
+from tkinter import filedialog, ttk
+from PIL import Image, ImageTk
+
+
+class VideoPlayer:
+    def __init__(self, root):
+        self.root = root
+        self.root.title("Tkinter MP4 鎾斁鍣�")
+
+        # 瑙嗛鎺т欢
+        self.video_label = tk.Label(root)
+        self.video_label.pack()
+
+        # 鎸夐挳鍜岃繘搴︽潯鍖哄煙
+        controls_frame = tk.Frame(root)
+        controls_frame.pack()
+
+        self.play_button = tk.Button(controls_frame, text="鎾斁", command=self.toggle_play_pause)
+        self.play_button.grid(row=0, column=0, padx=5)
+
+        self.replay_button = tk.Button(controls_frame, text="閲嶆柊鎾斁", command=self.replay_video)
+        self.replay_button.grid(row=0, column=1, padx=5)
+
+        self.progress = ttk.Scale(controls_frame, from_=0, to=1, orient="horizontal", command=self.seek_video)
+        self.progress.grid(row=0, column=2, padx=5, sticky="ew")
+
+        controls_frame.columnconfigure(2, weight=1)
+
+        # 鐘舵�佸彉閲�
+        self.cap = None
+        self.is_playing = False
+        self.current_frame = 0
+        self.total_frames = 0
+        self.fps = 30
+        self.video_path = None
+
+        # 鏂囦欢鎵撳紑鎸夐挳
+        self.open_button = tk.Button(root, text="鎵撳紑瑙嗛", command=self.open_file)
+        self.open_button.pack()
+
+    def open_file(self):
+        self.video_path = filedialog.askopenfilename(filetypes=[("MP4鏂囦欢", "*.mp4"), ("鎵�鏈夋枃浠�", "*.*")])
+        if not self.video_path:
+            return
+        self.load_video()
+
+    def load_video(self):
+        if self.cap:
+            self.cap.release()
+        self.cap = cv2.VideoCapture(self.video_path)
+        if not self.cap.isOpened():
+            tk.messagebox.showerror("閿欒", "鏃犳硶鎵撳紑瑙嗛")
+            return
+        self.fps = int(self.cap.get(cv2.CAP_PROP_FPS))
+        self.total_frames = int(self.cap.get(cv2.CAP_PROP_FRAME_COUNT))
+        self.current_frame = 0
+        self.progress.config(to=self.total_frames)
+        self.is_playing = True
+        self.play_button.config(text="鏆傚仠")
+        self.play_video()
+
+    def play_video(self):
+        if not self.is_playing or not self.cap:
+            return
+
+        ret, frame = self.cap.read()
+        if ret:
+            self.current_frame += 1
+            self.progress.set(self.current_frame)
+            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
+            img = ImageTk.PhotoImage(Image.fromarray(frame))
+            self.video_label.config(image=img)
+            self.video_label.image = img
+            self.root.after(int(1000 / self.fps), self.play_video)
+        else:
+            self.is_playing = False
+            self.play_button.config(text="鎾斁")
+
+    def toggle_play_pause(self):
+        if not self.cap:
+            return
+        if self.is_playing:
+            self.is_playing = False
+            self.play_button.config(text="鎾斁")
+        else:
+            self.is_playing = True
+            self.play_button.config(text="鏆傚仠")
+            self.play_video()
+
+    def replay_video(self):
+        if not self.cap:
+            return
+        self.cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
+        self.current_frame = 0
+        self.progress.set(0)
+        self.is_playing = True
+        self.play_button.config(text="鏆傚仠")
+        self.play_video()
+
+    def seek_video(self, value):
+        if not self.cap:
+            return
+        self.current_frame = int(float(value))
+        self.cap.set(cv2.CAP_PROP_POS_FRAMES, self.current_frame)
+        if not self.is_playing:
+            self.play_video()
+
+
+# 鍒涘缓涓荤獥鍙�
+root = tk.Tk()
+app = VideoPlayer(root)
+root.mainloop()
diff --git a/libvlc.dll b/libvlc.dll
deleted file mode 100644
index 8f77033..0000000
--- a/libvlc.dll
+++ /dev/null
Binary files differ
diff --git a/libvlccore.dll b/libvlccore.dll
deleted file mode 100644
index 1f7f1c3..0000000
--- a/libvlccore.dll
+++ /dev/null
Binary files differ
diff --git a/pipe_sample.txt b/pipe_sample.txt
new file mode 100644
index 0000000..24d473f
--- /dev/null
+++ b/pipe_sample.txt
@@ -0,0 +1 @@
+ffmpeg -i demo.mp4 -vf fps=30 -q:v 2 -f image2pipe - | ffmpeg -framerate 30 -f image2pipe -i - -c:v libx264 -preset slow -crf 18 -pix_fmt yuv420p output.mp4
\ No newline at end of file
diff --git a/test/ffmpeg_read_cv2_write.py b/test/ffmpeg_read_cv2_write.py
new file mode 100644
index 0000000..583b00e
--- /dev/null
+++ b/test/ffmpeg_read_cv2_write.py
@@ -0,0 +1,74 @@
+import cv2
+import numpy as np
+import subprocess
+
+def read_video_frames_to_memory(video_path, frame_rate=30):
+    """
+    浣跨敤 FFmpeg 灏嗚棰戝抚浠� PNG 鏍煎紡鐩存帴璇诲彇鍒板唴瀛樹腑銆�
+    """
+    ffmpeg_command = [
+        "ffmpeg", "-i", video_path,
+        "-vf", f"fps={frame_rate}",
+        "-f", "image2pipe", "-vcodec", "png", "-"
+    ]
+
+    frame_size = 1080*1440*3
+
+    # 浣跨敤 subprocess 鎵撳紑 FFmpeg 杩涚▼
+    process = subprocess.Popen(ffmpeg_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=frame_size**1)
+
+    frames = []
+    try:
+        while True:
+            # 璇诲彇鍗曞抚鏁版嵁
+            frame_bytes = process.stdout.read(frame_size)  # 姣忔灏濊瘯璇诲彇 1MB
+            if not frame_bytes:
+                break
+
+            # 瑙g爜 PNG 鏁版嵁涓� NumPy 鏁扮粍锛堜娇鐢� OpenCV锛�
+            frame = cv2.imdecode(np.frombuffer(frame_bytes, np.uint8), cv2.IMREAD_UNCHANGED)
+            if frame is not None:
+                frames.append(frame)
+    finally:
+        process.stdout.close()
+        process.wait()
+
+    return frames
+
+def write_frames_to_mp4(frames, output_path, frame_rate=30):
+    """
+    浠庡抚鏁版嵁鐢熸垚 MP4 鏂囦欢銆�
+    """
+    if not frames:
+        print("No frames to write.")
+        return
+
+    # 鑾峰彇甯у昂瀵� (楂樺害, 瀹藉害)
+    frame_height, frame_width = frames[0].shape[:2]
+    print(frame_width,frame_height)
+
+    # 瀹氫箟瑙嗛缂栫爜鍣ㄥ拰杈撳嚭鏂囦欢
+    fourcc = cv2.VideoWriter_fourcc(*"mp4v")  # MP4 鏍煎紡缂栫爜鍣�
+    video_writer = cv2.VideoWriter(output_path, fourcc, frame_rate, (frame_width, frame_height))
+
+    for frame in frames:
+        # 妫�鏌ュ抚鏄惁鏄笁閫氶亾 (RGB/BGR)锛屽鏋滈渶瑕佽浆鎹㈡牸寮�
+        if len(frame.shape) == 2:  # 鐏板害鍥�
+            frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2BGR)
+        elif frame.shape[2] == 4:  # RGBA
+            frame = cv2.cvtColor(frame, cv2.COLOR_RGBA2BGR)
+
+        video_writer.write(frame)
+
+    video_writer.release()
+    print(f"Video saved to {output_path}")
+
+if __name__ == "__main__":
+    video_path = "E:/鎶栭煶-AI椋庢櫙/Test/demo.mp4"
+    output_path = "output.mp4"
+
+    # 璇诲彇瑙嗛甯у埌鍐呭瓨
+    frames = read_video_frames_to_memory(video_path)
+
+    # 灏嗗抚鏁版嵁鍐欏叆 MP4 鏂囦欢
+    write_frames_to_mp4(frames, output_path)
diff --git a/test/ffplay_test.py b/test/ffplay_test.py
new file mode 100644
index 0000000..86ab341
--- /dev/null
+++ b/test/ffplay_test.py
@@ -0,0 +1,94 @@
+import subprocess
+import tkinter as tk
+from tkinter import ttk
+import threading
+import time
+
+class VideoPlayer:
+    def __init__(self, root, video_path):
+        self.root = root
+        self.video_path = video_path
+        self.is_paused = False
+        self.is_running = True
+
+        # 鍒涘缓鐣岄潰鍏冪礌
+        self.canvas = tk.Canvas(root, width=640, height=480)
+        self.canvas.pack()
+
+        self.play_button = tk.Button(root, text="鎾斁/鏆傚仠", command=self.toggle_pause)
+        self.play_button.pack(side=tk.LEFT)
+
+        self.restart_button = tk.Button(root, text="閲嶆柊鎾斁", command=self.restart_video)
+        self.restart_button.pack(side=tk.LEFT)
+
+        self.progress = ttk.Scale(root, from_=0, to=100, orient=tk.HORIZONTAL, command=self.update_position)
+        self.progress.pack(fill=tk.X, expand=True)
+
+        # 鍚姩鎾斁瑙嗛绾跨▼
+        self.video_thread = threading.Thread(target=self.play_video)
+        self.video_thread.start()
+
+    def toggle_pause(self):
+        """鍒囨崲鎾斁/鏆傚仠鐘舵��"""
+        if self.is_paused:
+            self.is_paused = False
+        else:
+            self.is_paused = True
+
+    def restart_video(self):
+        """閲嶆柊寮�濮嬫挱鏀�"""
+        self.is_paused = False
+        self.progress.set(0)
+        self.play_video()
+
+    def update_position(self, value):
+        """鏇存柊杩涘害鏉′綅缃�"""
+        self.current_position = float(value)
+
+    def play_video(self):
+        """鎾斁瑙嗛骞舵洿鏂拌繘搴︽潯"""
+        # subprocess.run 浼氶樆濉烇紝鍚姩涓�涓悗鍙拌繘绋嬭繍琛� ffplay
+        ffplay_cmd = ["ffplay", "-i", self.video_path, "-v", "quiet", "-x", "640", "-y", "480", "-autoexit"]
+        
+        # 鍒涘缓 subprocess 鏉ユ挱鏀捐棰�
+        process = subprocess.Popen(ffplay_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        
+        while self.is_running:
+            if self.is_paused:
+                continue
+            # 鏇存柊杩涘害鏉�
+            self.update_progress(process)
+            time.sleep(0.1)  # 鎺у埗鏇存柊棰戠巼
+
+        process.wait()  # 绛夊緟瑙嗛鎾斁缁撴潫
+        self.restart_video()  # 鎾斁缁撴潫鍚庤嚜鍔ㄩ噸鎾�
+
+    def update_progress(self, process):
+        """鏇存柊杩涘害鏉�"""
+        # 鑾峰彇 ffplay 鐨勮緭鍑哄苟鏇存柊杩涘害
+        stdout, stderr = process.communicate()
+        lines = stderr.decode().splitlines()
+        for line in lines:
+            if "time=" in line:
+                # 鎻愬彇鏃堕棿淇℃伅
+                current_time = line.split("time=")[-1].split(" ")[0]
+                hours, minutes, seconds = map(float, current_time.split(":"))
+                total_seconds = hours * 3600 + minutes * 60 + seconds
+                video_duration = 120  # 鎵嬪姩璁剧疆瑙嗛鏃堕暱锛屾垨鑰呴�氳繃鍏朵粬鏂瑰紡鑾峰彇鏃堕暱
+                progress_percentage = (total_seconds / video_duration) * 100
+                self.progress.set(progress_percentage)
+
+    def close(self):
+        """鍏抽棴瑙嗛鎾斁鍣�"""
+        self.is_running = False
+        self.video_thread.join()
+
+# 鍒涘缓 Tkinter 绐楀彛
+root = tk.Tk()
+root.title("瑙嗛鎾斁鍣�")
+
+media_path = "E:/鎶栭煶-AI椋庢櫙/data/鍏虫敞/1515593476095344/瑙嗛/7375164244729302272.mp4"  # 鏇挎崲涓哄疄闄呰棰戞枃浠惰矾寰�
+player = VideoPlayer(root, media_path)
+
+root.protocol("WM_DELETE_WINDOW", player.close)
+root.mainloop()
diff --git a/test/loop.py b/test/loop.py
new file mode 100644
index 0000000..8199b6c
--- /dev/null
+++ b/test/loop.py
@@ -0,0 +1,33 @@
+import vlc
+from pathlib import Path
+import time
+import os
+
+
+class Loop_Vlc_Player:
+
+    def __init__(self):
+        self.player = vlc.Instance()
+
+    def addPlayList(self, localPath):
+        self.mediaList = self.player.media_list_new()
+        self.mediaList.add_media(localPath)
+        self.listPlayer = self.player.media_list_player_new()
+        self.listPlayer.set_media_list(self.mediaList)
+        self.listPlayer.set_playback_mode(vlc.PlaybackMode(1))
+
+    def play(self):
+        self.listPlayer.play()
+
+    def stop(self):
+        self.listPlayer.stop()
+
+
+play = Loop_Vlc_Player()
+video_path = "E:/鎶栭煶-AI椋庢櫙/data/鍏虫敞/1515593476095344/瑙嗛/7375164244729302272.mp4"  # 鏇挎崲涓哄疄闄呰棰戞枃浠惰矾寰�
+
+play.addPlayList(video_path)
+play.play()
+while True:
+    pass
+
diff --git a/test/pi.py b/test/pi.py
new file mode 100644
index 0000000..1fbf48d
--- /dev/null
+++ b/test/pi.py
@@ -0,0 +1,70 @@
+import cv2
+import os
+
+def slice_video_by_frames(video_path, frame_segments, output_dir, codec="mp4v", fps=None):
+    """
+    浣跨敤 OpenCV 瀹炵幇瑙嗛鎸夊抚鍒囧垎銆�
+
+    鍙傛暟锛�
+    - video_path: 杈撳叆瑙嗛璺緞銆�
+    - frame_segments: 甯у尯闂寸殑鍒楄〃锛屼緥濡傦細[(start_frame1, end_frame1), (start_frame2, end_frame2), ...]銆�
+    - output_dir: 杈撳嚭鏂囦欢澶硅矾寰勩��
+    - codec: 瑙嗛缂栫爜鍣紝榛樿鏄� "mp4v"锛堥�傚悎鐢熸垚 MP4锛夈��
+    - fps: 甯х巼锛岄粯璁や负杈撳叆瑙嗛鐨勫抚鐜囥��
+    """
+    # 鍒涘缓杈撳嚭鐩綍
+    os.makedirs(output_dir, exist_ok=True)
+
+    # 鎵撳紑瑙嗛
+    video_capture = cv2.VideoCapture(video_path)
+    if not video_capture.isOpened():
+        raise ValueError(f"鏃犳硶鎵撳紑瑙嗛鏂囦欢: {video_path}")
+
+    # 鑾峰彇瑙嗛灞炴��
+    original_fps = video_capture.get(cv2.CAP_PROP_FPS)
+    frame_width = int(video_capture.get(cv2.CAP_PROP_FRAME_WIDTH))
+    frame_height = int(video_capture.get(cv2.CAP_PROP_FRAME_HEIGHT))
+    total_frames = int(video_capture.get(cv2.CAP_PROP_FRAME_COUNT))
+
+    if fps is None:
+        fps = original_fps
+
+    print(f"瑙嗛灞炴�э細鎬诲抚鏁�={total_frames}, 甯х巼={original_fps}, 鍒嗚鲸鐜�={frame_width}x{frame_height}")
+
+    for idx, (start_frame, end_frame) in enumerate(frame_segments):
+        # 鏍¢獙甯ц寖鍥�
+        if start_frame < 0 or end_frame > total_frames or start_frame >= end_frame:
+            print(f"鏃犳晥鐨勫抚鍖洪棿锛�({start_frame}, {end_frame})")
+            continue
+
+        # 杈撳嚭鏂囦欢璺緞
+        output_file = os.path.join(output_dir, f"slice_{idx+1}.mp4")
+
+        # 鍒濆鍖栬棰戝啓鍏ュ櫒
+        fourcc = cv2.VideoWriter_fourcc(*codec)
+        video_writer = cv2.VideoWriter(output_file, fourcc, fps, (frame_width, frame_height))
+
+        # 璺宠浆鍒拌捣濮嬪抚
+        video_capture.set(cv2.CAP_PROP_POS_FRAMES, start_frame)
+
+        # 閫愬抚璇诲彇骞跺啓鍏�
+        for frame_idx in range(start_frame, end_frame):
+            ret, frame = video_capture.read()
+            if not ret:
+                print(f"鏃犳硶璇诲彇甯э細{frame_idx}")
+                break
+            video_writer.write(frame)
+
+        video_writer.release()
+        print(f"鐢熸垚鍒囩墖: {output_file} ({start_frame} ~ {end_frame})")
+
+    video_capture.release()
+    print("瑙嗛鍒囧垎瀹屾垚銆�")
+
+# 绀轰緥鐢ㄦ硶
+if __name__ == "__main__":
+    video_path = "E:/鎶栭煶-AI椋庢櫙/Test/demo.mp4" # 鏇挎崲涓轰綘鐨勮緭鍏ヨ棰戣矾寰�
+    output_dir = "output"  # 鏇挎崲涓轰綘鐨勮緭鍑烘枃浠跺す璺緞
+    frame_segments = [(0, 60),(60, 79), (79,98),(98,116), (116,135),(135, 153), (153,172), (172,190), (190,209), (209,228), (228,247), (247,266), (266,285),(285,305)]  # 瀹氫箟甯у尯闂�
+
+    slice_video_by_frames(video_path, frame_segments, output_dir)
\ No newline at end of file
diff --git a/test/pipe_test copy.py b/test/pipe_test copy.py
new file mode 100644
index 0000000..5495ca6
--- /dev/null
+++ b/test/pipe_test copy.py
@@ -0,0 +1,71 @@
+import subprocess
+import os
+
+def split_video_by_pipe(video_path, frame_segments, width, height, output_dir):
+    """
+    浣跨敤 FFmpeg 鐨勭閬撴柟寮忥紝灏嗚棰戞媶鍒嗘垚鎸囧畾鐨勫抚鍒囩墖锛岃緭鍑轰负澶氫釜瑙嗛鏂囦欢銆�
+
+    鍙傛暟锛�
+    - video_path: 杈撳叆瑙嗛璺緞
+    - frame_segments: 鍒囩墖甯ф锛屼緥濡傦細[0, M1, M2, ..., Mlast]
+    - width, height: 瑙嗛鍒嗚鲸鐜囷紝鐢ㄤ簬璁$畻甯уぇ灏�
+    - output_dir: 杈撳嚭鏂囦欢鐩綍
+    """
+    # 瑙嗛甯ф牸寮忓亣璁� RGB锛堟瘡鍍忕礌 3 瀛楄妭锛�
+    bytes_per_pixel = 3
+    frame_size = width * height * bytes_per_pixel  # 鍗曞抚鐨勫瓧鑺傚ぇ灏�
+
+    # 鍒涘缓杈撳嚭瀛愮洰褰�
+    os.makedirs(output_dir, exist_ok=True)
+    
+    # 鎵撳紑瑙嗛瑙g爜绠¢亾锛岀敤浜庡抚鎻愬彇
+    ffmpeg_extract = [
+        "ffmpeg", "-i", video_path, "-vf", "fps=30", "-f", "image2pipe", "-vcodec", "rawvideo", "-"
+    ]
+    process_extract = subprocess.Popen(ffmpeg_extract, stdout=subprocess.PIPE, bufsize=frame_size * 1)
+
+    # 鍒涘缓澶氫釜甯у垎娈电閬�
+    slice_pipes = []
+    for i, _ in enumerate(frame_segments[:-1]):
+        output_file = os.path.join(output_dir, f"slice_{i+1}.mp4")
+        ffmpeg_encode = [
+            "ffmpeg", "-framerate", "30", "-f", "rawvideo", "-vcodec", "rawvideo", "-s", f"{width}x{height}", "-pix_fmt", "rgb24", "-i", "-",
+            "-c:v", "libx264", "-preset", "slow", "-crf", "18", "-pix_fmt", "yuv420p", output_file
+        ]
+        slice_pipes.append(subprocess.Popen(ffmpeg_encode, stdin=subprocess.PIPE, bufsize=frame_size * 1))
+
+    # 璇诲彇甯у苟鍒嗛厤鍒板搴旂殑鍒囩墖绠¢亾
+    current_frame = 0
+    while True:
+        frame_data = process_extract.stdout.read(frame_size)
+        if len(frame_data) < frame_size:
+            break  # 璇诲彇缁撴潫
+
+        # 鎵惧埌褰撳墠甯ф墍灞炵殑鍒囩墖娈�
+        for i, (start_frame, end_frame) in enumerate(zip(frame_segments[:-1], frame_segments[1:])):
+            if start_frame <= current_frame < end_frame:
+                print(i)
+                slice_pipes[i].stdin.write(frame_data)
+                break
+        
+        current_frame += 1
+
+    # 鍏抽棴鎵�鏈夌閬�
+    process_extract.stdout.close()
+    process_extract.wait()
+    for pipe in slice_pipes:
+        pipe.stdin.close()
+        pipe.wait()
+
+    print(f"瑙嗛鍒嗘瀹屾垚锛屽垏鐗囧瓨鍌ㄥ湪锛歿output_dir}")
+
+
+
+# 绀轰緥浣跨敤
+video_path = "E:/鎶栭煶-AI椋庢櫙/Test/demo.mp4"
+frame_segments = [0, 60, 69, 305]
+fps = 30
+width, height = 1080, 1440  
+output_dir = "output"
+
+split_video_by_pipe(video_path, frame_segments, width,height, output_dir)
\ No newline at end of file
diff --git a/test/pipe_test.py b/test/pipe_test.py
new file mode 100644
index 0000000..5e9d7ff
--- /dev/null
+++ b/test/pipe_test.py
@@ -0,0 +1,60 @@
+import subprocess
+import os
+
+def test_pipeline_to_multiple_slices(video_path):
+    frame_segments = [(0, 60), (60, 79), (79, 98), (98, 116), (116, 135),
+                      (135, 153), (153, 172), (172, 190), (190, 209),
+                      (209, 228), (228, 247), (247, 266), (266, 285), (285, 305)]  # 甯у尯闂�
+    
+    # 鍚姩 FFmpeg 浠ヨ鍙栬棰戝抚鏁版嵁骞堕�氳繃绠¢亾杈撳嚭
+    ffmpeg_extract = [
+        "ffmpeg", "-i", video_path, "-vf", "fps=30", "-f", "image2pipe", "-vcodec", "png", "-"
+    ]
+    process_extract = subprocess.Popen(ffmpeg_extract, stdout=subprocess.PIPE, bufsize=10**8)  # 浣跨敤杈冨ぇ缂撳啿鍖�
+
+    # 鍒涘缓澶氫釜瀛愯繘绋嬶紝澶勭悊瑙嗛鍒囩墖
+    slice_processes = []
+    output_pipes = []
+
+    for i, (start_frame, end_frame) in enumerate(frame_segments):
+        output_file = f"slice_{i+1}.mp4"
+        ffmpeg_encode = [
+            "ffmpeg", "-framerate", "30", "-f", "image2pipe", "-vcodec", "png", "-i", "-",
+            "-c:v", "libx264", "-preset", "slow", "-crf", "0", "-pix_fmt", "yuv420p", output_file
+        ]
+        process = subprocess.Popen(ffmpeg_encode, stdin=subprocess.PIPE)
+        slice_processes.append(process)
+        output_pipes.append((process.stdin, start_frame, end_frame))
+
+    current_frame = 0
+
+    try:
+        while True:
+            frame_data = process_extract.stdout.read(1024*1024)  # 姣忔璇诲彇 1MB锛岀洿鍒版棤鏁版嵁
+            if not frame_data:
+                break  # 褰撹鍙栧埌瑙嗛缁撴潫鏃惰烦鍑哄惊鐜�
+
+            # 鍒嗗彂甯ф暟鎹埌鍚堥�傜殑瀛愯繘绋�
+            for pipe, start_frame, end_frame in output_pipes:
+                if start_frame <= current_frame < end_frame:
+                    pipe.write(frame_data)  # 鍐欏叆甯ф暟鎹�
+                    break
+
+            current_frame += 1
+
+    finally:
+        # 鍏抽棴鎵�鏈夊瓙杩涚▼鐨勮緭鍏ユ祦
+        for pipe, _, _ in output_pipes:
+            pipe.close()
+
+        # 绛夊緟鎵�鏈夊瓙杩涚▼瀹屾垚
+        for process in slice_processes:
+            process.wait()
+
+        # 鍏抽棴鎻愬彇杩涚▼鐨勮緭鍑烘祦
+        process_extract.stdout.close()
+        process_extract.wait()
+
+if __name__ == "__main__":
+    video_path = "E:/鎶栭煶-AI椋庢櫙/Test/demo.mp4"
+    test_pipeline_to_multiple_slices(video_path)
diff --git a/test/pygame_test.py b/test/pygame_test.py
new file mode 100644
index 0000000..b526ac8
--- /dev/null
+++ b/test/pygame_test.py
@@ -0,0 +1,107 @@
+import pygame
+import subprocess
+import threading
+import time
+import tkinter as tk
+from tkinter import ttk
+
+class VideoPlayer:
+    def __init__(self, root, video_path):
+        self.root = root
+        self.video_path = video_path
+        self.is_paused = False
+        self.is_running = True
+        self.current_position = 0
+
+        # 鍒濆鍖� pygame
+        pygame.init()
+        self.screen = pygame.display.set_mode((640, 480))
+        pygame.display.set_caption("瑙嗛鎾斁鍣�")
+
+        # 鍒涘缓 Tkinter 鎺т欢
+        self.canvas = tk.Canvas(root, width=640, height=480)
+        self.canvas.pack()
+
+        self.play_button = tk.Button(root, text="鎾斁/鏆傚仠", command=self.toggle_pause)
+        self.play_button.pack(side=tk.LEFT)
+
+        self.restart_button = tk.Button(root, text="閲嶆柊鎾斁", command=self.restart_video)
+        self.restart_button.pack(side=tk.LEFT)
+
+        self.progress = ttk.Scale(root, from_=0, to=100, orient=tk.HORIZONTAL, command=self.update_position)
+        self.progress.pack(fill=tk.X, expand=True)
+
+        # 鍚姩鎾斁瑙嗛绾跨▼
+        self.video_thread = threading.Thread(target=self.play_video)
+        self.video_thread.start()
+
+    def toggle_pause(self):
+        """鍒囨崲鎾斁/鏆傚仠鐘舵��"""
+        if self.is_paused:
+            self.is_paused = False
+        else:
+            self.is_paused = True
+
+    def restart_video(self):
+        """閲嶆柊寮�濮嬫挱鏀�"""
+        self.is_paused = False
+        self.progress.set(0)
+        self.play_video()
+
+    def update_position(self, value):
+        """鏇存柊杩涘害鏉′綅缃�"""
+        self.current_position = float(value)
+
+    def play_video(self):
+        """鎾斁瑙嗛骞舵洿鏂拌繘搴︽潯"""
+        # 浣跨敤 subprocess 鎾斁瑙嗛骞舵彁鍙栧抚
+        ffmpeg_cmd = [
+            "ffmpeg", "-i", self.video_path, "-f", "image2pipe", "-pix_fmt", "rgb24", 
+            "-vcodec", "rawvideo", "-"]
+        
+        # 鍒涘缓 subprocess 鏉ユ墽琛� ffmpeg 鍛戒护
+        process = subprocess.Popen(ffmpeg_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        
+        frame_count = 0
+        while self.is_running:
+            if self.is_paused:
+                time.sleep(0.1)
+                continue
+
+            # 浠� ffmpeg 鎻愬彇涓�甯�
+            raw_frame = process.stdout.read(640 * 480 * 3)  # 璇诲彇涓�甯э紙RGB24锛�
+            if len(raw_frame) < 640 * 480 * 3:
+                break  # 濡傛灉璇诲彇鐨勫抚涓嶅畬鏁达紝鍒欏仠姝�
+
+            frame = pygame.image.fromstring(raw_frame, (640, 480), 'RGB')
+            self.screen.blit(frame, (0, 0))
+            pygame.display.flip()  # 鏇存柊灞忓箷
+
+            frame_count += 1
+            self.update_progress(frame_count)
+
+            time.sleep(0.04)  # 鎺у埗甯х巼 (鍋囪瑙嗛鐨勫抚鐜囨槸 25 FPS)
+
+        process.wait()  # 绛夊緟瑙嗛鎾斁缁撴潫
+        self.restart_video()  # 鎾斁缁撴潫鍚庤嚜鍔ㄩ噸鎾�
+
+    def update_progress(self, frame_count):
+        """鏇存柊杩涘害鏉�"""
+        video_duration = 120  # 鎵嬪姩璁剧疆瑙嗛鏃堕暱锛屾垨鑰呴�氳繃鍏朵粬鏂瑰紡鑾峰彇鏃堕暱
+        progress_percentage = (frame_count / (25 * video_duration)) * 100
+        self.progress.set(progress_percentage)
+
+    def close(self):
+        """鍏抽棴瑙嗛鎾斁鍣�"""
+        self.is_running = False
+        self.video_thread.join()
+
+# 鍒涘缓 Tkinter 绐楀彛
+root = tk.Tk()
+root.title("瑙嗛鎾斁鍣�")
+
+media_path = "E:/鎶栭煶-AI椋庢櫙/data/鍏虫敞/1515593476095344/瑙嗛/7375164244729302272.mp4"  # 鏇挎崲涓哄疄闄呰棰戞枃浠惰矾寰�
+player = VideoPlayer(root, media_path)
+
+root.protocol("WM_DELETE_WINDOW", player.close)
+root.mainloop()
diff --git a/test/refresh.py b/test/refresh.py
new file mode 100644
index 0000000..81b1f52
--- /dev/null
+++ b/test/refresh.py
@@ -0,0 +1,24 @@
+import tkinter as tk
+from tkinter import filedialog
+
+def open_folder():
+    folder_path = filedialog.askdirectory()
+    if folder_path:
+        # 鍋囪璁$畻鏂囦欢鏁伴噺
+        file_count = 5  # 绀轰緥鍊�
+        print("姝e湪鏇存柊鏂囦欢鏁伴噺...")
+        file_count_label.config(text="鏂囦欢鏁伴噺锛�" + str(file_count))
+        root.update()  # 鍒锋柊鐣岄潰
+
+root = tk.Tk()
+root.geometry("400x200")
+
+# 娣诲姞涓�涓� Label
+file_count_label = tk.Label(root, text="鏂囦欢鏁伴噺锛�0")
+file_count_label.pack(pady=10)
+
+# 娣诲姞鎸夐挳
+open_button = tk.Button(root, text="鎵撳紑鏂囦欢澶�", command=open_folder)
+open_button.pack(pady=20)
+
+root.mainloop()
diff --git a/test/scene_detect_demo.py b/test/scene_detect_demo.py
new file mode 100644
index 0000000..a4a9f6e
--- /dev/null
+++ b/test/scene_detect_demo.py
@@ -0,0 +1,69 @@
+import cv2
+from scenedetect import detect, ContentDetector
+from moviepy.editor import VideoFileClip
+
+import sys
+# 妫�娴嬭棰戜腑鐨勫満鏅�
+scene_list = detect(sys.argv[1], ContentDetector())
+
+frame_list = []
+    
+for i, scene in enumerate(scene_list):
+    if i==0:
+        print(scene[0].get_frames(),scene[1].get_frames()+2)
+        frame_list.append([scene[0].get_frames(),scene[1].get_frames()+2])
+    elif i==len(scene_list)-1:
+        print(scene[0].get_frames()+2,scene[1].get_frames())
+        frame_list.append([scene[0].get_frames()+2,scene[1].get_frames()])
+    else:
+        print(scene[0].get_frames()+2,scene[1].get_frames()+2)
+        frame_list.append([scene[0].get_frames()+2,scene[1].get_frames()+2])
+
+
+# 鎵撳紑鍘熷瑙嗛
+video_clip = VideoFileClip(sys.argv[1])
+
+# 閬嶅巻鍦烘櫙骞朵繚瀛樹负鏂扮殑 MP4 鏂囦欢
+for i, (start_frame, end_frame) in enumerate(scene_list):
+    # 灏嗗抚鏁拌浆鎹负绉�
+    start_time = start_frame.get_seconds()  # 浣跨敤 get_seconds() 杞崲涓虹
+    end_time = end_frame.get_seconds()      # 浣跨敤 get_seconds() 杞崲涓虹
+    
+    # 鍒囧壊瑙嗛
+    scene_clip = video_clip.subclip(start_time, end_time)
+    
+    # 璁剧疆杈撳嚭鏂囦欢鍚�
+    output_filename = f"oringal_{i+1}.mp4"
+    
+    # 淇濆瓨鍦烘櫙涓� MP4 鏂囦欢
+    scene_clip.write_videofile(output_filename, codec="libx264", fps=video_clip.fps)
+
+    print(f"Scene {i+1} has been saved as {output_filename}")
+
+# 鍏抽棴瑙嗛鏂囦欢
+video_clip.close()
+
+# 鎵撳紑鍘熷瑙嗛
+video_clip = VideoFileClip(sys.argv[1])
+fps =video_clip.fps
+# 閬嶅巻鍦烘櫙骞朵繚瀛樹负鏂扮殑 MP4 鏂囦欢
+for index,item in enumerate(frame_list):
+    # 灏嗗抚鏁拌浆鎹负绉�
+    start_time = item[0]/fps  
+    end_time = item[1]/fps  
+    
+    # 鍒囧壊瑙嗛
+    scene_clip = video_clip.subclip(start_time, end_time)
+    
+    # 璁剧疆杈撳嚭鏂囦欢鍚�
+    output_filename = f"modified_{index+1}.mp4"
+    
+    # 淇濆瓨鍦烘櫙涓� MP4 鏂囦欢
+    scene_clip.write_videofile(output_filename, codec="libx264", fps=video_clip.fps)
+
+    print(f"Scene {i+1} has been saved as {output_filename}")
+
+# 鍏抽棴瑙嗛鏂囦欢
+video_clip.close()
+
+
diff --git a/test/sence_detect_demo.py b/test/sence_detect_demo.py
new file mode 100644
index 0000000..c0d211b
--- /dev/null
+++ b/test/sence_detect_demo.py
@@ -0,0 +1,70 @@
+import cv2
+from scenedetect import detect, ContentDetector
+
+# 妫�娴嬭棰戜腑鐨勫満鏅�
+scene_list = detect('demo3.mp4', ContentDetector())
+
+# 瀛樺偍淇敼鍚庣殑鍦烘櫙淇℃伅
+modified_scene_list = []
+
+# 閬嶅巻鍦烘櫙
+for i, scene in enumerate(scene_list):
+    if i == 0:
+        # 绗竴涓満鏅洿鎺ユ坊鍔�
+        modified_scene_list.append(scene)
+    elif i == len(scene_list) - 1:
+        # 鏈�鍚庝竴涓満鏅笉澶勭悊
+        modified_scene_list.append(scene)
+    else:
+        # 浠庣浜屼釜鍦烘櫙寮�濮嬶紝澶勭悊鍓嶄袱甯�
+        current_scene_start_frame = scene[0].get_frames()
+        current_scene_end_frame = scene[1].get_frames()
+
+        # 鑾峰彇鍓嶄竴涓満鏅�
+        previous_scene = modified_scene_list[-1]
+
+        # 鑾峰彇鍓嶄竴涓満鏅殑缁撴潫甯�
+        previous_scene_end_frame = previous_scene[1].get_frames()
+
+        # 鏇存柊鍓嶄竴涓満鏅殑缁撴潫甯э紝灏嗗綋鍓嶅満鏅殑鍓嶄袱甯ф嫾鎺ュ埌鍓嶄竴涓満鏅悗闈�
+        modified_previous_scene_end_frame = previous_scene_end_frame + 2
+
+        # 鏇存柊鍓嶄竴涓満鏅殑缁撴潫鏃堕棿
+        modified_scene_list[-1] = (previous_scene[0], scene[0])
+
+        # 娣诲姞褰撳墠鍦烘櫙锛堝幓鎺夊墠涓ゅ抚锛�
+        modified_scene_list.append((scene[0], scene[1]))
+
+# 鎵撳紑鍘熷瑙嗛
+cap = cv2.VideoCapture('demo3.mp4')
+fps = cap.get(cv2.CAP_PROP_FPS)  # 鑾峰彇甯х巼
+frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))  # 鑾峰彇甯у搴�
+frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))  # 鑾峰彇甯ч珮搴�
+
+# 瀵规瘡涓満鏅繘琛屽垏鍓插苟淇濆瓨涓� MP4
+for i, scene in enumerate(modified_scene_list):
+    start_frame = scene[0].get_frames()
+    end_frame = scene[1].get_frames()
+    
+    # 璁剧疆瑙嗛璇诲彇鐨勮捣濮嬩綅缃�
+    cap.set(cv2.CAP_PROP_POS_FRAMES, start_frame)
+    
+    # 鍒涘缓涓�涓� VideoWriter 瀵硅薄锛岀敤浜庝繚瀛樺綋鍓嶅満鏅负鏂扮殑 MP4 鏂囦欢
+    output_filename = f'scene_{i+1}.mp4'
+    fourcc = cv2.VideoWriter_fourcc(*'H264')  # 浣跨敤 H.264 缂栫爜鍣�
+    out = cv2.VideoWriter(output_filename, fourcc, fps, (frame_width, frame_height))  # 瑙嗛鍒嗚鲸鐜�
+    
+    # 璇诲彇姣忎竴甯у苟鍐欏叆鍒拌緭鍑烘枃浠朵腑
+    for frame_num in range(start_frame, end_frame):
+        ret, frame = cap.read()
+        if not ret:
+            break
+        out.write(frame)
+
+    # 閲婃斁 VideoWriter 鍜� VideoCapture 瀵硅薄
+    out.release()
+
+    print(f'Scene {i+1} has been saved as {output_filename}')
+
+# 閲婃斁 VideoCapture 瀵硅薄
+cap.release()
diff --git a/test/t_ffmpeg.py b/test/t_ffmpeg.py
new file mode 100644
index 0000000..0774c9b
--- /dev/null
+++ b/test/t_ffmpeg.py
@@ -0,0 +1,3 @@
+from scenedetect import detect, ContentDetector, split_video_ffmpeg
+scene_list = detect('demo.mp4', ContentDetector())
+split_video_ffmpeg('demo.mp4', scene_list)
\ No newline at end of file
diff --git a/test/t_ssim.py b/test/t_ssim.py
new file mode 100644
index 0000000..4b539e4
--- /dev/null
+++ b/test/t_ssim.py
@@ -0,0 +1,66 @@
+import cv2
+from skimage.metrics import structural_similarity as ssim
+import numpy as np
+
+class VideoSSIM:
+    def __init__(self, video_path):
+        # 鍒濆鍖栬棰戣矾寰勫拰鎵撳紑瑙嗛
+        self.video_path = video_path
+        self.cap = cv2.VideoCapture(video_path)
+        if not self.cap.isOpened():
+            raise ValueError(f"Error opening video file: {video_path}")
+        
+        # 鑾峰彇瑙嗛甯х巼锛坒ps锛�
+        self.fps = self.cap.get(cv2.CAP_PROP_FPS)
+        
+        # 鑾峰彇瑙嗛鐨勫昂瀵�
+        self.frame_width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH))
+        self.frame_height = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
+
+    def calculate_ssim(self):
+        # 璇诲彇瑙嗛鐨勭涓�甯�
+        ret, prev_frame = self.cap.read()
+        if not ret:
+            raise ValueError("Error reading the first frame")
+
+        prev_frame_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)  # 杞崲涓虹伆搴﹀浘
+        
+        # 瀛樺偍鐩镐技鎬ф暟鍊�
+        ssim_values = []
+        
+        # 浠庣浜屽抚寮�濮嬮�愬抚璁$畻涓庡墠涓�甯х殑缁撴瀯鐩镐技鎬�
+        frame_index = 2  # 浠庣浜屽抚寮�濮�
+        while True:
+            ret, curr_frame = self.cap.read()
+            if not ret:
+                break
+            
+            # 杞崲褰撳墠甯т负鐏板害鍥�
+            curr_frame_gray = cv2.cvtColor(curr_frame, cv2.COLOR_BGR2GRAY)
+            
+            # 璁$畻SSIM
+            ssim_value, _ = ssim(prev_frame_gray, curr_frame_gray, full=True)
+            ssim_values.append((frame_index, ssim_value))  # 璁板綍甯х储寮曞拰SSIM鍊�
+            
+            # 鏇存柊鍓嶄竴甯�
+            prev_frame_gray = curr_frame_gray
+            frame_index += 1
+        
+        # 閲婃斁瑙嗛鎹曟崏瀵硅薄
+        self.cap.release()
+        
+        return ssim_values
+
+    def save_ssim_to_file(self, output_file="ssim_values.txt"):
+        ssim_values = self.calculate_ssim()
+        
+        # 淇濆瓨SSIM鍊煎埌鏂囦欢
+        with open(output_file, "w") as f:
+            for frame_idx, ssim_value in ssim_values:
+                f.write(f"Frame {frame_idx}: SSIM = {ssim_value}\n")
+        
+        print(f"SSIM values saved to {output_file}")
+
+# 浣跨敤绀轰緥
+video_ssim = VideoSSIM("demo.mp4")  # 鏇挎崲鎴愪綘鐨勮棰戞枃浠惰矾寰�
+video_ssim.save_ssim_to_file("demo_ssim_output.txt")
diff --git a/test/test_cv.py b/test/test_cv.py
new file mode 100644
index 0000000..409602f
--- /dev/null
+++ b/test/test_cv.py
@@ -0,0 +1,94 @@
+import cv2
+import numpy as np
+import os
+import time
+
+def read_video_to_memory(video_path):
+    """
+    璇诲彇 MP4 瑙嗛骞跺皢姣忎竴甯у瓨鍌ㄥ埌鍐呭瓨涓�
+    """
+    start_time = time.time()
+    cap = cv2.VideoCapture(video_path)
+    frames = []
+    
+    # 鑾峰彇瑙嗛鐨勬�诲抚鏁板拰甯х巼
+    total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
+    fps = cap.get(cv2.CAP_PROP_FPS)
+
+    print(total_frames)
+
+    print(fps)
+    
+    while True:
+        ret, frame = cap.read()
+        if not ret:
+            break
+        frames.append(frame)
+    
+    cap.release()
+    print(time.time() -start_time )
+    return frames, fps, total_frames
+
+def generate_thumbnail(frame, max_size=144):
+    """
+    鐢熸垚涓嶈秴杩囨寚瀹氬ぇ灏忕殑缂╃暐鍥�
+    """
+    height, width = frame.shape[:2]
+    
+    # 纭畾缂╂斁姣斾緥
+    scale = min(max_size / height, max_size / width)
+    new_width = int(width * scale)
+    new_height = int(height * scale)
+    
+    # 缂╂斁骞惰繑鍥炵缉鐣ュ浘
+    thumbnail = cv2.resize(frame, (new_width, new_height))
+    return thumbnail
+
+def save_video_slice(frames, slice_range, output_file, fps):
+    """
+    鏍规嵁鎸囧畾鐨勫抚鑼冨洿灏嗚棰戜繚瀛樹负鏂扮殑鐗囨
+    """
+    fourcc = cv2.VideoWriter_fourcc(*'mp4v')  # 鐢ㄤ簬鐢熸垚 MP4 鏍煎紡
+    height, width = frames[0].shape[:2]
+    out = cv2.VideoWriter(output_file, fourcc, fps, (width, height))
+    
+    start_frame, end_frame = slice_range
+    
+    # 閬嶅巻鎸囧畾鑼冨洿鐨勫抚骞跺啓鍏ュ埌鏂拌棰戜腑
+    for i in range(start_frame, end_frame):
+        out.write(frames[i])
+    
+    out.release()
+
+def create_video_slice_from_memory(video_path, slice_segments, output_dir):
+    """
+    浠庡唴瀛樹腑鐨勮棰戝抚鍒涘缓澶氫釜瑙嗛鐗囨
+    """
+    frames, fps, total_frames = read_video_to_memory(video_path)
+    
+    start_time = time.time()
+    # 鐢熸垚缂╃暐鍥惧苟鏄剧ず
+    thumbnails = []
+    for frame in frames:
+        thumbnails.append(generate_thumbnail(frame))
+
+    print(time.time()-start_time)
+    
+    
+    # 鏍规嵁鍒囩墖鍒嗗壊瑙嗛骞朵繚瀛�
+    for i, (start_frame, end_frame) in enumerate(slice_segments):
+        output_file = os.path.join(output_dir, f"slice_{i+1}.mp4")
+        start_time = time.time()-start_time
+        save_video_slice(frames, (start_frame, end_frame), output_file, fps)
+        print(time.time()-start_time)
+
+
+# 绀轰緥锛氳鍙栬棰戝苟鍒涘缓澶氫釜鍒囩墖
+video_path = "E:/鎶栭煶-AI椋庢櫙/Test/demo.mp4"
+slice_segments = [(0, 60),(60, 79), (79,98),(98,116), (116,135),(135, 153), (153,172), (172,190), (190,209), (209,228), (228,247), (247,266), (266,285),(285,303)]  # 瀹氫箟甯у尯闂�
+output_dir = "output_slices"
+
+if not os.path.exists(output_dir):
+    os.makedirs(output_dir)
+
+create_video_slice_from_memory(video_path, slice_segments, output_dir)
diff --git a/test/tk.py b/test/tk.py
new file mode 100644
index 0000000..a03c1bf
--- /dev/null
+++ b/test/tk.py
@@ -0,0 +1,77 @@
+import subprocess
+import os
+
+import re
+
+
+def cut_video_by_frames(video_path, frame_segments, total_frames, output_dir):
+    """
+    灏嗚棰戞寜鐓ф寚瀹氱殑甯у垏鐗囪繘琛屽垏鍓层��
+
+    鍙傛暟锛�
+    - video_path: 杈撳叆瑙嗛鐨勮矾寰�
+    - frame_segments: 鍒囩墖鐨勫抚搴忓彿鏁扮粍锛屼緥濡傦細[0, M1, M2, ..., Mlast]
+    - output_dir: 杈撳嚭瑙嗛鏂囦欢鐨勭洰褰�
+    """
+    fps = 30   # default fps
+
+    # 鑾峰彇瑙嗛鐨勫抚鐜� (fps)
+    command = [
+        "ffmpeg", "-i", video_path, "-vf", "fps=1", "-f", "null", "-"
+    ]
+    result = subprocess.run(command, stdout=subprocess.PIPE,
+                            stderr=subprocess.PIPE, text=True)
+    output = result.stderr
+    # 瑙f瀽 fps锛屾煡鎵句俊鎭�
+    fps_line = next(line for line in output.splitlines() if 'fps' in line)
+    # 浣跨敤姝e垯琛ㄨ揪寮忔彁鍙栧抚鐜囧�硷紙鍋囪fps鍊兼�绘槸鍑虹幇鍦�"fps"鍓嶉潰锛�
+    match = re.search(r'(\d+(\.\d+)?)\s*fps', fps_line)
+    if match:
+        fps = float(match.group(1))  # 鎻愬彇骞惰浆鎹负 float
+        print(f"FPS: {fps}")
+
+    print(f"瑙嗛鐨勬�诲抚鏁�: {total_frames}, 甯х巼: {fps}")
+
+    # 閬嶅巻鍒囩墖鍖洪棿
+    for i in range(len(frame_segments) - 1):
+        start_frame = frame_segments[i]
+        end_frame = frame_segments[i + 1]
+
+        
+        start_time = float(start_frame) / fps
+        end_time = float(end_frame) / fps
+
+        output_file = os.path.join(output_dir, f"segment_{i + 1}.mp4")
+
+        
+        # 浣跨敤 FFmpeg 鍛戒护鏉ュ垏鍓茶棰�
+        command = [
+            "ffmpeg", "-i", video_path, "-ss", f"{start_time:.10f}", "-to", f"{end_time:.10f}",
+            "-c:v", "libx264", "-c:a", "copy","-crf", "18","-preset", "veryslow", output_file
+        ]
+        print(" ".join(command))
+       
+        subprocess.run(command)
+
+    # 鏈�鍚庝竴娈靛鐞嗭紙浠庢渶鍚庝竴涓垏鐗囧埌瑙嗛缁撴潫锛�
+    last_start_frame = frame_segments[-1]
+    last_start_time = last_start_frame / fps
+    output_file = os.path.join(
+        output_dir, f"segment_{len(frame_segments)}.mp4")
+
+    #print(f"姝e湪鍒囧壊鏈�鍚庝竴娈碉細浠� {last_start_time:.10f}s 鍒拌棰戠粨鏉燂紝淇濆瓨涓� {output_file}")
+    command = [
+        "ffmpeg", "-i", video_path, "-ss", f"{last_start_time:.10f}",
+        "-c:v", "libx264", "-c:a", "copy","-crf", "18","-preset", "veryslow", output_file
+    ]
+    print(" ".join(command))
+    subprocess.run(command)
+
+
+target_file = "E:/鎶栭煶-AI椋庢櫙/鏂板缓鏂囦欢澶筡_demoold.mp4"
+selected_labels = [0, 60, 79, 98, 116, 135,
+                   153, 172, 190, 209, 228, 246, 264, 283]
+frame_count = 305
+output_dir = "E:/鎶栭煶-AI椋庢櫙/鏂板缓鏂囦欢澶筡ProcessResults"
+
+cut_video_by_frames(target_file, selected_labels, frame_count, output_dir)
diff --git a/test/vlc_test.py b/test/vlc_test.py
new file mode 100644
index 0000000..ed5d492
--- /dev/null
+++ b/test/vlc_test.py
@@ -0,0 +1,106 @@
+import tkinter as tk
+from tkinter import ttk
+import vlc
+import os
+
+
+class VideoPlayer:
+    def __init__(self, root):
+        self.root = root
+        self.player = vlc.Instance()
+        self.is_playing = False
+        self.is_paused = False
+        self.listPlayer = None
+        self.create_ui()
+
+    def create_ui(self):
+        # Canvas to display video
+        self.canvas = tk.Canvas(self.root, width=640, height=360)
+        self.canvas.pack()
+
+        # Create play, pause, and stop buttons
+        self.play_button = tk.Button(self.root, text="Play", command=self.toggle_play_pause)
+        self.play_button.pack(side=tk.LEFT)
+
+        self.stop_button = tk.Button(self.root, text="Stop", command=self.stop)
+        self.stop_button.pack(side=tk.LEFT)
+
+        # Progress bar for video
+        self.progress_bar = ttk.Scale(self.root, from_=0, to=100, orient="horizontal", length=500, command=self.on_progress_drag)
+        self.progress_bar.pack()
+
+        # Start a thread to update progress bar
+        self.update_progress_task()
+
+    def add_video(self, video_path):
+        # Create media list and add video
+        self.mediaList = self.player.media_list_new()
+        self.media = self.player.media_new(video_path)
+        self.mediaList.add_media(self.media)
+
+        # Create MediaListPlayer and associate it with the media list
+        self.listPlayer = self.player.media_list_player_new()
+        self.listPlayer.set_media_list(self.mediaList)
+        self.listPlayer.set_playback_mode(vlc.PlaybackMode(1))
+
+    def play(self):
+        if self.listPlayer:
+            self.listPlayer.play()
+            self.is_playing = True
+            self.is_paused = False
+            self.play_button.config(text="Pause")
+
+    def stop(self):
+        if self.listPlayer:
+            self.listPlayer.stop()
+            self.is_playing = False
+            self.is_paused = False
+            self.play_button.config(text="Play")
+
+    def toggle_play_pause(self):
+        if self.is_playing:
+            self.listPlayer.pause()
+            self.is_playing = False
+            self.is_paused = True
+            self.play_button.config(text="Resume")
+        elif self.is_paused:
+            self.listPlayer.play()
+            self.is_playing = True
+            self.is_paused = False
+            self.play_button.config(text="Pause")
+        else:
+            self.play()
+
+    def update_progress_task(self):
+        # Continuously update the progress bar
+        if self.listPlayer:
+            current_time = self.listPlayer.get_media_player().get_time()  # Get current playback time
+            duration = self.listPlayer.get_media_player().get_length()  # Get video duration
+            if duration > 0:
+                progress = (current_time / duration) * 100  # Calculate progress percentage
+                self.progress_bar.set(progress)
+
+        # Call the function every 100 ms
+        self.root.after(100, self.update_progress_task)
+
+    def on_progress_drag(self, value):
+        # Seek the video to the dragged position
+        if self.listPlayer:
+            duration = self.listPlayer.get_media_player().get_length()
+            new_time = (float(value) / 100) * duration
+            self.listPlayer.get_media_player().set_time(int(new_time))
+
+
+def main():
+    root = tk.Tk()
+    root.title("VLC Video Player")
+
+    video_player = VideoPlayer(root)
+    video_path = "E:/鎶栭煶-AI椋庢櫙/data/鍏虫敞/1515593476095344/瑙嗛/7375164244729302272.mp4"  # 鏇挎崲涓哄疄闄呰棰戞枃浠惰矾寰�
+    video_player.add_video(video_path)  # Replace with the path to your video
+    # Start the Tkinter main loop
+    root.mainloop()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/tkv.py b/tkv.py
deleted file mode 100644
index 71c10b1..0000000
--- a/tkv.py
+++ /dev/null
@@ -1,467 +0,0 @@
-import tkinter as tk
-from tkinter import filedialog, messagebox, ttk,Canvas
-import os
-import numpy as np
-from PIL import Image, ImageTk
-import vlc
-import subprocess
-import functools
-import re
-
-
-# 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("Video Processing Tool")
-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=100, height=200, bg='yellow')
-control_frame.pack(side=tk.RIGHT, anchor="ne", padx=5, pady=5)
-
-# 绾跨▼鍑芥暟鏉ユ樉绀鸿棰�
-
-def on_playback_ended(event):
-    # player.play()
-    video_frame.pack_forget()  # 濡傛灉浣跨敤 pack()
-    global current_video_path
-    display_thumbnails(current_video_path)
-
-
-def toggle_play_pause():
-    if player.is_playing():
-        player.pause()  # 鏆傚仠鎾斁
-        play_pause_button.config(text="鎾斁瑙嗛")  # 鏇存柊鎸夐挳鏂囨湰涓烘挱鏀�
-    else:
-        player.play()  # 鎾斁
-        play_pause_button.config(text="鏆傚仠瑙嗛")  # 鏇存柊鎸夐挳鏂囨湰涓烘殏鍋�
-
-# 鏇存柊杩涘害鏉″苟澧炲姞璋冭瘯淇℃伅
-
-
-def update_progress():
-    # 纭繚鎾斁鍣ㄦ鍦ㄦ挱鏀�
-    if player.is_playing():
-        current_time = player.get_time() / 1000  # 姣杞负绉�
-        total_time = player.get_length() / 1000  # 姣杞负绉�
-        if total_time > 0:
-            progress_percentage = (current_time / total_time) * 100
-            progress_var.set(progress_percentage)
-        progress_bar.after(50, update_progress)
-    else:
-        progress_bar.after(50, update_progress)
-
-
-def get_thumbnail_frames(video_file):
-    # 鑾峰彇鍚屽悕鏂囦欢澶硅矾寰�
-    base_dir = os.path.dirname(video_file)
-    video_name = os.path.splitext(os.path.basename(video_file))[0]
-    thumbnail_dir = os.path.join(base_dir, video_name)
-
-    # 濡傛灉鏂囦欢澶逛笉瀛樺湪锛岃皟鐢� bat 鏂囦欢澶勭悊
-    if not os.path.exists(thumbnail_dir):
-        print(f"鏂囦欢澶� {thumbnail_dir} 涓嶅瓨鍦紝璋冪敤 bat 鏂囦欢杩涜澶勭悊...")
-        subprocess.run(['mp4_generate_thumbnails.bat', video_file], check=True)
-
-    # 閲嶆柊鑾峰彇鏂囦欢澶瑰唴鐨勬墍鏈� jpg 鏂囦欢
-    jpg_files = [os.path.join(thumbnail_dir, f) for f in os.listdir(
-        thumbnail_dir) if f.lower().endswith('.jpg')]
-    jpg_files.sort()  # 鎸夌収鏂囦欢鍚嶉『搴忔帓搴�
-
-    return jpg_files
-
-selected_labels = []  # 璁板綍褰撳墠閫変腑鐨勬爣绛�
-thumbnails = []
-
-def display_thumbnails(video_file):
-    global thumbnails, selected_labels
-    thumbnails = get_thumbnail_frames(video_file)
-    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)
-
-    # 鍒涘缓涓�涓猣rame浣滀负Canvas鐨勫瓙椤规潵娣诲姞缂╃暐鍥�
-    thumbnail_container = tk.Frame(canvas)
-    canvas.create_window((0, 0), window=thumbnail_container, anchor="nw")
-
-    # 鍚敤榧犳爣婊氳疆浜嬩欢鏉ユ粴鍔–anvas
-    def on_mouse_wheel(event):
-        """澶勭悊榧犳爣婊氳疆浜嬩欢"""
-        canvas.yview_scroll(int(-1 * (event.delta / 120)), "units")
-
-    # 缁戝畾榧犳爣婊氳疆浜嬩欢
-    canvas.bind_all("<MouseWheel>", on_mouse_wheel)
-
-    # 娣诲姞缂╃暐鍥�
-    for idx, thumb in enumerate(thumbnails):
-        # 浣跨敤PIL鍔犺浇鍥剧墖
-        pil_image = Image.open(thumb)
-
-        # 杞崲涓篢kinter鍙樉绀虹殑鏍煎紡
-        photo = ImageTk.PhotoImage(pil_image)
-
-        # 鍒涘缓涓�涓爣绛炬樉绀哄浘鍍�
-        thumb_label = tk.Label(thumbnail_container, image=photo)
-        thumb_label.image = photo  # 蹇呴』淇濇寔瀵瑰浘鍍忕殑寮曠敤
-        thumb_label.grid(row=row, column=col, padx=1, pady=1)
-
-        # 灏唗oggle_checkmark鐨勮皟鐢ㄧ敤 functools.partial鍖呰锛屼紶閫抜dx
-        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, pil_image)
-            selected_labels.append(idx)
-
-        # 灏哻heckmark_label淇濆瓨鍦ㄦ爣绛句腑锛屽悗缁偣鍑绘椂鍙互鍙傝��
-        thumb_label.checkmark_label = checkmark_label
-
-        # 鏇存柊鍒楁暟鍜岃鏁�
-        col += 1
-        if col >= max_col:
-            col = 0
-            row += 1
-
-    # 鏇存柊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 ==len(thumbnails)-1:
-            return
-        pil_image = Image.open(thumbnails[idx])
-        checkmark_label = add_checkmark_icon(label, pil_image)
-        label.checkmark_label = checkmark_label
-        selected_labels.append(idx)
-    
-    #print(selected_labels)
-
-
-def add_checkmark_icon(thumb_label, pil_image):
-    """鍦ㄥ浘鍍忎笂娣诲姞鍕鹃�夊浘鏍�"""
-    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=pil_image.width - 15, y=5, anchor="ne")  # 纭繚鍥炬爣浣嶇疆鍦ㄥ彸涓婅
-
-    return checkmark_label
-
-
-def show_large_image(image):
-    # 鍒涘缓涓�涓柊鐨勭獥鍙f潵鏄剧ず澶у浘
-    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):
-    total_time = player.get_length() / 1000  # 瑙嗛鎬绘椂闀匡紙绉掞級
-    new_time = (event.x / progress_bar.winfo_width()) * total_time  # 璁$畻鏂扮殑鏃堕棿
-    player.set_time(int(new_time * 1000))  # 璁剧疆鏂版椂闂达紙姣锛�
-
-
-player = vlc.MediaPlayer()
-player.event_manager().event_attach(
-    vlc.EventType.MediaPlayerEndReached, on_playback_ended)
-
-canvas = Canvas(video_frame, width=1080, height=1920)  # 璁剧疆Canvas澶у皬
-canvas.pack(side=tk.BOTTOM, pady=10)  # Video player area under progress bar
-
-# 鍒濆鍖� VLC 鎾斁鍣�
-# Windows 浣跨敤 set_hwnd(embed.winfo_id())锛孡inux 浣跨敤 set_xwindow(embed.winfo_id())
-player.set_hwnd(canvas.winfo_id())
-
-
-# 瑙嗛杩涘害鏉�
-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.BOTTOM, pady=10)
-
-# 缁戝畾杩涘害鏉$偣鍑讳簨浠讹紝璺宠浆鍒版寚瀹氭椂闂�
-progress_bar.bind("<ButtonRelease-1>", on_progress_change)
-
-update_progress()
-# 璁剧疆涓荤獥鍙�
-# Functions
-
-output_dir = ""
-
-def open_folder():
-    global output_dir
-    """Open folder and get all MP4 files"""
-    folder = filedialog.askdirectory()
-    if not folder:
-        return
-
-    global video_files
-    video_files = []
-    for root_dir, dirs, files in os.walk(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("鏂囦欢澶癸細"+folder+ ",鏂囦欢鏁伴噺锛�"+str(len(video_files)))
-        root.update()  # 鍒锋柊鐣岄潰
-        load_video(video_files[0])
-
-        output_dir = os.path.join(folder, "ProcessResults")
-        create_folders(output_dir)
-    else:
-        messagebox.showerror("Error", "娌℃湁鎵惧埌MP4鏂囦欢")
-
-
-def load_video(video_path):
-    """Load video into the player and start playback"""
-    global current_video_path, video_player
-    current_video_path = video_path
-    thumbnail_frame.pack_forget()
-    video_frame.pack(side=tk.LEFT, padx=0)
-    player.set_media(vlc.Media(current_video_path))
-    player.play()
-
-
-def delete_video():
-    """Delete current video and play the next"""
-    global current_video_idx
-    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 split_video():
-    """Delete current video and play the next"""
-    global current_video_idx
-    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
-
-        cut_video_by_frames(save_hook_,save_music_,target_file,selected_labels,len(thumbnails),output_dir)
-
-        current_video_idx += 1
-        if current_video_idx < len(video_files):
-            load_video(video_files[current_video_idx])
-        else:
-            messagebox.showinfo("Info", "澶勭悊瀹屾瘯锛�")
-
-def update_title_minus_one():
-    current_title = root.title()
-    parts = current_title.rsplit("锛�", 1)
-    if len(parts) == 2 and parts[1].isdigit():
-        new_count = int(parts[1]) - 1
-        new_title = f"{parts[0]}锛歿new_count}"
-        root.title(new_title)
-        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 cut_video_by_frames(save_hook,save_music,video_path, frame_segments, total_frames, output_dir):
-    """
-    灏嗚棰戞寜鐓ф寚瀹氱殑甯у垏鐗囪繘琛屽垏鍓层��
-
-    鍙傛暟锛�
-    - video_path: 杈撳叆瑙嗛鐨勮矾寰�
-    - frame_segments: 鍒囩墖鐨勫抚搴忓彿鏁扮粍锛屼緥濡傦細[0, M1, M2, ..., Mlast]
-    - output_dir: 杈撳嚭瑙嗛鏂囦欢鐨勭洰褰�
-    """
-    fps = 30   # default fps
-    frame_segments.sort()
-
-    # 鑾峰彇瑙嗛鐨勫抚鐜� (fps)
-    command = [
-        "ffmpeg", "-i", video_path, "-vf", "fps=1", "-f", "null", "-"
-    ]
-    result = subprocess.run(command, stdout=subprocess.PIPE,
-                            stderr=subprocess.PIPE, text=True, encoding='utf-8')
-
-    if result.returncode != 0:
-        print(f"Error occurred while executing the command: {result.stderr}")
-    else:
-        output = result.stderr
-
-    if output:
-        fps_line = next(line for line in output.splitlines() if 'fps' in line)
-        # 浣跨敤姝e垯琛ㄨ揪寮忔彁鍙栧抚鐜囧�硷紙鍋囪fps鍊兼�绘槸鍑虹幇鍦�"fps"鍓嶉潰锛�
-        match = re.search(r'(\d+(\.\d+)?)\s*fps', fps_line)
-        if match:
-            fps = float(match.group(1))  # 鎻愬彇骞惰浆鎹负 float
-        print(f"FPS: {fps}")
-    else:
-        print("No output from ffmpeg")
-
-
-    print(f"瑙嗛鐨勬�诲抚鏁�: {total_frames}, 甯х巼: {fps}")
-
-    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")
-        command = ["ffmpeg", "-i", video_path, "-vn", 
-        "-acodec", "pcm_s16le","-ar", "44100","-ac", "2", output_file]
-    subprocess.Popen(command)
-
-    # 閬嶅巻鍒囩墖鍖洪棿
-    for i in range(len(frame_segments) - 1):
-        start_frame = frame_segments[i]
-        end_frame = frame_segments[i + 1]
-
-        
-        start_time = float(start_frame) / fps
-        end_time = float(end_frame) / fps
-
-        if save_hook and i==0:
-            output_file = os.path.join(os.path.join(output_dir,"hook"), f"{file_name_witout_extension}.mp4")
-        else:
-            output_file = os.path.join(os.path.join(output_dir,"slice"), f"{file_name_witout_extension}_{i + 1}.mp4")
-
-        
-        # 浣跨敤 FFmpeg 鍛戒护鏉ュ垏鍓茶棰�
-        command = [
-            "ffmpeg", "-i", video_path, "-ss", f"{start_time:.10f}", "-to", f"{end_time:.10f}",
-            "-c:v", "libx264", "-crf", "18","-preset", "veryslow", output_file
-        ]
-        print(" ".join(command))
-       
-        subprocess.Popen(command)
-
-    # 鏈�鍚庝竴娈靛鐞嗭紙浠庢渶鍚庝竴涓垏鐗囧埌瑙嗛缁撴潫锛�
-    last_start_frame = frame_segments[-1]
-    last_start_time = last_start_frame / fps
-    output_file = os.path.join(
-        os.path.join(output_dir,"slice"), f"{file_name_witout_extension}_{len(frame_segments)}.mp4")
-
-    #print(f"姝e湪鍒囧壊鏈�鍚庝竴娈碉細浠� {last_start_time:.10f}s 鍒拌棰戠粨鏉燂紝淇濆瓨涓� {output_file}")
-    command = [
-        "ffmpeg", "-i", video_path, "-ss", f"{last_start_time:.10f}",
-        "-c:v", "libx264","-crf", "18","-preset", "veryslow", output_file
-    ]
-    print(" ".join(command))
-    subprocess.Popen(command)
-
-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)
-open_folder_button.pack()
-
-# 鎾斁鎺у埗鎸夐挳锛堟挱鏀�/鏆傚仠锛�
-play_pause_button = tk.Button(control_frame, text="鏆傚仠瑙嗛", command=toggle_play_pause)
-play_pause_button.pack()
-
-delete_button = tk.Button(control_frame, text="涓嶄繚鐣�", command=delete_video)
-delete_button.pack()
-
-save_hook = tk.IntVar(value=1)  # 榛樿鍕鹃��
-save_music = tk.IntVar(value=1)  # 榛樿鍕鹃��
-
-# 鍒涘缓涓や釜 Checkbutton
-checkbox1 = tk.Checkbutton(control_frame, text="淇濆瓨Hook瑙嗛", variable=save_hook)
-checkbox1.pack()
-
-checkbox2 = tk.Checkbutton(control_frame, text="淇濆瓨闊抽", variable=save_music)
-checkbox2.pack()
-
-
-
-delete_button = tk.Button(control_frame, text="鎷嗗垎", command=split_video)
-delete_button.pack()
-
-
-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)
-
-#video_frame.pack_forget()
-
-#display_thumbnails("E:\鎶栭煶-AI椋庢櫙\鏂板缓鏂囦欢澶筡_demoold")
-# Start the Tkinter loop
-root.mainloop()
diff --git a/video-splitor.py b/video-splitor.py
new file mode 100644
index 0000000..154b9c7
--- /dev/null
+++ b/video-splitor.py
@@ -0,0 +1,694 @@
+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("绠�鏄撹棰戞媶瑙e伐鍏� 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)
+
+    # 鍒涘缓涓�涓猣rame浣滀负Canvas鐨勫瓙椤规潵娣诲姞缂╃暐鍥�
+    thumbnail_container = tk.Frame(canvas)
+    canvas.create_window((0, 0), window=thumbnail_container, anchor="nw")
+
+    # 鍚敤榧犳爣婊氳疆浜嬩欢鏉ユ粴鍔–anvas
+    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))
+        # 杞崲涓篢kinter鍙敤鐨凱hotoImage鏍煎紡
+        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)
+
+        # 灏唗oggle_checkmark鐨勮皟鐢ㄧ敤 functools.partial鍖呰锛屼紶閫抜dx
+        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)
+        # 灏哻heckmark_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):
+    # 鍒涘缓涓�涓柊鐨勭獥鍙f潵鏄剧ず澶у浘
+    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  # 涓嶅寘鍚玡nd_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="闊抽(闄ook闊抽)", 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()
diff --git a/videosplitorV0.1.spec b/videosplitorV0.1.spec
index ee534d0..ba98d2c 100644
--- a/videosplitorV0.1.spec
+++ b/videosplitorV0.1.spec
@@ -3,9 +3,11 @@
 import os
 import shutil
 from PyInstaller.utils.hooks import collect_all
+import zipfile
+import time
 
 a = Analysis(
-    ['tkv.py'],
+    ['video-splitor.py'],
     pathex=[],
     binaries=[],
     datas=[],
@@ -43,21 +45,14 @@
 
 # 瀹氫箟棰濆鎷疯礉鐨勬枃浠�
 path_ffmpeg = os.path.join(os.getcwd(), 'ffmpeg.exe')
-path_thumb = os.path.join(os.getcwd(), 'mp4_generate_thumbnails.bat')
 path_checkmark = os.path.join(os.getcwd(), 'checkmark.png')
-path_libvlc = os.path.join(os.getcwd(), 'libvlc.dll')
-path_libvlccore = os.path.join(os.getcwd(), 'libvlccore.dll')
-
-plugins_path = os.path.join(os.getcwd(), 'plugins')
+path_vlc_plugins = os.path.join(os.getcwd(), 'VLC.zip')
 
 # 灏� ffmpeg.exe 鍜� plugins 鏂囦欢澶规坊鍔犲埌 EXE 鐨勫悓绾х洰褰�
 datas = [
     (path_ffmpeg, '.'), 
-    (path_thumb, '.'),  
-    (path_checkmark, '.'),  
-    (path_libvlc, '.'),  
-    (path_libvlccore, '.'),  
-    (plugins_path, 'plugins') 
+    (path_checkmark, '.'),
+    (path_vlc_plugins, '.')
 ]
 
 
@@ -67,27 +62,18 @@
     # 鑾峰彇鐢熸垚鐨� dist 鐩綍
     dist_dir = os.path.join(os.getcwd(), 'dist')
     
-    # 閫掑綊鎷疯礉 plugins 鐩綍
-    if os.path.exists(plugins_path):
-        destination_plugins = os.path.join(dist_dir, 'plugins')
-        shutil.copytree(plugins_path, destination_plugins)
-    
     if os.path.exists(path_ffmpeg):
         shutil.copy(path_ffmpeg, dist_dir)
     
-    if os.path.exists(path_thumb):
-        shutil.copy(path_thumb, dist_dir)
-    
     if os.path.exists(path_checkmark):
         shutil.copy(path_checkmark, dist_dir)
-    
-    if os.path.exists(path_libvlc):
-        shutil.copy(path_libvlc, dist_dir)
-    
-    if os.path.exists(path_libvlccore):
-        shutil.copy(path_libvlccore, dist_dir)
+
+    if os.path.exists(path_vlc_plugins):
+        copied_file_path = shutil.copy(path_vlc_plugins, dist_dir)
+        with zipfile.ZipFile(copied_file_path, 'r') as zip_ref:
+            zip_ref.extractall(dist_dir)
+        time.sleep(1)  # 绛夊緟璧勬簮閲婃斁
+        os.remove(copied_file_path)
 
 # 鍦ㄦ墦鍖呭悗鐨勫簲鐢ㄤ腑鎵ц鏂囦欢鎷疯礉鎿嶄綔
-post_processing_hook(exe)
-
-
+post_processing_hook(exe)
\ No newline at end of file

--
Gitblit v1.9.1