import tkinter as tk
from tkinter import messagebox, ttk
import vlc
import time
class CustomSlider(tk.Canvas):
def __init__(self, master, **kwargs):
super().__init__(master, **kwargs)
self.bind("", self.on_click)
self.value = 0
self.command = None
def set(self, value):
self.value = value
self.update()
def update(self):
self.delete("all")
width = self.winfo_width()
height = self.winfo_height()
filled_width = int(self.value * width / 100)
self.create_rectangle(0, 0, width, height, fill="grey", outline="")
self.create_rectangle(0, 0, filled_width, height, fill="green", outline="")
def on_click(self, event):
width = self.winfo_width()
click_position = event.x / width
self.value = int(click_position * 100)
self.update()
if self.command:
self.command(self.value)
class PlaylistWindow(tk.Toplevel):
def __init__(self, master, playlist, play_function):
super().__init__(master)
self.title("Playlist")
self.geometry("300x400")
self.protocol("WM_DELETE_WINDOW", self.hide_window)
self.listbox = tk.Listbox(self)
self.listbox.pack(fill=tk.BOTH, expand=True)
for item in playlist:
self.listbox.insert(tk.END, item['name'])
# Thay đổi từ double-click sang single-click
self.listbox.bind('', lambda e: play_function(self.listbox.curselection()[0]))
# Thêm nút "Play Selected"
self.play_button = tk.Button(self, text="Play Selected", command=self.play_selected)
self.play_button.pack(fill=tk.X)
self.play_function = play_function
def play_selected(self):
selection = self.listbox.curselection()
if selection:
self.play_function(selection[0])
def hide_window(self):
self.withdraw()
class VideoPlayer(tk.Tk):
def __init__(self, playlist):
super().__init__()
# Thêm biến playlist và chỉ mục hiện tại
self.playlist = playlist
self.current_index = 0
# Cài đặt kích thước giao diện
self.title("M3U8 Video Player")
self.geometry("900x650")
# Biến để kiểm tra trạng thái toàn màn hình
self.fullscreen = False
# Tạo một frame để hiển thị video
self.video_frame = tk.Frame(self, bg='black')
self.video_frame.pack(fill=tk.BOTH, expand=1)
# Khởi tạo trình phát video VLC
self.instance = vlc.Instance()
self.player = self.instance.media_player_new()
# Lấy handle của frame để nhúng video
self.player.set_hwnd(self.video_frame.winfo_id())
# Khởi tạo video đầu tiên
self.load_video(self.playlist[self.current_index]['url'])
# Tự động phát video khi khởi động
self.after(1000, self.auto_start_playback)
# Thêm nút điều khiển và thanh thời gian
self.control_frame = tk.Frame(self)
self.control_frame.pack(side=tk.BOTTOM, fill=tk.X)
self.play_pause_button = tk.Button(self.control_frame, text="Play", command=self.toggle_play_pause)
self.play_pause_button.pack(side=tk.LEFT)
# Thanh thời gian tùy chỉnh
self.time_slider = CustomSlider(self.control_frame, height=20)
self.time_slider.pack(side=tk.LEFT, fill=tk.X, expand=1)
self.time_slider.command = self.seek_to_time
# Hiển thị thời gian hiện tại và tổng thời gian
self.current_time_label = tk.Label(self.control_frame, text="00:00:00")
self.current_time_label.pack(side=tk.LEFT)
self.total_time_label = tk.Label(self.control_frame, text="00:00:00")
self.total_time_label.pack(side=tk.LEFT)
# Điều khiển âm lượng
self.volume_slider = tk.Scale(self.control_frame, from_=0, to=100, orient=tk.HORIZONTAL, command=self.set_volume)
self.volume_slider.set(100) # Đặt âm lượng mặc định là 100%
self.volume_slider.pack(side=tk.LEFT)
# Nút toàn màn hình
fullscreen_button = tk.Button(self.control_frame, text="Toàn màn hình", command=self.toggle_fullscreen)
fullscreen_button.pack(side=tk.LEFT)
# Thêm nút chuyển bài
next_button = tk.Button(self.control_frame, text="Next", command=self.next_video)
next_button.pack(side=tk.LEFT)
prev_button = tk.Button(self.control_frame, text="Previous", command=self.prev_video)
prev_button.pack(side=tk.LEFT)
# Thêm nút Playlist
self.playlist_button = tk.Button(self.control_frame, text="Playlist", command=self.toggle_playlist_window)
self.playlist_button.pack(side=tk.LEFT)
# Tạo cửa sổ playlist (ban đầu là ẩn)
self.playlist_window = PlaylistWindow(self, playlist, self.play_from_playlist)
self.playlist_window.withdraw()
# Bắt đầu cập nhật thời gian
self.update_time()
# Bắt sự kiện tương tác chuột và bàn phím
self.bind("", self.show_controls)
self.bind("", self.show_controls)
# Timer để ẩn giao diện khi không tương tác
self.hide_controls_timer = None
# Thêm binding cho các phím tắt
self.bind("", lambda e: self.toggle_play_pause())
self.bind("", lambda e: self.seek(-5))
self.bind("", lambda e: self.seek(5))
self.bind("", lambda e: self.change_volume(5))
self.bind("", lambda e: self.change_volume(-5))
# Thêm binding cho phím Esc
self.bind("", self.exit_fullscreen)
def auto_start_playback(self):
self.play()
self.play_pause_button.config(text="Pause")
def play(self):
self.player.play()
self.play_pause_button.config(text="Pause")
def pause(self):
self.player.pause()
self.play_pause_button.config(text="Play")
def seek(self, seconds):
current_time = self.player.get_time()
new_time = current_time + seconds * 1000 # Chuyển đổi giây sang mili giây
self.player.set_time(new_time)
def seek_to_time(self, value):
total_length = self.player.get_length()
new_time = int(value) * total_length / 100
self.player.set_time(int(new_time))
def set_volume(self, value):
self.player.audio_set_volume(int(value))
def change_volume(self, delta):
current_volume = self.player.audio_get_volume()
new_volume = max(0, min(100, current_volume + delta))
self.player.audio_set_volume(new_volume)
self.volume_slider.set(new_volume)
def toggle_play_pause(self, event=None):
if self.player.is_playing():
self.pause()
else:
self.play()
def toggle_fullscreen(self):
self.fullscreen = not self.fullscreen
if self.fullscreen:
self.attributes("-fullscreen", True)
self.control_frame.pack_forget() # Ẩn control frame
else:
self.exit_fullscreen()
def exit_fullscreen(self, event=None):
if self.fullscreen:
self.fullscreen = False
self.attributes("-fullscreen", False)
self.control_frame.pack(side=tk.BOTTOM, fill=tk.X) # Hiện lại control frame
def update_time(self):
if self.player.is_playing():
current_time = self.player.get_time()
total_length = self.player.get_length()
# Cập nhật thanh trượt thời gian
if total_length > 0:
slider_value = int(current_time * 100 / total_length)
self.time_slider.set(slider_value)
# Cập nhật hiển thị thời gian
current_time_str = self.format_time(current_time)
total_time_str = self.format_time(total_length)
self.current_time_label.config(text=current_time_str)
self.total_time_label.config(text=total_time_str)
self.after(100, self.update_time)
def format_time(self, milliseconds):
seconds, milliseconds = divmod(milliseconds, 1000)
minutes, seconds = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)
return "{:02d}:{:02d}:{:02d}".format(int(hours), int(minutes), int(seconds))
def show_controls(self, event):
if self.fullscreen:
self.control_frame.pack(side=tk.BOTTOM, fill=tk.X)
if self.hide_controls_timer:
self.after_cancel(self.hide_controls_timer)
self.hide_controls_timer = self.after(2000, self.hide_controls)
def hide_controls(self):
if self.fullscreen:
self.control_frame.pack_forget()
def load_video(self, url):
media = self.instance.media_new(url)
self.player.set_media(media)
self.update_title()
def update_title(self):
current_video = self.playlist[self.current_index]
self.title(f"Now Playing: {current_video['name']}")
def toggle_playlist_window(self):
if self.playlist_window.winfo_viewable():
self.playlist_window.hide_window()
else:
self.playlist_window.deiconify()
def play_from_playlist(self, index):
if 0 <= index < len(self.playlist):
self.current_index = index
self.load_video(self.playlist[self.current_index]['url'])
self.play()
self.playlist_window.listbox.selection_clear(0, tk.END)
self.playlist_window.listbox.selection_set(self.current_index)
self.playlist_window.listbox.see(self.current_index) # Đảm bảo mục được chọn luôn hiển thị
def next_video(self):
self.current_index = (self.current_index + 1) % len(self.playlist)
self.load_video(self.playlist[self.current_index]['url'])
self.play()
self.playlist_window.listbox.selection_clear(0, tk.END)
self.playlist_window.listbox.selection_set(self.current_index)
self.playlist_window.listbox.see(self.current_index)
def prev_video(self):
self.current_index = (self.current_index - 1) % len(self.playlist)
self.load_video(self.playlist[self.current_index]['url'])
self.play()
self.playlist_window.listbox.selection_clear(0, tk.END)
self.playlist_window.listbox.selection_set(self.current_index)
self.playlist_window.listbox.see(self.current_index)
def on_closing(self):
self.player.stop()
self.destroy()
if __name__ == "__main__":
playlist = [
{"name": "Spy x Family Episode 1", "url": "https://raw.githubusercontent.com/Huyenuiio/gittesst2/spyxfamily/spyxfamilycodewhite/output.m3u8"},
{"name": "Another Episode", "url": "https://raw.githubusercontent.com/Huyenuiio/fsfafafewwkjawekfj/main/ep1/output.m3u8"},
# Thêm các mục khác vào đây
]
app = VideoPlayer(playlist)
app.protocol("WM_DELETE_WINDOW", app.on_closing)
app.mainloop()
Tags:
python watch anime