Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 64 additions & 9 deletions bin/start_viewer.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,77 @@ trap '' 16
# Disable swapping
echo 0 > /sys/fs/cgroup/memory/memory.swappiness

if [ "$DEVICE_TYPE" = "pi5" ]; then
# Clean up any stale X server processes and lock files
pkill Xorg
rm -f /tmp/.X0-lock /tmp/.X11-unix/X0

# Start X server with dummy video driver and cursor disabled
export DISPLAY=:0
Xorg "$DISPLAY" -s 0 dpms -nocursor &
XORG_PID=$!

# Wait for X server to be ready with timeout
TIMEOUT=30
TIMEOUT_COUNT=0
while [ $TIMEOUT_COUNT -lt $TIMEOUT ]; do
if xset -display :0 q > /dev/null 2>&1; then
echo "X server is ready"
break
fi

# Check if X server process is still running
if ! kill -0 $XORG_PID 2>/dev/null; then
echo "X server failed to start"
exit 1
fi

echo "Waiting for X server to be ready (${TIMEOUT_COUNT}/${TIMEOUT}s)"
sleep 1
TIMEOUT_COUNT=$((TIMEOUT_COUNT + 1))
done

if [ $TIMEOUT_COUNT -eq $TIMEOUT ]; then
echo "X server failed to start within $TIMEOUT seconds"
exit 1
fi

# Now that X is ready, configure display settings
xset -display "$DISPLAY" s off
xset -display "$DISPLAY" s noblank
xset -display "$DISPLAY" -dpms

# Hide cursor immediately after X server is ready
xset -display "$DISPLAY" -cursor_name left_ptr
# Alternative: completely hide cursor
xset -display "$DISPLAY" -cursor_name none
fi

# Start viewer
sudo -E -u viewer dbus-run-session python -m viewer &
VIEWER_PID=$!

# Wait for the viewer
while true; do
PID=$(pidof python)
if [ "$?" == '0' ]; then
break
fi
sleep 0.5
# Wait for the viewer with timeout
TIMEOUT=30
TIMEOUT_COUNT=0
while [ $TIMEOUT_COUNT -lt $TIMEOUT ]; do
if kill -0 $VIEWER_PID 2>/dev/null; then
break
fi
echo "Waiting for viewer to start (${TIMEOUT_COUNT}/${TIMEOUT}s)"
sleep 1
TIMEOUT_COUNT=$((TIMEOUT_COUNT + 1))
done

if [ $TIMEOUT_COUNT -eq $TIMEOUT ]; then
echo "Viewer failed to start within $TIMEOUT seconds"
exit 1
fi

# If the viewer runs OOM, force the OOM killer to kill this script so the container restarts
echo 1000 > /proc/$$/oom_score_adj

# Exit when the viewer stops
while kill -0 "$PID"; do
sleep 1
while kill -0 "$VIEWER_PID"; do
sleep 1
done
6 changes: 5 additions & 1 deletion docker/Dockerfile.viewer.j2
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,16 @@ RUN curl "{{webview_base_url}}/webview-{{qt_version}}-{{debian_version}}-{{board
curl "{{webview_base_url}}/webview-{{qt_version}}-{{debian_version}}-{{board}}-{{webview_git_hash}}.tar.gz.sha256" \
-sL -o "/tmp/webview-{{qt_version}}-{{debian_version}}-{{board}}-{{webview_git_hash}}.tar.gz.sha256" && \
cd /tmp && \
sha256sum -c "webview-{{qt_version}}-{{debian_version}}-{{board}}-{{webview_git_hash}}.tar.gz.sha256" && \
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revert this change before merging.

tar -xzf "/tmp/webview-{{qt_version}}-{{debian_version}}-{{board}}-{{webview_git_hash}}.tar.gz" -C /usr/local && \
rm "webview-{{qt_version}}-{{debian_version}}-{{board}}-{{webview_git_hash}}.tar.gz"

ENV QT_QPA_EGLFS_FORCE888=1
{% if board == 'pi5' %}
ENV QT_QPA_PLATFORM=xcb
ENV DISPLAY=:0
{% else %}
ENV QT_QPA_PLATFORM=linuxfb
{% endif %}

# Turn on debug logging for now
#ENV QT_LOGGING_RULES=qt.qpa.*=true
Expand Down
9 changes: 9 additions & 0 deletions tools/image_builder/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,15 @@ def get_viewer_context(board: str) -> dict:
]

if board in ['pi5', 'x86']:
if board == 'pi5':
apt_dependencies.extend([
'xserver-xorg-core',
'xserver-xorg-video-fbdev',
'x11-xserver-utils',
'xauth',
'xinit',
])

apt_dependencies.extend([
'qt6-base-dev',
'qt6-webengine-dev',
Expand Down
37 changes: 23 additions & 14 deletions viewer/media_player.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from __future__ import unicode_literals

from os import getenv

import sh
import vlc

Expand All @@ -25,6 +27,23 @@ def stop(self):
def is_playing(self):
raise NotImplementedError

def get_alsa_audio_device(self):
if settings['audio_output'] == 'local':
if get_device_type() == 'pi5':
return 'default:CARD=vc4hdmi0'
elif get_device_type() == 'x86':
return 'default:CARD=HID'
return 'plughw:CARD=Headphones'
else:
if get_device_type() in ['pi4', 'pi5']:
return 'default:CARD=vc4hdmi0'
elif get_device_type() in ['pi1', 'pi2', 'pi3']:
return 'default:CARD=vc4hdmi'
elif get_device_type() == 'x86':
return 'hdmi:CARD=PCH'
else:
return 'default:CARD=HID'


class FFMPEGMediaPlayer(MediaPlayer):
def __init__(self):
Expand All @@ -38,6 +57,10 @@ def set_asset(self, uri, duration):
self.player_kwargs = {
'_bg': True,
'_ok_code': [0, 124],
'_env': {
'AUDIODEV': self.get_alsa_audio_device(),
'DISPLAY': getenv('DISPLAY', ':0')
}
}

def play(self):
Expand Down Expand Up @@ -66,20 +89,6 @@ def __init__(self):

self.player.audio_output_set('alsa')

def get_alsa_audio_device(self):
if settings['audio_output'] == 'local':
if get_device_type() == 'pi5':
return 'default:CARD=vc4hdmi0'

return 'plughw:CARD=Headphones'
else:
if get_device_type() in ['pi4', 'pi5']:
return 'default:CARD=vc4hdmi0'
elif get_device_type() in ['pi1', 'pi2', 'pi3']:
return 'default:CARD=vc4hdmi'
else:
return 'default:CARD=HID'

def __get_options(self):
return [
f'--alsa-audio-device={self.get_alsa_audio_device()}',
Expand Down