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

@@ -2,7 +2,7 @@
"screen_orientation": "Landscape", "screen_orientation": "Landscape",
"screen_name": "tv-terasa", "screen_name": "tv-terasa",
"quickconnect_key": "8887779", "quickconnect_key": "8887779",
"server_ip": "digi-signage.moto-adv.com", "server_ip": "192.168.1.22",
"port": "80", "port": "80",
"screen_w": "1920", "screen_w": "1920",
"screen_h": "1080", "screen_h": "1080",

View File

@@ -323,3 +323,69 @@
[INFO] [SignageApp] File Banner_poarta_2_x6.jpg already exists. Skipping download. [INFO] [SignageApp] File Banner_poarta_2_x6.jpg already exists. Skipping download.
[INFO] [SignageApp] Preparing to download WhatsApp_Video_2025-08-21_at_18.34.19_86a6f243.mp4 from http://digi-signage.moto-adv.com/media/WhatsApp_Video_2025-08-21_at_18.34.19_86a6f243.mp4... [INFO] [SignageApp] Preparing to download WhatsApp_Video_2025-08-21_at_18.34.19_86a6f243.mp4 from http://digi-signage.moto-adv.com/media/WhatsApp_Video_2025-08-21_at_18.34.19_86a6f243.mp4...
[INFO] [SignageApp] File WhatsApp_Video_2025-08-21_at_18.34.19_86a6f243.mp4 already exists. Skipping download. [INFO] [SignageApp] File WhatsApp_Video_2025-08-21_at_18.34.19_86a6f243.mp4 already exists. Skipping download.
[INFO] [SignageApp] Fetching playlist from URL: http://192.168.1.22:80/api/playlists with params: {'hostname': 'tv-terasa', 'quickconnect_code': '8887779'}
[ERROR] [SignageApp] Failed to fetch playlist. Status Code: 404
[INFO] [SignageApp] Local playlist version: 0, Server playlist version: 0
[INFO] [SignageApp] Local playlist is already up to date.
[INFO] [SignageApp] Fetching playlist from URL: http://192.168.1.22:80/api/playlists with params: {'hostname': 'tv-terasa', 'quickconnect_code': '8887779'}
[INFO] [SignageApp] Server response: {'hashed_quickconnect': '$2b$12$Prw4EUYn4j59CAdsZCsvsug6.xociqbOPaNr0oxOA2zwD9S2MSiK6', 'playlist': [{'duration': 30, 'file_name': 'big-buck-bunny-1080p-60fps-30sec.mp4', 'url': 'http://192.168.1.22/media/big-buck-bunny-1080p-60fps-30sec.mp4'}, {'duration': 15, 'file_name': 'demo2.jpeg', 'url': 'http://192.168.1.22/media/demo2.jpeg'}], 'playlist_version': 3}
[INFO] [SignageApp] Fetched updated playlist from server.
[INFO] [SignageApp] Local playlist version: 0, Server playlist version: 3
[INFO] [SignageApp] Preparing to download big-buck-bunny-1080p-60fps-30sec.mp4 from http://192.168.1.22/media/big-buck-bunny-1080p-60fps-30sec.mp4...
[INFO] [SignageApp] Successfully downloaded big-buck-bunny-1080p-60fps-30sec.mp4 to /home/pi/Desktop/tkinter_player/signage_player/static_data/media/big-buck-bunny-1080p-60fps-30sec.mp4
[INFO] [SignageApp] Preparing to download demo2.jpeg from http://192.168.1.22/media/demo2.jpeg...
[INFO] [SignageApp] Successfully downloaded demo2.jpeg to /home/pi/Desktop/tkinter_player/signage_player/static_data/media/demo2.jpeg
[INFO] [SignageApp] Fetching playlist from URL: http://192.168.1.22:80/api/playlists with params: {'hostname': 'tv-terasa', 'quickconnect_code': '8887779'}
[INFO] [SignageApp] Server response: {'hashed_quickconnect': '$2b$12$Prw4EUYn4j59CAdsZCsvsug6.xociqbOPaNr0oxOA2zwD9S2MSiK6', 'playlist': [{'duration': 30, 'file_name': 'big-buck-bunny-1080p-60fps-30sec.mp4', 'url': 'http://192.168.1.22/media/big-buck-bunny-1080p-60fps-30sec.mp4'}, {'duration': 15, 'file_name': 'demo2.jpeg', 'url': 'http://192.168.1.22/media/demo2.jpeg'}], 'playlist_version': 3}
[INFO] [SignageApp] Fetched updated playlist from server.
[INFO] [SignageApp] Local playlist version: 0, Server playlist version: 3
[INFO] [SignageApp] Preparing to download big-buck-bunny-1080p-60fps-30sec.mp4 from http://192.168.1.22/media/big-buck-bunny-1080p-60fps-30sec.mp4...
[INFO] [SignageApp] Successfully downloaded big-buck-bunny-1080p-60fps-30sec.mp4 to /home/pi/Desktop/tkinter_player/signage_player/static_data/media/big-buck-bunny-1080p-60fps-30sec.mp4
[INFO] [SignageApp] Preparing to download demo2.jpeg from http://192.168.1.22/media/demo2.jpeg...
[INFO] [SignageApp] Successfully downloaded demo2.jpeg to /home/pi/Desktop/tkinter_player/signage_player/static_data/media/demo2.jpeg
[INFO] [SignageApp] Fetching playlist from URL: http://192.168.1.22:80/api/playlists with params: {'hostname': 'tv-terasa', 'quickconnect_code': '8887779'}
[INFO] [SignageApp] Server response: {'hashed_quickconnect': '$2b$12$Prw4EUYn4j59CAdsZCsvsug6.xociqbOPaNr0oxOA2zwD9S2MSiK6', 'playlist': [{'duration': 30, 'file_name': 'big-buck-bunny-1080p-60fps-30sec.mp4', 'url': 'http://192.168.1.22/media/big-buck-bunny-1080p-60fps-30sec.mp4'}, {'duration': 15, 'file_name': 'demo2.jpeg', 'url': 'http://192.168.1.22/media/demo2.jpeg'}], 'playlist_version': 3}
[INFO] [SignageApp] Fetched updated playlist from server.
[INFO] [SignageApp] Local playlist version: 0, Server playlist version: 3
[INFO] [SignageApp] Preparing to download big-buck-bunny-1080p-60fps-30sec.mp4 from http://192.168.1.22/media/big-buck-bunny-1080p-60fps-30sec.mp4...
[INFO] [SignageApp] File big-buck-bunny-1080p-60fps-30sec.mp4 already exists. Skipping download.
[INFO] [SignageApp] Preparing to download demo2.jpeg from http://192.168.1.22/media/demo2.jpeg...
[INFO] [SignageApp] File demo2.jpeg already exists. Skipping download.
[INFO] [SignageApp] Fetching playlist from URL: http://192.168.1.22:80/api/playlists with params: {'hostname': 'tv-terasa', 'quickconnect_code': '8887779'}
[INFO] [SignageApp] Server response: {'hashed_quickconnect': '$2b$12$Prw4EUYn4j59CAdsZCsvsug6.xociqbOPaNr0oxOA2zwD9S2MSiK6', 'playlist': [{'duration': 30, 'file_name': 'big-buck-bunny-1080p-60fps-30sec.mp4', 'url': 'http://192.168.1.22/media/big-buck-bunny-1080p-60fps-30sec.mp4'}, {'duration': 15, 'file_name': 'demo2.jpeg', 'url': 'http://192.168.1.22/media/demo2.jpeg'}], 'playlist_version': 3}
[INFO] [SignageApp] Fetched updated playlist from server.
[INFO] [SignageApp] Local playlist version: 0, Server playlist version: 3
[INFO] [SignageApp] Preparing to download big-buck-bunny-1080p-60fps-30sec.mp4 from http://192.168.1.22/media/big-buck-bunny-1080p-60fps-30sec.mp4...
[INFO] [SignageApp] File big-buck-bunny-1080p-60fps-30sec.mp4 already exists. Skipping download.
[INFO] [SignageApp] Preparing to download demo2.jpeg from http://192.168.1.22/media/demo2.jpeg...
[INFO] [SignageApp] File demo2.jpeg already exists. Skipping download.
[INFO] [SignageApp] Fetching playlist from URL: http://192.168.1.22:80/api/playlists with params: {'hostname': 'tv-terasa', 'quickconnect_code': '8887779'}
[INFO] [SignageApp] Server response: {'hashed_quickconnect': '$2b$12$Prw4EUYn4j59CAdsZCsvsug6.xociqbOPaNr0oxOA2zwD9S2MSiK6', 'playlist': [{'duration': 30, 'file_name': 'big-buck-bunny-1080p-60fps-30sec.mp4', 'url': 'http://192.168.1.22/media/big-buck-bunny-1080p-60fps-30sec.mp4'}, {'duration': 50, 'file_name': 'demo2.jpeg', 'url': 'http://192.168.1.22/media/demo2.jpeg'}, {'duration': 30, 'file_name': 'call-of-duty-black-3840x2160-23674.jpg', 'url': 'http://192.168.1.22/media/call-of-duty-black-3840x2160-23674.jpg'}], 'playlist_version': 4}
[INFO] [SignageApp] Fetched updated playlist from server.
[INFO] [SignageApp] Local playlist version: 0, Server playlist version: 4
[INFO] [SignageApp] Preparing to download big-buck-bunny-1080p-60fps-30sec.mp4 from http://192.168.1.22/media/big-buck-bunny-1080p-60fps-30sec.mp4...
[INFO] [SignageApp] File big-buck-bunny-1080p-60fps-30sec.mp4 already exists. Skipping download.
[INFO] [SignageApp] Preparing to download demo2.jpeg from http://192.168.1.22/media/demo2.jpeg...
[INFO] [SignageApp] File demo2.jpeg already exists. Skipping download.
[INFO] [SignageApp] Preparing to download call-of-duty-black-3840x2160-23674.jpg from http://192.168.1.22/media/call-of-duty-black-3840x2160-23674.jpg...
[INFO] [SignageApp] Successfully downloaded call-of-duty-black-3840x2160-23674.jpg to /home/pi/Desktop/tkinter_player/signage_player/static_data/media/call-of-duty-black-3840x2160-23674.jpg
[INFO] [SignageApp] Fetching playlist from URL: http://192.168.1.22:80/api/playlists with params: {'hostname': 'tv-terasa', 'quickconnect_code': '8887779'}
[INFO] [SignageApp] Server response: {'hashed_quickconnect': '$2b$12$Prw4EUYn4j59CAdsZCsvsug6.xociqbOPaNr0oxOA2zwD9S2MSiK6', 'playlist': [{'duration': 30, 'file_name': 'big-buck-bunny-1080p-60fps-30sec.mp4', 'url': 'http://192.168.1.22/media/big-buck-bunny-1080p-60fps-30sec.mp4'}, {'duration': 50, 'file_name': 'demo2.jpeg', 'url': 'http://192.168.1.22/media/demo2.jpeg'}, {'duration': 30, 'file_name': 'call-of-duty-black-3840x2160-23674.jpg', 'url': 'http://192.168.1.22/media/call-of-duty-black-3840x2160-23674.jpg'}], 'playlist_version': 4}
[INFO] [SignageApp] Fetched updated playlist from server.
[INFO] [SignageApp] Local playlist version: 0, Server playlist version: 4
[INFO] [SignageApp] Preparing to download big-buck-bunny-1080p-60fps-30sec.mp4 from http://192.168.1.22/media/big-buck-bunny-1080p-60fps-30sec.mp4...
[INFO] [SignageApp] File big-buck-bunny-1080p-60fps-30sec.mp4 already exists. Skipping download.
[INFO] [SignageApp] Preparing to download demo2.jpeg from http://192.168.1.22/media/demo2.jpeg...
[INFO] [SignageApp] File demo2.jpeg already exists. Skipping download.
[INFO] [SignageApp] Preparing to download call-of-duty-black-3840x2160-23674.jpg from http://192.168.1.22/media/call-of-duty-black-3840x2160-23674.jpg...
[INFO] [SignageApp] File call-of-duty-black-3840x2160-23674.jpg already exists. Skipping download.
[INFO] [SignageApp] Fetching playlist from URL: http://192.168.1.22:80/api/playlists with params: {'hostname': 'tv-terasa', 'quickconnect_code': '8887779'}
[INFO] [SignageApp] Server response: {'hashed_quickconnect': '$2b$12$Prw4EUYn4j59CAdsZCsvsug6.xociqbOPaNr0oxOA2zwD9S2MSiK6', 'playlist': [{'duration': 30, 'file_name': 'big-buck-bunny-1080p-60fps-30sec.mp4', 'url': 'http://192.168.1.22/media/big-buck-bunny-1080p-60fps-30sec.mp4'}, {'duration': 50, 'file_name': 'demo2.jpeg', 'url': 'http://192.168.1.22/media/demo2.jpeg'}, {'duration': 30, 'file_name': 'call-of-duty-black-3840x2160-23674.jpg', 'url': 'http://192.168.1.22/media/call-of-duty-black-3840x2160-23674.jpg'}], 'playlist_version': 4}
[INFO] [SignageApp] Fetched updated playlist from server.
[INFO] [SignageApp] Local playlist version: 0, Server playlist version: 4
[INFO] [SignageApp] Preparing to download big-buck-bunny-1080p-60fps-30sec.mp4 from http://192.168.1.22/media/big-buck-bunny-1080p-60fps-30sec.mp4...
[INFO] [SignageApp] File big-buck-bunny-1080p-60fps-30sec.mp4 already exists. Skipping download.
[INFO] [SignageApp] Preparing to download demo2.jpeg from http://192.168.1.22/media/demo2.jpeg...
[INFO] [SignageApp] File demo2.jpeg already exists. Skipping download.
[INFO] [SignageApp] Preparing to download call-of-duty-black-3840x2160-23674.jpg from http://192.168.1.22/media/call-of-duty-black-3840x2160-23674.jpg...
[INFO] [SignageApp] File call-of-duty-black-3840x2160-23674.jpg already exists. Skipping download.

View File

@@ -1,7 +1,6 @@
import os import os
import json import json
import tkinter as tk import tkinter as tk
from PIL import Image, ImageTk
import vlc import vlc
import subprocess import subprocess
import sys import sys
@@ -121,8 +120,21 @@ class SimpleTkPlayer:
self.show_current_media() self.show_current_media()
def next_media(self): def next_media(self):
self.current_index = (self.current_index + 1) % len(self.playlist) # If at the last media, update playlist before looping
self.show_current_media() 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): def toggle_pause(self):
if not self.paused: if not self.paused:
@@ -184,39 +196,49 @@ class SimpleTkPlayer:
return return
media = self.playlist[self.current_index] media = self.playlist[self.current_index]
file_path = os.path.join(MEDIA_DATA_PATH, media['file_name']) 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) self.show_video(file_path, on_end=self.next_media)
elif file_path.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp', '.gif')): elif ext.endswith(('.jpg', '.jpeg', '.png', '.bmp', '.gif')):
try: self.show_image_via_vlc(file_path, media.get('duration', 10), on_end=self.next_media)
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')
else: else:
self.label.config(text=f"Unsupported: {media['file_name']}", fg='yellow') 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): def next_media_loop(self):
if not self.playlist or self.paused: if not self.playlist or self.paused:
self.root.after(1000, self.next_media_loop) self.root.after(1000, self.next_media_loop)
return 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.show_current_media()
self.root.after(duration * 1000, self.next_media_loop)
def exit_app(self): def exit_app(self):
# Signal the update thread to stop if stop_event is present # 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')] files = [f for f in os.listdir(PLAYLIST_DIR) if f.startswith('server_playlist_v') and f.endswith('.json')]
if not files: if not files:
return [] return []
# Sort by version number descending
files.sort(key=lambda x: int(x.split('_v')[-1].split('.json')[0]), reverse=True) 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) data = json.load(f)
return data.get('playlist', []) 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()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 848 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 410 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 737 KiB

View File

@@ -0,0 +1,20 @@
{
"playlist": [
{
"file_name": "big-buck-bunny-1080p-60fps-30sec.mp4",
"url": "media/big-buck-bunny-1080p-60fps-30sec.mp4",
"duration": 30
},
{
"file_name": "demo2.jpeg",
"url": "media/demo2.jpeg",
"duration": 50
},
{
"file_name": "call-of-duty-black-3840x2160-23674.jpg",
"url": "media/call-of-duty-black-3840x2160-23674.jpg",
"duration": 30
}
],
"version": 4
}

View File

@@ -1,25 +0,0 @@
{
"playlist": [
{
"file_name": "cropped-cropped-main-picture-scaled-1.jpeg",
"url": "media/cropped-cropped-main-picture-scaled-1.jpeg",
"duration": 15
},
{
"file_name": "start_page.jpeg",
"url": "media/start_page.jpeg",
"duration": 15
},
{
"file_name": "Banner_poarta_2_x6.jpg",
"url": "media/Banner_poarta_2_x6.jpg",
"duration": 10
},
{
"file_name": "WhatsApp_Video_2025-08-21_at_18.34.19_86a6f243.mp4",
"url": "media/WhatsApp_Video_2025-08-21_at_18.34.19_86a6f243.mp4",
"duration": 101
}
],
"version": 5
}