updated the playlist and playng state
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
Binary file not shown.
@@ -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
|
||||
|
||||
@@ -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."""
|
||||
|
||||
|
||||
@@ -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}")
|
||||
@@ -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
BIN
src/static/resurse/123.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 537 KiB |
BIN
src/static/resurse/20250605_09h44m12s_grim.png
Normal file
BIN
src/static/resurse/20250605_09h44m12s_grim.png
Normal file
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 |
Reference in New Issue
Block a user