-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvideo_player.py
126 lines (104 loc) · 4.09 KB
/
video_player.py
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
115
116
117
118
119
120
121
122
123
124
125
126
import tkinter as tk
from tkinter import ttk
import vlc
import os
class VideoPlayer:
def __init__(self, parent, width=400, height=300):
"""Initialize the video player with VLC backend."""
self.instance = vlc.Instance()
self.player = self.instance.media_player_new()
# Create a frame to hold the video
self.frame = ttk.Frame(parent)
if os.name == "nt": # Windows
self.player.set_hwnd(self.frame.winfo_id())
else: # Linux/Mac
self.player.set_xwindow(self.frame.winfo_id())
self.frame.configure(width=width, height=height)
# Create control buttons frame
self.controls = ttk.Frame(parent)
# Play/Pause button
self.play_button = ttk.Button(self.controls, text="Pause", command=self.toggle_play)
self.play_button.pack(side=tk.LEFT, padx=5)
# Volume control
self.volume_scale = ttk.Scale(
self.controls,
from_=0,
to=100,
orient=tk.HORIZONTAL,
command=self.set_volume
)
self.volume_scale.set(100)
self.volume_scale.pack(side=tk.LEFT, padx=5)
# Progress bar
self.progress_var = tk.DoubleVar()
self.progress_scale = ttk.Scale(
self.controls,
from_=0,
to=1000,
orient=tk.HORIZONTAL,
variable=self.progress_var
)
self.progress_scale.pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True)
# Bind events for seeking
self.progress_scale.bind("<Button-1>", self.start_seek)
self.progress_scale.bind("<ButtonRelease-1>", self.end_seek)
self.is_seeking = False
self.update_id = None
def start_seek(self, event):
"""Called when user starts dragging the seek bar"""
self.is_seeking = True
def end_seek(self, event):
"""Called when user releases the seek bar"""
if self.is_seeking:
# Get the final position and seek there
pos = self.progress_var.get() / 1000.0
self.player.set_position(pos)
self.is_seeking = False
def load_video(self, path: str):
"""Load a video file into the player."""
self.stop() # Stop any existing playback
media = self.instance.media_new(str(path))
self.player.set_media(media)
# Wait for media to be parsed
media.parse()
self.player.play()
self.play_button.configure(text="Pause")
self._start_progress_update()
def toggle_play(self):
"""Toggle between play and pause states."""
if self.player.is_playing():
self.player.pause()
self.play_button.configure(text="Play")
else:
self.player.play()
self.play_button.configure(text="Pause")
def set_volume(self, value):
"""Set the player volume."""
self.player.audio_set_volume(int(float(value)))
def _start_progress_update(self):
"""Start the progress update timer."""
if self.update_id:
self.frame.after_cancel(self.update_id)
self._update_progress()
def _update_progress(self):
"""Update the progress bar to match video position."""
if self.player.is_playing() and not self.is_seeking:
try:
position = self.player.get_position() * 1000
self.progress_var.set(position)
except:
pass
self.update_id = self.frame.after(100, self._update_progress)
def stop(self):
"""Stop video playback."""
if self.update_id:
self.frame.after_cancel(self.update_id)
self.update_id = None
self.player.stop()
self.progress_var.set(0)
self.play_button.configure(text="Play")
def cleanup(self):
"""Release all resources."""
self.stop()
self.player.release()
self.instance.release()