updated systems

This commit is contained in:
2025-06-25 15:45:01 +03:00
parent f7d749cc8b
commit 4e2909718c
14 changed files with 1188 additions and 559 deletions

View File

@@ -2,4 +2,5 @@ kivy
requests
watchdog
Pillow
bcrypt
bcrypt
ffpyplayer

View File

@@ -1,10 +1,10 @@
{
"screen_orientation": "Landscape",
"screen_name": "tv-terasa",
"screen_name": "rpi-tv11",
"quickconnect_key": "8887779",
"server_ip": "digi-signage.moto-adv.com",
"port": "80",
"server_ip": "192.168.1.74",
"port": "5000",
"screen_w": "1920",
"screen_h": "1080",
"playlist_version": 2
"playlist_version": 7
}

View File

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 148 KiB

BIN
src/Resurse/demo2.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 KiB

View File

@@ -0,0 +1,15 @@
{
"playlist": [
{
"file_name": "demo1.jpg",
"url": "Resurse/demo1.jpg",
"duration": 20
},
{
"file_name": "demo2.jpg",
"url": "Resurse/demo2.jpg",
"duration": 20
}
],
"version": 1
}

File diff suppressed because it is too large Load Diff

View File

@@ -8,6 +8,7 @@
size_hint: (1, 1)
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
opacity: 0
keep_ratio: True
Image:
id: image_display

View File

@@ -1,7 +1,5 @@
from kivy.config import Config
Config.set('kivy', 'video', 'ffpyplayer')
# Now import other Kivy modules
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen # Import ScreenManager and Screen for managing screens
@@ -108,15 +106,51 @@ class MediaPlayer(Screen):
"""Called when the screen is entered."""
Logger.info("MediaPlayer: Starting on_enter method.")
# Load server settings from the configuration file
if os.path.exists(CONFIG_FILE):
try:
with open(CONFIG_FILE, 'r') as file:
config_data = json.load(file)
server = config_data.get("server_ip", "")
host = config_data.get("screen_name", "")
quick = config_data.get("quickconnect_key", "")
port = config_data.get("port", "")
Logger.info(f"MediaPlayer: Loaded server settings: server={server}, host={host}, quick={quick}, port={port}")
except json.JSONDecodeError as e:
Logger.error(f"MediaPlayer: Failed to parse configuration file. Error: {e}")
server, host, quick, port = "", "", "", ""
else:
Logger.warning(f"MediaPlayer: Configuration file {CONFIG_FILE} not found. Defaulting server settings to empty.")
server, host, quick, port = "", "", "", ""
# Attempt to load the local 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}")
# Check if the local playlist exists
if not self.playlist: # If no local playlist exists
Logger.warning("MediaPlayer: No local playlist found. Fetching from server...")
Logger.warning("MediaPlayer: No local playlist found. Attempting to load demo playlist...")
# Load the demo playlist
demo_playlist_path = os.path.join(os.path.dirname(__file__), 'Resurse', 'demo_playlist.json')
if os.path.exists(demo_playlist_path):
try:
with open(demo_playlist_path, 'r') as demo_file:
demo_playlist_data = json.load(demo_file) # Pass the file object to json.load()
self.playlist = demo_playlist_data.get('playlist', []) # Extract the playlist key
Logger.info("MediaPlayer: Demo playlist loaded successfully.")
except json.JSONDecodeError as e:
Logger.error(f"MediaPlayer: Failed to parse demo playlist file. Error: {e}")
else:
Logger.error("MediaPlayer: Demo playlist file not found. No media to play.")
return
# Check if server settings are valid
if not self.playlist or not server or not host or not quick or not port:
Logger.warning("MediaPlayer: Invalid server settings. Using demo playlist.")
else:
# Fetch the server playlist
server_playlist_data = fetch_server_playlist()
server_playlist = server_playlist_data.get('playlist', [])
@@ -127,7 +161,6 @@ class MediaPlayer(Screen):
# Download media files and save the playlist locally
download_media_files(server_playlist, server_version)
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
@@ -205,13 +238,9 @@ class MediaPlayer(Screen):
media = self.playlist[self.current_index] # Get the current media
file_name = media.get('file_name', '') # Get the file name
file_extension = os.path.splitext(file_name)[1].lower() # Get the file extension
file_path = media.get('url', '') # Use the exact path specified in the playlist
duration = media.get('duration', 10) # Get the duration (default: 10 seconds)
# Define the base directory for media files
base_dir = os.path.join(os.path.dirname(__file__), 'static', 'resurse')
file_path = os.path.join(base_dir, file_name) # Full path to the media file
Logger.info(f"MediaPlayer: Playing media: {file_path}")
# Check if the file exists
@@ -228,6 +257,7 @@ class MediaPlayer(Screen):
self.log_event(file_name, "STARTED")
# Determine the type of media and play it
file_extension = os.path.splitext(file_name)[1].lower() # Get the file extension
if file_extension in ['.mp4', '.avi', '.mov']:
self.play_video(file_path) # Play video
elif file_extension in ['.jpg', '.jpeg', '.png', '.gif']:
@@ -238,11 +268,12 @@ class MediaPlayer(Screen):
def play_video(self, file_path):
"""Play a video file without a fade-in effect."""
Logger.info(f"Playing video: {file_path}")
Logger.info(f"MediaPlayer: Attempting to play video: {file_path}")
if not os.path.exists(file_path):
Logger.error(f"Video file not found: {file_path}")
Logger.error(f"MediaPlayer: Video file not found: {file_path}")
return
Logger.info(f"MediaPlayer: Video file exists. Setting up video player...")
# Set the video source and start playback
self.video_player.source = file_path
self.video_player.state = 'play' # Start playing the video
@@ -252,9 +283,10 @@ class MediaPlayer(Screen):
# Schedule the next media after the video's duration
if self.video_player.duration > 0:
Logger.info(f"MediaPlayer: Video duration detected: {self.video_player.duration} seconds.")
Clock.schedule_once(self.next_media, self.video_player.duration)
else:
Logger.warning("Video duration is unknown. Using default duration")
Logger.warning("MediaPlayer: Video duration is unknown. Using default duration.")
def show_image(self, file_path, duration):
"""Display an image with a fade-in effect."""

View File

@@ -58,13 +58,14 @@ def load_local_playlist():
def save_local_playlist(playlist):
"""Save the updated playlist locally."""
Logger.info("python_functions: Starting save_local_playlist function.")
Logger.debug(f"python_functions: Playlist to save: {playlist}")
if not playlist or 'playlist' not in playlist:
Logger.error("python_functions: Invalid playlist data. Cannot save local playlist.")
return
try:
with open(LOCAL_PLAYLIST_FILE, 'w') as local_file:
json.dump(playlist, local_file)
json.dump(playlist, local_file, indent=4) # Ensure proper formatting
Logger.info("python_functions: Updated local playlist with server data.")
except IOError as e:
Logger.error(f"python_functions: Failed to save local playlist: {e}")
@@ -122,19 +123,19 @@ def download_media_files(playlist, version):
file_name = media.get('file_name', '')
file_url = media.get('url', '')
duration = media.get('duration', 10) # Default duration if not provided
file_path = os.path.join(base_dir, file_name)
local_path = os.path.join(base_dir, file_name) # Local file path
Logger.debug(f"python_functions: Preparing to download {file_name} from {file_url}...")
if os.path.exists(file_path):
if os.path.exists(local_path):
Logger.info(f"python_functions: File {file_name} already exists. Skipping download.")
else:
try:
response = requests.get(file_url, timeout=10)
if response.status_code == 200:
with open(file_path, 'wb') as file:
with open(local_path, 'wb') as file:
file.write(response.content)
Logger.info(f"python_functions: Successfully downloaded {file_name} to {file_path}")
Logger.info(f"python_functions: Successfully downloaded {file_name} to {local_path}")
else:
Logger.error(f"python_functions: Failed to download {file_name}. Status Code: {response.status_code}")
continue
@@ -142,15 +143,18 @@ def download_media_files(playlist, version):
Logger.error(f"python_functions: Error downloading {file_name}: {e}")
continue
# Update the playlist entry to point to the local file path
updated_media = {
'file_name': file_name,
'url': file_path, # Update URL to local path
'url': f"static/resurse/{file_name}", # Update URL to local path
'duration': duration
}
Logger.debug(f"python_functions: Updated media entry: {updated_media}")
updated_playlist.append(updated_media)
# Save the updated playlist locally
save_local_playlist({'playlist': updated_playlist, 'version': version})
Logger.info("python_functions: Finished media file download and updated local playlist.")
def clean_unused_files(playlist):
"""Remove unused media files from the resource folder."""

View File

@@ -1 +1,15 @@
{"playlist": [{"duration": 20, "file_name": "Ibex_450.jpg", "url": "http://digi-signage.moto-adv.com/media/Ibex_450.jpg"}, {"duration": 20, "file_name": "cropped-cropped-main-picture-scaled-1.jpeg", "url": "http://digi-signage.moto-adv.com/media/cropped-cropped-main-picture-scaled-1.jpeg"}], "version": 2}
{
"playlist": [
{
"file_name": "20250417_09h25m37s_grim.png",
"url": "static/resurse/20250417_09h25m37s_grim.png",
"duration": 20
},
{
"file_name": "123.jpeg",
"url": "static/resurse/123.jpeg",
"duration": 15
}
],
"version": 7
}

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: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 410 KiB