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.
This commit is contained in:
Kiwy Player
2026-01-17 20:41:31 +02:00
parent e735e85d3c
commit 6bf4e3735a
5 changed files with 108 additions and 7 deletions

View File

@@ -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