Playlist logic fixes, always use latest playlist version, VLC-only image display, and bugfixes

This commit is contained in:
2025-08-26 16:14:53 +03:00
parent f4c73b54f7
commit 22901043b7
13 changed files with 139 additions and 67 deletions

View File

@@ -1,7 +1,6 @@
import os
import json
import tkinter as tk
from PIL import Image, ImageTk
import vlc
import subprocess
import sys
@@ -121,8 +120,21 @@ class SimpleTkPlayer:
self.show_current_media()
def next_media(self):
self.current_index = (self.current_index + 1) % len(self.playlist)
self.show_current_media()
# If at the last media, update playlist before looping
if self.current_index == len(self.playlist) - 1:
self.update_playlist_from_server()
self.current_index = 0
self.show_current_media()
else:
self.current_index = (self.current_index + 1) % len(self.playlist)
self.show_current_media()
def update_playlist_from_server(self):
# Dummy implementation: replace with your actual update logic
# For example, call a function to fetch and reload the playlist
print("[INFO] Updating playlist from server...")
# You can import and call your real update function here
# Example: self.playlist = get_latest_playlist()
def toggle_pause(self):
if not self.paused:
@@ -184,39 +196,49 @@ class SimpleTkPlayer:
return
media = self.playlist[self.current_index]
file_path = os.path.join(MEDIA_DATA_PATH, media['file_name'])
if file_path.lower().endswith(('.mp4', '.avi', '.mov', '.mkv')):
ext = file_path.lower()
if ext.endswith(('.mp4', '.avi', '.mov', '.mkv')):
self.show_video(file_path, on_end=self.next_media)
elif file_path.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp', '.gif')):
try:
img = Image.open(file_path)
# Fit to screen without crop or stretch
screen_w = self.root.winfo_screenwidth()
screen_h = self.root.winfo_screenheight()
img_w, img_h = img.size
scale = min(screen_w / img_w, screen_h / img_h)
new_w = int(img_w * scale)
new_h = int(img_h * scale)
img = img.resize((new_w, new_h), Image.LANCZOS)
bg = Image.new('RGB', (screen_w, screen_h), 'black')
x = (screen_w - new_w) // 2
y = (screen_h - new_h) // 2
bg.paste(img, (x, y))
photo = ImageTk.PhotoImage(bg)
self.label.config(image=photo, text='')
self.label.image = photo
except Exception as e:
self.label.config(text=f"Image error: {e}", fg='red')
elif ext.endswith(('.jpg', '.jpeg', '.png', '.bmp', '.gif')):
self.show_image_via_vlc(file_path, media.get('duration', 10), on_end=self.next_media)
else:
self.label.config(text=f"Unsupported: {media['file_name']}", fg='yellow')
def show_image_via_vlc(self, file_path, duration, on_end=None):
# Use VLC to show image for a set duration
if hasattr(self, 'vlc_player') and self.vlc_player:
self.vlc_player.stop()
if not hasattr(self, 'video_canvas'):
self.video_canvas = tk.Canvas(self.root, bg='black', highlightthickness=0)
self.video_canvas.pack(fill=tk.BOTH, expand=True)
self.label.pack_forget()
self.video_canvas.pack(fill=tk.BOTH, expand=True)
self.root.attributes('-fullscreen', True)
self.root.update_idletasks()
self.vlc_instance = vlc.Instance('--vout=x11')
self.vlc_player = self.vlc_instance.media_player_new()
self.vlc_player.set_mrl(file_path)
self.vlc_player.set_fullscreen(True)
self.vlc_player.set_xwindow(self.video_canvas.winfo_id())
self.vlc_player.play()
# Schedule stop and next after duration
def finish_image():
self.vlc_player.stop()
self.video_canvas.pack_forget()
self.label.pack(fill=tk.BOTH, expand=True)
if on_end:
on_end()
self.root.after(int(duration * 1000), finish_image)
def next_media(self):
self.current_index = (self.current_index + 1) % len(self.playlist)
self.show_current_media()
def next_media_loop(self):
if not self.playlist or self.paused:
self.root.after(1000, self.next_media_loop)
return
duration = self.playlist[self.current_index].get('duration', 10)
self.current_index = (self.current_index + 1) % len(self.playlist)
self.show_current_media()
self.root.after(duration * 1000, self.next_media_loop)
def exit_app(self):
# Signal the update thread to stop if stop_event is present
@@ -281,20 +303,9 @@ def load_latest_playlist():
files = [f for f in os.listdir(PLAYLIST_DIR) if f.startswith('server_playlist_v') and f.endswith('.json')]
if not files:
return []
# Sort by version number descending
files.sort(key=lambda x: int(x.split('_v')[-1].split('.json')[0]), reverse=True)
with open(os.path.join(PLAYLIST_DIR, files[0]), 'r') as f:
latest_file = files[0]
with open(os.path.join(PLAYLIST_DIR, latest_file), 'r') as f:
data = json.load(f)
return data.get('playlist', [])
def main():
root = tk.Tk()
root.title("Simple Tkinter Player")
root.configure(bg='black')
root.attributes('-fullscreen', True)
playlist = load_latest_playlist()
player = SimpleTkPlayer(root, playlist)
player.main_start()
root.mainloop()
if __name__ == '__main__':
main()