diff --git a/signage_player/__pycache__/player.cpython-311.pyc b/signage_player/__pycache__/player.cpython-311.pyc index 59930e5..b496111 100644 Binary files a/signage_player/__pycache__/player.cpython-311.pyc and b/signage_player/__pycache__/player.cpython-311.pyc differ diff --git a/signage_player/main_data/app_config.txt b/signage_player/main_data/app_config.txt index 7e2e0d8..9eb348d 100644 --- a/signage_player/main_data/app_config.txt +++ b/signage_player/main_data/app_config.txt @@ -2,7 +2,7 @@ "screen_orientation": "Landscape", "screen_name": "tv-terasa", "quickconnect_key": "8887779", - "server_ip": "digi-signage.moto-adv.com", + "server_ip": "192.168.1.22", "port": "80", "screen_w": "1920", "screen_h": "1080", diff --git a/signage_player/main_data/log.txt b/signage_player/main_data/log.txt index 468a0b2..c6ac4c8 100644 --- a/signage_player/main_data/log.txt +++ b/signage_player/main_data/log.txt @@ -323,3 +323,69 @@ [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] 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. diff --git a/signage_player/player.py b/signage_player/player.py index a39fbac..79d820a 100644 --- a/signage_player/player.py +++ b/signage_player/player.py @@ -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() diff --git a/signage_player/static_data/media/Banner_poarta_2_x6.jpg b/signage_player/static_data/media/Banner_poarta_2_x6.jpg deleted file mode 100644 index fcf0864..0000000 Binary files a/signage_player/static_data/media/Banner_poarta_2_x6.jpg and /dev/null differ diff --git a/signage_player/static_data/media/WhatsApp_Video_2025-08-21_at_18.34.19_86a6f243.mp4 b/signage_player/static_data/media/WhatsApp_Video_2025-08-21_at_18.34.19_86a6f243.mp4 deleted file mode 100644 index d5e0a13..0000000 Binary files a/signage_player/static_data/media/WhatsApp_Video_2025-08-21_at_18.34.19_86a6f243.mp4 and /dev/null differ diff --git a/signage_player/static_data/media/big-buck-bunny-1080p-60fps-30sec.mp4 b/signage_player/static_data/media/big-buck-bunny-1080p-60fps-30sec.mp4 new file mode 100644 index 0000000..6c61dbf Binary files /dev/null and b/signage_player/static_data/media/big-buck-bunny-1080p-60fps-30sec.mp4 differ diff --git a/signage_player/static_data/media/call-of-duty-black-3840x2160-23674.jpg b/signage_player/static_data/media/call-of-duty-black-3840x2160-23674.jpg new file mode 100644 index 0000000..62f7d98 Binary files /dev/null and b/signage_player/static_data/media/call-of-duty-black-3840x2160-23674.jpg differ diff --git a/signage_player/static_data/media/cropped-cropped-main-picture-scaled-1.jpeg b/signage_player/static_data/media/cropped-cropped-main-picture-scaled-1.jpeg deleted file mode 100644 index 8a15a16..0000000 Binary files a/signage_player/static_data/media/cropped-cropped-main-picture-scaled-1.jpeg and /dev/null differ diff --git a/signage_player/static_data/media/demo2.jpeg b/signage_player/static_data/media/demo2.jpeg new file mode 100644 index 0000000..29d8372 Binary files /dev/null and b/signage_player/static_data/media/demo2.jpeg differ diff --git a/signage_player/static_data/media/start_page.jpeg b/signage_player/static_data/media/start_page.jpeg deleted file mode 100644 index 3a57493..0000000 Binary files a/signage_player/static_data/media/start_page.jpeg and /dev/null differ diff --git a/signage_player/static_data/playlist/server_playlist_v4.json b/signage_player/static_data/playlist/server_playlist_v4.json new file mode 100644 index 0000000..58d0533 --- /dev/null +++ b/signage_player/static_data/playlist/server_playlist_v4.json @@ -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 +} \ No newline at end of file diff --git a/signage_player/static_data/playlist/server_playlist_v5.json b/signage_player/static_data/playlist/server_playlist_v5.json deleted file mode 100644 index aaa4698..0000000 --- a/signage_player/static_data/playlist/server_playlist_v5.json +++ /dev/null @@ -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 -} \ No newline at end of file