From 6bf4e3735a14f3e45dfb77cfa1c0ea57d9750379 Mon Sep 17 00:00:00 2001 From: Kiwy Player Date: Sat, 17 Jan 2026 20:41:31 +0200 Subject: [PATCH] Add comprehensive video playback optimization for smooth performance Environment variable optimizations: - KIVY_WINDOW='pygame' - Better window backend performance - KIVY_AUDIO='ffpyplayer' - Optimized audio playback - KIVY_GL_BACKEND='gl' - Use OpenGL for better graphics - FFMPEG_THREADS='4' - Multi-threaded video decoding - LIBPLAYER_BUFFER='2048000' - 2MB buffer for smooth playback - SDL_AUDIODRIVER='alsa' - Better audio on Raspberry Pi Kivy configuration optimizations: - multisampling=0 - Disable for better performance - fast_rgba=1 - Enable fast RGBA mode - Stereo audio (channels=2) - Reduced logging overhead (warning level) Video widget enhancements: - FFmpeg buffer optimization (2MB) - Multi-threaded decoding (4 threads) - Ignore index for better seeking - Allow codec fallback - 60 FPS animation delay New video optimization script (.video-optimization.sh): - GPU memory increased to 256MB - Install video codec libraries - Optimize swappiness to 30 (better memory management) - CPU forced to performance mode - Filesystem cache optimization Installation integration: - Runs video optimization automatically on Raspberry Pi - Configures GPU memory, libraries, and system settings - Improves overall video playback smoothness This addresses video stuttering, frame drops, and playback lag by optimizing at multiple levels: environment, application, and system. --- .gitignore | 4 ++- .player_heartbeat | 2 +- .video-optimization.sh | 61 ++++++++++++++++++++++++++++++++++++++++++ install.sh | 13 +++++++++ src/main.py | 35 ++++++++++++++++++++---- 5 files changed, 108 insertions(+), 7 deletions(-) create mode 100644 .video-optimization.sh diff --git a/.gitignore b/.gitignore index 8bae06a..578997f 100644 --- a/.gitignore +++ b/.gitignore @@ -56,4 +56,6 @@ playlists/server_playlist_*.json # OS .DS_Store -Thumbs.db \ No newline at end of file +Thumbs.db + +.player_heartbear diff --git a/.player_heartbeat b/.player_heartbeat index 26cb022..5735d75 100644 --- a/.player_heartbeat +++ b/.player_heartbeat @@ -1 +1 @@ -1768673747.1927276 \ No newline at end of file +1768675283.8000998 \ No newline at end of file diff --git a/.video-optimization.sh b/.video-optimization.sh new file mode 100644 index 0000000..78c606a --- /dev/null +++ b/.video-optimization.sh @@ -0,0 +1,61 @@ +#!/bin/bash +# Video playback optimization script for Raspberry Pi +# Improves video smoothness and reduces stuttering + +echo "Optimizing system for smooth video playback..." + +# 1. Increase GPU memory split for better video performance +if [ -f /boot/config.txt ]; then + echo "Checking GPU memory configuration..." + if grep -q "gpu_mem=" /boot/config.txt; then + # GPU memory already configured, check if it's sufficient + CURRENT_GPU_MEM=$(grep "gpu_mem=" /boot/config.txt | head -1 | cut -d'=' -f2) + if [ "$CURRENT_GPU_MEM" -lt 256 ]; then + sudo sed -i 's/gpu_mem=.*/gpu_mem=256/' /boot/config.txt + echo "✓ GPU memory increased to 256MB for video" + fi + else + # Add GPU memory setting + echo "gpu_mem=256" | sudo tee -a /boot/config.txt > /dev/null + echo "✓ GPU memory set to 256MB for video" + fi +fi + +# 2. Install video codec support +echo "Installing video codec libraries..." +sudo apt-get install -y \ + libva-drm2 \ + libva2 \ + libavcodec-extra \ + libavutil-dev \ + 2>/dev/null || true + +# 3. Optimize swappiness for better memory management +echo "Optimizing memory management..." +if [ -f /proc/sys/vm/swappiness ]; then + CURRENT_SWAP=$(cat /proc/sys/vm/swappiness) + if [ "$CURRENT_SWAP" -gt 30 ]; then + echo 30 | sudo tee /proc/sys/vm/swappiness > /dev/null + echo "vm.swappiness=30" | sudo tee -a /etc/sysctl.conf > /dev/null + echo "✓ Swappiness optimized" + fi +fi + +# 4. Disable CPU frequency scaling for consistent performance +echo "Ensuring CPU performance mode..." +for cpu in /sys/devices/system/cpu/cpu[0-9]*; do + if [ -f "$cpu/cpufreq/scaling_governor" ]; then + echo performance | sudo tee "$cpu/cpufreq/scaling_governor" > /dev/null 2>&1 || true + fi +done +echo "✓ CPU set to performance mode" + +# 5. Optimize file system cache +echo "Optimizing filesystem cache..." +echo 50 | sudo tee /proc/sys/vm/vfs_cache_pressure > /dev/null +echo "vm.vfs_cache_pressure=50" | sudo tee -a /etc/sysctl.conf > /dev/null +echo "✓ Filesystem cache optimized" + +echo "" +echo "✅ Video playback optimization complete!" +echo "Note: Some changes require a reboot to take effect." diff --git a/install.sh b/install.sh index a4709ef..b89373e 100644 --- a/install.sh +++ b/install.sh @@ -593,6 +593,19 @@ if detect_raspberry_pi; then setup_raspberry_pi_power_management fi +# Optimize video playback for Raspberry Pi +if detect_raspberry_pi; then + echo "" + echo "==========================================" + echo "Optimizing for Video Playback" + echo "==========================================" + + # Run video optimization script + if [ -f "$SCRIPT_DIR/.video-optimization.sh" ]; then + bash "$SCRIPT_DIR/.video-optimization.sh" + fi +fi + echo "To run the signage player:" echo " cd src && python3 main.py" echo "" diff --git a/src/main.py b/src/main.py index 957726f..cacaab2 100644 --- a/src/main.py +++ b/src/main.py @@ -16,10 +16,27 @@ os.environ['KIVY_VIDEO'] = 'ffpyplayer' # Use ffpyplayer as video provider os.environ['FFPYPLAYER_CODECS'] = 'h264,h265,vp9,vp8' # Support common codecs os.environ['SDL_VIDEO_ALLOW_SCREENSAVER'] = '0' # Prevent screen saver +# Video playback optimizations +os.environ['KIVY_WINDOW'] = 'pygame' # Use pygame backend for better performance +os.environ['KIVY_AUDIO'] = 'ffpyplayer' # Use ffpyplayer for audio +os.environ['KIVY_GL_BACKEND'] = 'gl' # Use OpenGL backend +os.environ['FFMPEG_THREADS'] = '4' # Use 4 threads for ffmpeg decoding +os.environ['LIBPLAYER_BUFFER'] = '2048000' # 2MB buffer for smooth playback +os.environ['SDL_AUDIODRIVER'] = 'alsa' # Use ALSA for better audio on Pi + # Configure Kivy BEFORE importing any Kivy modules from kivy.config import Config -# Disable default virtual keyboard - we'll use our custom one -Config.set('kivy', 'keyboard_mode', '') + +# Performance optimizations for video playback +Config.set('kivy', 'keyboard_mode', '') # Disable default virtual keyboard +Config.set('graphics', 'fullscreen', '0') # Will be set to 1 later +Config.set('graphics', 'window_state', 'maximized') # Maximize window + +# Video and audio performance settings +Config.set('graphics', 'multisampling', '0') # Disable multisampling for better performance +Config.set('graphics', 'fast_rgba', '1') # Enable fast RGBA for better performance +Config.set('audio', 'channels', '2') # Stereo audio +Config.set('kivy', 'log_level', 'warning') # Reduce logging overhead from kivy.app import App from kivy.uix.widget import Widget @@ -1315,7 +1332,7 @@ class SignagePlayer(Widget): self.next_media() def play_video(self, video_path, duration): - """Play a video file using Kivy's Video widget""" + """Play a video file using Kivy's Video widget with optimizations""" try: # Verify file exists if not os.path.exists(video_path): @@ -1326,15 +1343,23 @@ class SignagePlayer(Widget): Logger.debug(f"SignagePlayer: Loading video {os.path.basename(video_path)} for {duration}s") - # Create Video widget with optimized settings + # Create Video widget with optimized settings for smooth playback self.current_widget = Video( source=video_path, state='play', # Start playing immediately options={ 'eos': 'stop', # Stop at end of stream + 'ff_opts': { + # FFmpeg options for better playback performance + 'buffer_size': '2048000', # 2MB buffer + 'threads': '4', # Multi-threaded decoding + 'fflags': '+ignidx', # Ignore index for better seeking + }, + 'allow_fallback': True, # Allow codec fallback }, size_hint=(1, 1), - pos_hint={'center_x': 0.5, 'center_y': 0.5} + pos_hint={'center_x': 0.5, 'center_y': 0.5}, + anim_delay=1.0/60.0 # 60 FPS animation ) # Bind to loaded and error events