wangzhibo
2024-12-04 4c5a1f2f09f6906bf26a783d2fa345a5886a2335
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
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()