updated the playlist and playng state

This commit is contained in:
2025-06-24 15:41:17 +03:00
parent 71eab75d51
commit cca7d75376
12 changed files with 206 additions and 48 deletions

View File

@@ -3,7 +3,7 @@
# filepath: /home/pi/Desktop/signage-player/run_app.sh
# Navigate to the application directory
cd /home/pi/signage-player/src || exit
cd /home/pi/Desktop/signage-player/src || exit
# Check for the --verbose flag
if [[ "$1" == "--verbose" ]]; then

View File

@@ -1 +1,10 @@
{"screen_orientation": "Landscape", "screen_name": "rpi-tv11", "quickconnect_key": "8887779", "server_ip": "192.168.1.74", "port": "5000", "screen_w": "1920", "screen_h": "1080"}
{
"screen_orientation": "Landscape",
"screen_name": "rpi-tv11",
"quickconnect_key": "8887779",
"server_ip": "192.168.1.74",
"port": "5000",
"screen_w": "1920",
"screen_h": "1080",
"playlist_version": 5
}

View File

@@ -1,7 +1,27 @@
2025-06-20 16:32:40 - STARTED: edit_pencil.png
2025-06-20 16:33:00 - STARTED: delete.png
2025-06-20 16:35:13 - STARTED: edit_pencil.png
2025-06-20 16:35:15 - STARTED: delete.png
2025-06-20 16:35:16 - STARTED: edit_pencil.png
2025-06-20 16:35:17 - STARTED: delete.png
2025-06-20 16:35:18 - STARTED: edit_pencil.png
2025-06-24 14:10:03 - STARTED: edit_pencil.png
2025-06-24 14:10:22 - STARTED: delete.png
2025-06-24 14:16:01 - STARTED: edit_pencil.png
2025-06-24 14:16:21 - STARTED: delete.png
2025-06-24 14:17:04 - STARTED: edit_pencil.png
2025-06-24 14:17:24 - STARTED: delete.png
2025-06-24 14:17:44 - STARTED: edit_pencil.png
2025-06-24 14:17:59 - STARTED: edit_pencil.png
2025-06-24 14:18:14 - STARTED: edit_pencil.png
2025-06-24 14:19:22 - STARTED: edit_pencil.png
2025-06-24 14:19:37 - STARTED: edit_pencil.png
2025-06-24 14:19:52 - STARTED: edit_pencil.png
2025-06-24 14:20:08 - STARTED: edit_pencil.png
2025-06-24 14:44:17 - STARTED: edit_pencil.png
2025-06-24 14:44:32 - STARTED: edit_pencil.png
2025-06-24 14:44:47 - STARTED: edit_pencil.png
2025-06-24 14:48:16 - STARTED: 20250605_09h44m12s_grim.png
2025-06-24 15:23:13 - STARTED: 20250605_09h44m12s_grim.png
2025-06-24 15:23:33 - STARTED: 20250605_09h44m12s_grim.png
2025-06-24 15:27:25 - STARTED: 20250605_09h44m12s_grim.png
2025-06-24 15:27:45 - STARTED: 20250605_09h44m12s_grim.png
2025-06-24 15:29:48 - STARTED: 20250605_09h44m12s_grim.png
2025-06-24 15:30:08 - STARTED: 20250605_09h44m12s_grim.png
2025-06-24 15:30:09 - STARTED: 20250605_09h44m12s_grim.png
2025-06-24 15:39:48 - STARTED: 20250605_09h44m12s_grim.png
2025-06-24 15:39:55 - STARTED: 20250605_09h44m12s_grim.png
2025-06-24 15:40:16 - STARTED: 123.jpeg

View File

@@ -162,6 +162,23 @@
multiline: False
size_hint_x: 0.3
# New row for testing server connection
BoxLayout:
orientation: 'horizontal'
size_hint_y: None
height: 40
spacing: 10
Button:
text: "Test Connection to Server"
size_hint_x: 0.3
on_release: root.test_server_connection()
Label:
id: server_connection_label
text: "Server connection status will appear here."
size_hint_x: 0.7
# Buttons in the lower part of the screen
BoxLayout:
size_hint_y: 0.4 # Allocate 40% of the screen height for buttons

View File

@@ -21,9 +21,10 @@ import os # Import os for file and directory operations
import json # Import json for handling JSON data
import datetime # Import datetime for timestamping logs
import subprocess
import requests
# Import functions from python_functions.py
from python_functions import load_local_playlist, download_media_files, clean_unused_files, fetch_server_playlist
from python_functions import load_local_playlist, download_media_files, clean_unused_files,save_local_playlist, fetch_server_playlist
# Load the KV file for UI layout
Builder.load_file('kv/media_player.kv')
@@ -103,34 +104,37 @@ class MediaPlayer(Screen):
def on_enter(self):
"""Called when the screen is entered."""
Logger.info("MediaPlayer: Entering screen...")
# Attempt to load the local playlist
self.playlist = load_local_playlist()
Logger.info(f"MediaPlayer: Loaded local playlist: {self.playlist}")
local_playlist_data = load_local_playlist()
self.playlist = local_playlist_data.get('playlist', []) # Extract the playlist key
local_version = local_playlist_data.get('version', 0) # Extract the local playlist version
Logger.info(f"MediaPlayer: Loaded local playlist: {self.playlist}, Version: {local_version}")
if not self.playlist: # If no local playlist exists
Logger.warning("MediaPlayer: No local playlist found. Fetching from server...")
# Fetch the server playlist
server_playlist_data = fetch_server_playlist()
server_playlist = server_playlist_data.get('playlist', [])
server_version = server_playlist_data.get('version', 0)
if server_playlist: # If server playlist is valid
Logger.info("MediaPlayer: Server playlist fetched successfully.")
# Download media files and save the playlist locally
download_media_files(server_playlist, server_version)
self.playlist = load_local_playlist() # Reload the updated local playlist
if self.playlist:
Logger.info("MediaPlayer: Local playlist updated successfully.")
else:
Logger.error("MediaPlayer: Failed to update local playlist.")
save_local_playlist({'playlist': server_playlist, 'version': server_version})
update_config_playlist_version(server_version) # Update playlist version in app_config.txt
# Reload the updated local playlist
local_playlist_data = load_local_playlist()
self.playlist = local_playlist_data.get('playlist', []) # Extract the playlist key
Logger.info("MediaPlayer: Local playlist updated successfully.")
else:
Logger.error("MediaPlayer: Failed to fetch server playlist. No media to play.")
return
if self.playlist: # If the playlist is loaded successfully
self.play_media() # Start playing media
self.show_buttons() # Ensure buttons are visible when the screen is entered
@@ -272,7 +276,36 @@ class MediaPlayer(Screen):
Clock.unschedule(self.image_timer)
# Update the current index
self.current_index = (self.current_index + 1) % len(self.playlist)
self.current_index += 1
# Check if the end of the playlist is reached
if self.current_index >= len(self.playlist):
Logger.info("End of playlist reached. Checking for updates...")
self.current_index = 0 # Reset the index to start from the beginning
# Fetch the server playlist
server_playlist_data = fetch_server_playlist()
server_playlist = server_playlist_data.get('playlist', [])
server_version = server_playlist_data.get('version', 0)
# Load the local playlist
local_playlist_data = load_local_playlist()
local_version = local_playlist_data.get('version', 0)
# Compare versions
if server_version > local_version: # Update only if server version is newer
Logger.info(f"Playlist version mismatch detected. Local version: {local_version}, Server version: {server_version}")
# Clean up old media files
clean_unused_files(local_playlist_data.get('playlist', []))
# Update the local playlist and download new media files
download_media_files(server_playlist, server_version)
local_playlist_data = load_local_playlist() # Reload the updated local playlist
self.playlist = local_playlist_data.get('playlist', []) # Extract the playlist key
Logger.info("Playlist updated successfully.")
else:
Logger.info("Playlist versions match. No update needed.")
# Play the next media
self.play_media()
@@ -349,25 +382,40 @@ class MediaPlayer(Screen):
self.ids.play_pause_button.background_normal = './Resurse/play.png'
def check_playlist_updates(self, dt):
"""Check for updates to the playlist."""
"""Check for updates to the playlist using the playlist_version from app_config.txt."""
Logger.info("Checking for playlist updates...")
# Load the playlist version from app_config.txt
if os.path.exists(CONFIG_FILE):
try:
with open(CONFIG_FILE, 'r') as file:
config_data = json.load(file)
local_version = config_data.get('playlist_version', 0) # Get the local playlist version
Logger.info(f"Loaded local playlist version from app_config.txt: {local_version}")
except json.JSONDecodeError as e:
Logger.error(f"Failed to parse app_config.txt. Error: {e}")
local_version = 0
else:
Logger.warning(f"Configuration file {CONFIG_FILE} not found. Defaulting local playlist version to 0.")
local_version = 0
# Fetch the server playlist
server_playlist_data = fetch_server_playlist() # Fetch the playlist from the server
server_playlist_data = fetch_server_playlist()
server_playlist = server_playlist_data.get('playlist', [])
server_version = server_playlist_data.get('version', 0)
# Load the local playlist
local_playlist_data = load_local_playlist() # Load the local playlist
local_version = local_playlist_data.get('version', 0) if local_playlist_data else 0
# Compare versions
if server_version != local_version: # If versions differ
if server_version > local_version: # Update only if server version is newer
Logger.info(f"Playlist version mismatch detected. Local version: {local_version}, Server version: {server_version}")
# Clean up old media files
local_playlist_data = load_local_playlist()
clean_unused_files(local_playlist_data.get('playlist', []))
# Update the local playlist and download new media files
download_media_files(server_playlist) # Download media files from the server
self.playlist = load_local_playlist() # Reload the updated local playlist
download_media_files(server_playlist, server_version)
local_playlist_data = load_local_playlist() # Reload the updated local playlist
self.playlist = local_playlist_data.get('playlist', []) # Extract the playlist key
Logger.info("Playlist updated successfully.")
else:
Logger.info("Playlist versions match. No update needed.")
@@ -391,7 +439,8 @@ class SettingsScreen(Screen):
"server_ip": "",
"port": "",
"screen_w": "", # Default width
"screen_h": "" # Default height
"screen_h": "", # Default height
"playlist_version": 0 # Default playlist version
}
def save_config(self):
@@ -456,6 +505,45 @@ class SettingsScreen(Screen):
Logger.warning("Incorrect password. Returning to SettingsScreen.")
popup.dismiss() # Close the popup
def test_server_connection(self):
"""Test the connection to the server and update the label."""
Logger.info("SettingsScreen: Testing connection to server...")
# Load configuration data
server_ip = self.config_data.get("server_ip", "")
port = self.config_data.get("port", "")
local_version = self.config_data.get("playlist_version", 0)
if not server_ip or not port:
self.ids.server_connection_label.text = "Server IP or port is not configured."
Logger.error("SettingsScreen: Server IP or port is missing in configuration.")
return
try:
# Construct the server URL
url = f"http://{server_ip}:{port}/api/playlists"
params = {
'hostname': self.config_data.get("screen_name", ""),
'quickconnect_code': self.config_data.get("quickconnect_key", "")
}
Logger.info(f"SettingsScreen: Sending request to {url} with params: {params}...")
response = requests.get(url, params=params, timeout=5)
if response.status_code == 200:
response_data = response.json()
server_version = response_data.get("playlist_version", "Unknown")
self.ids.server_connection_label.text = (
f"Server is reachable. Playlist version on server: {server_version}. "
f"Playlist version on player: {local_version}."
)
Logger.info("SettingsScreen: Server is reachable.")
else:
self.ids.server_connection_label.text = f"Server unreachable. Status code: {response.status_code}."
Logger.error(f"SettingsScreen: Failed to reach server. Status code: {response.status_code}.")
except requests.exceptions.RequestException as e:
self.ids.server_connection_label.text = "Server unreachable. Check connection settings."
Logger.error(f"SettingsScreen: Error connecting to server: {e}")
class MediaPlayerApp(App):
"""Main application class."""

View File

@@ -32,23 +32,23 @@ port = config_data.get("port", "")
Logger.info(f"python_functions: Configuration loaded: server={server}, host={host}, quick={quick}, port={port}")
def load_local_playlist():
"""Load the playlist from local storage."""
"""Load the playlist and version from local storage."""
if os.path.exists(LOCAL_PLAYLIST_FILE):
try:
with open(LOCAL_PLAYLIST_FILE, 'r') as local_file:
local_playlist = json.load(local_file)
Logger.info(f"python_functions: Local playlist loaded: {local_playlist}")
if isinstance(local_playlist, dict) and 'playlist' in local_playlist and 'version' in local_playlist:
return local_playlist.get('playlist', [])
return local_playlist # Return the full playlist data
else:
Logger.error("python_functions: Invalid local playlist structure.")
return []
return {'playlist': [], 'version': 0}
except json.JSONDecodeError as e:
Logger.error(f"python_functions: Failed to parse local playlist file. Error: {e}")
return []
return {'playlist': [], 'version': 0}
else:
Logger.warning("python_functions: Local playlist file not found.")
return []
return {'playlist': [], 'version': 0}
def save_local_playlist(playlist):
"""Save the updated playlist locally."""
@@ -72,26 +72,32 @@ def fetch_server_playlist():
'hostname': host,
'quickconnect_code': quick
}
Logger.info(f"Fetching playlist from URL: {url} with params: {params}")
response = requests.get(url, params=params)
if response.status_code == 200:
response_data = response.json()
Logger.info(f"Server response: {response_data}")
playlist = response_data.get('playlist', [])
version = response_data.get('playlist_version', None)
hashed_quickconnect = response_data.get('hashed_quickconnect', None)
if version is not None and hashed_quickconnect is not None:
if bcrypt.checkpw(quick.encode('utf-8'), hashed_quickconnect.encode('utf-8')):
Logger.info("python_functions: Fetched updated playlist from server.")
Logger.info("Fetched updated playlist from server.")
# Update the playlist version in app_config.txt
update_config_playlist_version(version)
return {'playlist': playlist, 'version': version}
else:
Logger.error("python_functions: Quickconnect code validation failed.")
Logger.error("Quickconnect code validation failed.")
else:
Logger.error("python_functions: Failed to retrieve playlist or hashed quickconnect from the response.")
Logger.error("Failed to retrieve playlist or hashed quickconnect from the response.")
else:
Logger.error(f"python_functions: Failed to fetch playlist. Status Code: {response.status_code}")
Logger.error(f"Failed to fetch playlist. Status Code: {response.status_code}")
except requests.exceptions.RequestException as e:
Logger.error(f"python_functions: Failed to fetch playlist: {e}")
Logger.error(f"Failed to fetch playlist: {e}")
return {'playlist': [], 'version': 0}
@@ -157,4 +163,22 @@ def clean_unused_files(playlist):
os.remove(file_path)
Logger.info(f"python_functions: Deleted unused file: {file_path}")
except OSError as e:
Logger.error(f"python_functions: Failed to delete {file_path}: {e}")
Logger.error(f"python_functions: Failed to delete {file_path}: {e}")
def update_config_playlist_version(version):
"""Update the playlist version in app_config.txt."""
if not os.path.exists(CONFIG_FILE):
Logger.error(f"python_functions: Configuration file {CONFIG_FILE} not found.")
return
try:
with open(CONFIG_FILE, 'r') as file:
config_data = json.load(file)
config_data['playlist_version'] = version # Add or update the playlist version
with open(CONFIG_FILE, 'w') as file:
json.dump(config_data, file, indent=4)
Logger.info(f"python_functions: Updated playlist version in app_config.txt to {version}.")
except (IOError, json.JSONDecodeError) as e:
Logger.error(f"python_functions: Failed to update playlist version in app_config.txt. Error: {e}")

View File

@@ -1 +1 @@
{"playlist": [{"file_name": "edit_pencil.png", "url": "/home/pi/Desktop/signage-player/src/static/resurse/edit_pencil.png", "duration": 20}, {"file_name": "delete.png", "url": "/home/pi/Desktop/signage-player/src/static/resurse/delete.png", "duration": 20}], "version": 2}
{"playlist": [{"file_name": "123.jpeg", "url": "/home/pi/Desktop/signage-player/src/static/resurse/123.jpeg", "duration": 30}], "version": 5}

BIN
src/static/resurse/123.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB