Skip to content

Releases: Screenly/Anthias

2026.08.1

Choose a tag to compare

@vpetersson-bot vpetersson-bot released this 14 Aug 10:25
3b06666

Highlights

HDMI-CEC, rebuilt. CEC now talks to the kernel uABI directly instead of
shelling out, so adapter discovery works on boards with more than one display
port rather than assuming /dev/cec0. Passthrough is fixed, and there is a new
display schedule that can turn the attached TV on and off on a timetable.

Large images no longer starve small boards. Oversized JPEG and PNG uploads
are downscaled during processing on low-RAM devices, which keeps multi-megapixel
photos from exhausting memory on the 1 GB and 512 MB boards.

Menu Board installs with its menu. Array-valued app settings render
correctly, fixing an install that previously came up empty.

Quieter viewer, faster failure. Two noisy Sentry/journal sources are
silenced, and the viewer now fails fast when it loses the display instead of
sitting in a degraded state. Diagnostics also bounds the CEC subprocess reap and
reports its states distinctly.

Telemetry reports the release version, so usage can finally be broken down
by version.

Plus website and API-reference refreshes, and a round of dependency updates.

What's Changed

Other Changes 🔧

Full Changelog: v2026.08.0...v2026.08.1

2026.08.0

Choose a tag to compare

@vpetersson-bot vpetersson-bot released this 05 Aug 16:25
f5ff6fd

Highlights

This release is a bug-fix and hardening round focused on image handling,
headless display recovery, and networking in restricted environments.

  • Images now honour EXIF orientation (#3233) — portrait photos taken on a
    phone no longer display sideways, on both the upload-normalisation path and
    the viewer's direct-render path.
  • Large images no longer exhaust memory on low-RAM boards (#3235) — a
    high-megapixel upload is downscaled to the board's pixel budget before
    encoding, instead of pushing a Pi 3 / Pi 2 into an OOM reboot.
  • Viewer recovers from the Wayland headless-boot display wedge (#3240) —
    a board that boots with no display attached now retries in a bounded way
    rather than sitting on a blank screen.
  • HTTP proxies are honoured across install and runtime (#3242, #3239) —
    Anthias installs and runs behind a corporate proxy.
  • x86 cold-boot DNS race fixed (#3231) — systemd-resolved is now
    installed on x86, so the first boot after an install resolves names reliably.
  • Local-console installs no longer kill the active TTY (#3241).
  • Idle websockets no longer trip a Redis channel-layer read timeout
    (#3229).

Plus dependency updates, an expanded ruff ruleset, added viewer test coverage,
and website SEO fixes.

What's Changed

Other Changes 🔧

Full Changelog: v2026.07.4...v2026.08.0

2026.07.4

Choose a tag to compare

@vpetersson vpetersson released this 28 Jul 09:31
7fe850c

What's Changed

Other Changes 🔧

  • fix(viewer): rotate 180 video in the ISP on the linuxfb boards (Pi 1/2/3) by @vpetersson in #3207
  • fix(viewer): route audio_output to a live PulseAudio sink on x86/arm64 by @vpetersson in #3209
  • fix(server): serve remote-hosted image previews from their source URL by @vpetersson in #3211
  • test: isolate settings-save tests from the shared on-device config by @vpetersson-bot in #3215
  • chore(deps-dev): bump the python group with 4 updates by @dependabot[bot] in #3214
  • chore(deps): bump the github-actions group with 8 updates by @dependabot[bot] in #3213
  • chore(deps): bump the bun group with 3 updates by @dependabot[bot] in #3212
  • chore: add curated Claude knowledge base and un-ignore it by @vpetersson in #3210
  • chore: scrub fleet-scale metrics from the release knowledge base by @vpetersson-bot in #3216
  • fix(ci,device): drop workflow_dispatch ref input + narrow bare except in CPU info parser by @vpetersson-bot in #3217
  • fix(deps): pin pillow-heif to 1.4.0 to unbreak the armhf build by @vpetersson-bot in #3218
  • fix(website): unescape JSON-LD strings, answer "is this Screenly OSE?" by @vpetersson-bot in #3222
  • chore(deps): bump docker/login-action from 4.4.0 to 4.5.1 in the github-actions group by @dependabot[bot] in #3220
  • chore(release): bump version metadata to 2026.07.4 by @vpetersson-bot in #3223

New Contributors

Full Changelog: v2026.07.3...v2026.07.4

2026.07.3

Choose a tag to compare

@vpetersson vpetersson released this 16 Jul 18:22
a782add

Highlights — screen rotation, fixed & consistent everywhere

screen_rotation now works correctly and rotates the same way on every board and for every asset type:

  • Images and web pages now rotate on Pi 1/2/3 (linuxfb) — previously only video turned (#3197).
  • Pi 3 (64-bit) video follows screen_rotation — hardware overlay plane for 0°/180°, raster fallback for 90°/270° (#3189).
  • Rotation direction unified to clockwise across all display stacks — linuxfb (Pi 1/2/3), eglfs (Pi 3-64/4) and wayland (Pi 5/x86) previously disagreed; a given screen_rotation now looks identical on every device (#3202).

Validated across the physical testbed (Pi 2, Pi 3 32/64-bit, Pi 4, Pi 5, x86, Rock Pi 4) with all four asset types (image, video, web page, RTSP stream) and a multi-hour soak.

Other notable changes

  • Native date/time pickers for schema format fields (#3187).
  • Pi 2 boot splash no longer falls back to the plain text theme (#3199).
  • Supply-chain: container image signing + SBOM generation (#3186, #3200).

What's Changed

Other Changes 🔧

  • feat(apps): render native date/time pickers for schema format fields by @vpetersson in #3187
  • chore(release): bump version metadata to 2026.07.2 by @vpetersson in #3188
  • fix(viewer): rotate pi3-64 video by dropping the vc4 overlay when rotated by @vpetersson in #3189
  • chore(release): bump version metadata to 2026.07.3 by @vpetersson in #3190
  • fix(webview): rotate images and web pages on linuxfb (Pi 1/2/3) by @vpetersson in #3197
  • docs(website): recommend Raspberry Pi Imager, demote curl|bash to advanced by @vpetersson in #3191
  • chore(deps-dev): bundle five Python dependency bumps by @vpetersson in #3201
  • chore(deps): use the uv Dependabot ecosystem so uv.lock stays in sync by @vpetersson in #3203
  • fix(viewer): rotate eglfs/wayland clockwise to match linuxfb + video by @vpetersson in #3202
  • chore(deps): ignore Django major updates in the python group by @vpetersson in #3206
  • chore(deps-dev): bump the python group with 11 updates by @dependabot[bot] in #3205
  • chore(deps-dev): bump the bun group across 1 directory with 2 updates by @dependabot[bot] in #3204
  • fix(image-builder): silence platform lint + sign container images by @vpetersson in #3186
  • fix(splash): stop the Pi 2 boot splash falling back to the text theme by @vpetersson in #3199
  • Updates SBOM generation by @vpetersson in #3200

Full Changelog: v2026.07.2...v2026.07.3

2026.07.2

Choose a tag to compare

@vpetersson vpetersson released this 13 Jul 15:39
88eb857

Highlights ✨

Fixes the Pi 2 / Pi 3 blank-screen crash and adds a content-import framework for migrating from other signage platforms, alongside a batch of viewer and platform improvements.

  • Pi 2 / Pi 3 blank screen fixed — the Qt5 WebEngine viewer no longer crash-loops on armv7 boards. Modern Debian gcc emitted a misaligned 64-bit NEON store in QtWebEngine that faulted (SIGBUS) on the Cortex-A7 / A53, leaving a permanent blank screen; the Qt5 toolchain is now built with arm_use_neon=false + a -mno-unaligned-access cross-compiler wrap. Validated end-to-end on real Pi 2 and native 32-bit Pi 3 hardware, and it also resolves the ANTHIAS-D / ANTHIAS-F heap-corruption crashes (#3184, closes #3022).
  • Import content from other signage platforms — a new extensible import-provider framework pulls playlists and assets from Yodeck, ScreenCloud, piSignage, and Xibo CMS.
  • Self-signed HTTPS media & pages — a verify_ssl toggle with a per-asset override so internal/self-hosted HTTPS content renders instead of failing.
  • Per-asset custom HTTP headers, timezone selection & on-device clock in Settings, and bulk edit of No cache / Skip asset check.
  • Pi 3 (64-bit) hardware video — 30 fps playback with audio, plus reduced-seam in-slot looping.
  • Stability — Chromium low-memory profile and bounded viewer output on ~1 GB boards, a swapoff-OOM upgrade fix, resumable-upload isolation, and WebSocket / Celery / Sentry hardening.

What's Changed

Other Changes 🔧

  • feat(import): import content from Yodeck via an extensible import-provider framework by @vpetersson in #3144
  • feat(import): add ScreenCloud (GraphQL) provider to the import framework by @vpetersson in #3145
  • feat(import): add OptiSigns (GraphQL) provider to the import framework by @vpetersson in #3146
  • feat(import): add piSignage (REST) provider to the import framework by @vpetersson in #3148
  • feat(import): add Xibo CMS (REST) provider to the import framework by @vpetersson in #3149
  • docs(import): list all supported import providers by @vpetersson in #3151
  • feat(bulk-edit): add No cache & Skip asset check to mass edit; restore nocache in viewer by @vpetersson in #3150
  • fix(import): correct ScreenCloud endpoints/download; broaden Yodeck files by @vpetersson in #3152
  • Update index.html by @JonnyTech in #3153
  • fix(import): correct OptiSigns field mapping and extension source by @vpetersson in #3154
  • chore(import): remove the OptiSigns provider by @vpetersson in #3157
  • fix(viewer): bound AnthiasViewer output instead of buffering it in RAM by @vpetersson in #3147
  • fix(sentry): drop operator-input/config noise events (#3034) by @vpetersson in #3158
  • fix(viewer): self-heal a headless-boot Wayland display wedge by @vpetersson in #3155
  • fix(upload): isolate resumable uploads with a per-request temp path by @vpetersson in #3159
  • refactor(viewer): split start_viewer.sh into per-platform libs by @vpetersson in #3161
  • fix(viewer): stop webpage transitions flashing a foreign page by @vpetersson in #3160
  • feat(settings): add userspace timezone selection and a device clock by @vpetersson in #3163
  • chore(deps): bump the github-actions group with 6 updates by @dependabot[bot] in #3173
  • fix(upgrade): stop swapoff OOM from aborting run_upgrade by @vpetersson in #3172
  • feat(webview): per-asset custom HTTP headers for web assets by @vpetersson in #3162
  • chore(deps): bundle routine dependency bumps by @vpetersson in #3175
  • pi3-64 hardware video playback (30fps, zero drops) + audio by @vpetersson in #3164
  • feat(ssl): support self-signed HTTPS media/pages via verify_ssl + per-asset override by @vpetersson in #3176
  • pi3-64: reduced-seam in-slot video looping (SEGMENT seeks) by @vpetersson in #3174
  • fix(viewer): force Chromium's low-memory profile on ~1 GB boards by @vpetersson in #3178
  • feat(website): generate llms.txt and llms-full.txt by @vpetersson in #3179
  • fix(celery): give reconcile_stuck_processing a soft time limit by @vpetersson in #3180
  • fix(sentry): drop client-disconnect static-file noise by @vpetersson in #3182
  • fix(ws): tolerate a client that disconnects mid-broadcast by @vpetersson in #3181
  • fix(image-builder): consume WebView-v2026.07.1 Qt5 toolchain by @vpetersson in #3185
  • fix(webview): stop Pi 2/3 blank screen from gcc NEON alignment SIGBUS by @vpetersson in #3184

Full Changelog: v2026.07.1...v2026.07.2

WebView-v2026.07.1

Choose a tag to compare

@vpetersson vpetersson released this 13 Jul 14:08
bd78617

Qt 5.15.19 cross-compile toolchain tarballs for the 32-bit Raspberry Pi boards (pi2, pi3), consumed at viewer-image build time via tools/image_builder (qt5_toolchain_url) and docker/Dockerfile.qt5-webview-builder.j2.

Bumped from WebView-v2026.07.0 to carry the armv7 NEON-alignment fix: arm_use_neon=false (QtWebEngine's Chromium gn args) plus a -mno-unaligned-access wrapper on the arm-linux-gnueabihf-{gcc,g++} cross compilers in src/anthias_webview/build_qt5.sh. This stops the Pi 2/3 blank-screen crash-loop caused by gcc lowering struct init/copy of 8-byte-aligned types into a NEON :64 block-store that faults on the 4-byte-aligned pointers QtWebEngine hands it (Unhandled fault: alignment exception (0x801) / SIGBUS; the ARM kernel can't fix up NEON).

Validated on real hardware:

  • Binary: the fixed libQt5WebEngineCore.so has the alignment-asserted NEON block stores stripped ~27x (pi2 159, pi3 157 vs 4251 in the unfixed build).
  • Runtime: the unfixed build crash-loops with a blank screen on both a Pi 2 (Cortex-A7) and a native 32-bit Pi 3 (Cortex-A53); these toolchains produce a stable viewer that renders webpage / image / video with 0 alignment traps across a multi-hour soak.
  • The pi2 toolchain here was clean-rebuilt from scratch (no ccache / no Docker cache) and reproduces the fix.

Assets:

  • qt5-5.15.19-trixie-pi2.tar.gz (+ .sha256)
  • qt5-5.15.19-trixie-pi3.tar.gz (+ .sha256)

2026.07.1

Choose a tag to compare

@vpetersson vpetersson released this 08 Jul 07:40
99073a4

Highlights

A point release rolling up the fixes and features merged since 2026.07.0. Notable themes:

Backup / restore (streaming, low-RAM safe)

  • The restore upload is streamed to disk instead of read() into memory, so a multi-GB restore no longer OOMs the worker on a 1 GB Pi (#3143). Pairs with the streamed backup download shipped in 2026.07.0 (#3074).

Viewer & display

  • linuxfb display mode is re-asserted after an HDMI hotplug, so the picture comes back at full resolution when a TV is power-cycled (#3075)
  • Stale PulseAudio pid file is cleared on start so HDMI audio survives a reboot (#3113)
  • pi3-64 ships +rpt1 ffmpeg so H.264 uses hardware decode (#3110)

Assets & API

  • New signage app store in the Add Asset flow (#3114)
  • Absolute-path asset URIs are confined to the asset directory (#3117) and youtube_asset downloads are gated on a real YouTube URL (#3118)
  • Asset duration is bounded to prevent a viewer crash-loop (#3128); disk-full uploads are handled gracefully (#3133)
  • The update check picks the latest CalVer release rather than GitHub's /releases/latest (#3130)

Reliability & telemetry

  • Offline-device and operator-input events are dropped in Sentry before_send to cut noise (#3132, #3141)
  • Reboot/shutdown survives a down balena supervisor (#3131)

Install & build

  • Install probes actual sudo capability instead of guessing from the sudoers filename (#3129)
  • Frozen Qt 5 webview toolchain bumped to 5.15.19 (#3121)

Tested on hardware ✅

Full 6-board testbed QA of this release is green (Pi 2, Pi 3-64, Pi 4, Pi 5, x86, Rock Pi 4):

  • REST API v1 / v1.1 / v1.2 / v2 — all checks pass on every board.
  • Rendering — image, web page, and video present on all six boards, with hardware video decode verified (Pi 5 HEVC, Pi 4 H.264).
  • Backup / restore streaming (#3074 + #3143) — end-to-end validated on all three 1 GB boards (pi3-64, pi4-64, Rock Pi 4) with a real 641 MB backup: streamed both directions, peak RSS ~70–170 MiB (far below the archive size), full restore, 0 OOM, 0 container restarts.

Two pre-existing, non-regressing findings remain tracked separately: choppy 1080p presentation on the Qt6 Pi boards (#2987) and stop/blank not pausing the loop on headless Wayland (#3136).


What's Changed

Other Changes 🔧

  • docs(website): promote Raspberry Pi Imager across the site by @vpetersson in #2919
  • fix(website): correct Pi 3 board status on get-started page by @vpetersson in #3111
  • fix(build): ship +rpt1 ffmpeg on pi3-64 so H.264 uses HW decode by @vpetersson in #3110
  • fix(viewer): clear stale PulseAudio pid file so audio survives reboot by @vpetersson in #3113
  • feat(assets): add signage app store to the Add Asset flow by @vpetersson in #3114
  • fix(assets): name store-app assets from their chosen setting, not the manifest name by @vpetersson in #3115
  • feat(ui): add Star on GitHub / Review on G2 CTAs by @vpetersson in #3116
  • fix(api): confine absolute-path asset URIs to the asset directory by @vpetersson in #3117
  • fix(api): gate youtube_asset downloads on a real YouTube URL by @vpetersson in #3118
  • fix(system-info): tidy up x86 Device Info (CEC state + device model) by @vpetersson in #3119
  • docs: point Screenly migration guide at the in-app wizard by @vpetersson in #3120
  • chore(webview): bump frozen Qt 5 toolchain to 5.15.19 by @vpetersson in #3121
  • fix(assets): bound asset duration to prevent viewer crash-loop by @vpetersson in #3128
  • fix(server): handle disk-full uploads gracefully by @vpetersson in #3133
  • fix(sentry): drop offline-device gaierror events in before_send by @vpetersson in #3132
  • fix(server): pick latest CalVer release, not GitHub /releases/latest by @vpetersson in #3130
  • fix(celery): survive a down balena supervisor in reboot/shutdown by @vpetersson in #3131
  • fix(install): probe sudo capability instead of guessing from sudoers filename by @vpetersson in #3129
  • fix(viewer): re-assert linuxfb display mode after HDMI hotplug by @vpetersson in #3075
  • fix(api): stream the recover upload to disk instead of read() by @vpetersson in #3143
  • fix(sentry): drop expected operator-input/transient noise (round 2) by @vpetersson in #3141
  • chore(release): bump to 2026.07.1 by @vpetersson in #3139

Full Changelog: v2026.07.0...v2026.07.1

WebView-v2026.07.0

Choose a tag to compare

@vpetersson vpetersson released this 07 Jul 08:01
4c61d40

Qt 5.15.19 cross-compile toolchain for the frozen 32-bit Qt 5 Pi boards (pi2, pi3), Debian Trixie / armhf. Bumps the previous 5.15.14 toolchain to the latest Qt 5.15 LTS patch. Consumed at viewer-image build time via qt5_toolchain_url in tools/image_builder/utils.py; the pi2/pi3 QtWebView is cross-compiled against these tarballs.

2026.07.0

Choose a tag to compare

@vpetersson vpetersson released this 02 Jul 12:29
87e8259

Highlights

A monthly roll-up of the fixes and features merged since 2026.06.3. Notable themes:

Display & viewer

  • Screen rotation now works on all cage/Wayland boards (Pi 5, arm64) (#3047)
  • New blank/unblank commands to turn the display off/on (#3065)
  • "Prefer dark mode" setting for web-page assets (#3050)

Assets & playback

  • Bulk asset management — enable/disable/edit/delete from the home screen (#3048), plus restored multi-file bulk upload (#3049) and UI/UX polish (#3066)
  • New assets now display without a restart: the viewer detects DB changes under SQLite WAL mode (#3062)
  • RTSP / streaming URLs are classified as streaming rather than web pages (#3071)
  • yt-dlp format selection biased toward the board's HW-decoded codec (Pi 5 HEVC) (#3093)

Reliability & telemetry

  • Celery soft-limits on the display-power and telemetry pokes so a slow poke can't SIGKILL the worker (#3063)
  • Settings-save input validation no longer reported to Sentry as errors (#3068)
  • Backup is streamed as an async iterator so large backups don't time out (#3074)

Install & build

  • armhf builds moved off the retired Linaro toolchain to Debian's crossbuild toolchain (#3070)
  • polkitd installed on the Trixie+ manage-network path (#3060); pi3-64 accepted in Ansible validation (#3067); Pi 3 image stream detected from userspace arch (#3076); python3-dev added for the armv7l cffi build (#3100)
  • collect_debug.sh for debugging faulty installations (#3077)
  • Disk images compressed with xz instead of zstd (#3107); rpi-imager images tagged with hardware devices so they list in Imager (#3090)

Tested on hardware ✅

Full integrated-stack end-to-end validation of this release's images across three hardware classes. Every supported asset type was driven through the real viewer and verified to load and play back:

Asset type x86 (amd64) Raspberry Pi 5 Raspberry Pi 4
Image
Video ✅ H.264 ✅ HEVC (HW decode) ✅ H.264 (HW decode)
Web page

All four services (server / viewer / celery / redis) healthy on every board, with a clean error/crash scan across the run. Pi 5 HEVC and Pi 4 H.264 confirmed using the hardware video decoders.


What's Changed

Other Changes 🔧

  • fix(viewer): recognize all cage/Wayland boards for screen rotation by @vpetersson in #3047
  • fix(server): restore multi-file (bulk) upload in the Add Asset modal by @vpetersson in #3049
  • feat(viewer): add "Prefer dark mode" setting for web page assets by @vpetersson in #3050
  • fix(balena): add missing device types to unpin fleet map by @vpetersson in #3051
  • fix(install): install polkitd on Trixie+ manage-network path; minimize apt updates by @vpetersson in #3060
  • feat(server): add bulk asset management (enable/disable/edit/delete) by @vpetersson in #3048
  • chore(deps): bump grouped Dependabot updates and refresh uv.lock by @vpetersson in #3064
  • fix(viewer): detect DB changes under WAL so new assets load by @vpetersson in #3062
  • fix(server): polish home bulk-action & upload UI/UX by @vpetersson in #3066
  • fix(celery): soft-limit the display-power and telemetry pokes by @vpetersson in #3063
  • feat(viewer): blank/unblank commands to turn the display off by @vpetersson in #3065
  • fix(install): accept pi3-64 in Ansible playbook validation by @vpetersson in #3067
  • fix(sentry): don't report settings-save input validation as errors by @vpetersson in #3068
  • fix(build): replace retired Linaro armhf toolchain with Debian's by @vpetersson in #3070
  • fix(server): classify RTSP/streaming URLs as streaming, not webpage by @vpetersson in #3071
  • fix(server): stream the backup as an async iterator so it doesn't time out by @vpetersson in #3074
  • fix(install): detect Pi 3 image stream from userspace arch, not kernel by @vpetersson in #3076
  • feat(bin): add collect_debug.sh for debugging faulty installations by @vpetersson in #3077
  • chore(deps-dev): bump the bun group with 3 updates by @dependabot[bot] in #3083
  • chore(deps): bump pytest, certifi, ansible-core, sentry-sdk by @vpetersson in #3086
  • chore(deps): bump msgpack from 1.1.2 to 1.2.1 by @dependabot[bot] in #3091
  • fix(server): allow LAN/private hosts in asset reachability probe by @vpetersson in #3103
  • chore(deps): bump the github-actions group across 1 directory with 5 updates by @dependabot[bot] in #3105
  • feat(webview): append Anthias version to the User-Agent by @vpetersson in #3102
  • docs(website): cover root-password sudo/curl gap in x86 install guide by @vpetersson in #3106
  • fix(install): add python3-dev for armv7l cffi build by @vpetersson in #3100
  • chore(images): compress disk images with xz instead of zstd by @vpetersson in #3107
  • chore(deps): consolidated dependency bump by @vpetersson in #3108
  • fix: bias yt-dlp format_sort toward board's HW-decoded codec (Pi 5 HEVC) by @TekScene in #3093
  • fix(rpi-imager): tag images with hardware devices so Imager lists them by @vpetersson in #3090
  • chore(release): bump to 2026.07.0 by @vpetersson in #3109

New Contributors

Full Changelog: v2026.06.3...v2026.07.0

2026.06.3

Choose a tag to compare

@vpetersson vpetersson released this 09 Jun 08:05
fe8f054

Maintenance release rolling up everything since 2026.06.1 (the 2026.06.2 bump was never cut as a release). Focus areas: arm64/Qt6 board support, Sentry error tracking, viewer/webview crash-recovery, and server/celery resilience. Cutting this triggers the balena OTA deploy to all screenly_ose/anthias-* fleets; unpinned devices pull it and restart.

New boards & fleets

  • feat(viewer,build,balena): add arm64/Qt6 pi3-64 board and the Rock Pi 4 fleet; keep 32-bit pi3 as legacy (#2985).

Observability

  • feat(sentry): add Sentry error tracking to the Django services (#3007).
  • feat(sentry): tag events with device type, host kernel, and board model (#3021).
  • feat(sentry): stamp the release with the build hash and tag balena deploys (#3025).
  • fix(sentry): stop reporting transient redis blips and client disconnects (#3018), also drop transient redis TimeoutError events (#3028), and silence the celery redis-backend reconnect-retry log (#3036).
  • fix(celery): don't report the by-design codec rejection to Sentry (#3041).

Performance

  • perf(viewer): pace Qt6 video frame delivery to scene-render capacity (#3006).
  • fix(viewer): aspect-fit, gapless looping, and 30fps cap for pi1/2/3 video (#3004).

Viewer & webview

  • fix(viewer): run PulseAudio so Qt 6 video plays with audio (#3001).
  • fix(viewer): default x86 audio fallback to ALSA 'default' (#3038).
  • fix(viewer): wait for cage's Wayland socket before spawning the webview (#3030).
  • fix(webview): add a page-load watchdog so a stalled fetch can't freeze the display (#3003).
  • fix(viewer): respawn the webview when it dies mid-D-Bus call (#3012), before setup's bus.get (#3020), and on a video-play D-Bus death rather than log+stop (#3031).
  • fix(viewer): silence sh's monitor-thread crash report on webview exit (#3011).

Server & celery resilience

  • fix(server): open SQLite with WAL journaling and a busy timeout (#3015).
  • fix(celery): gate worker startup on applied database migrations (#3016).
  • fix(celery): catch the asset-probe timeout instead of hard-killing the worker (#3017).
  • fix(celery): store display_power in redis as a string, not a bool (#3032).
  • fix(server): survive unreadable static files instead of crash-looping (#3026).
  • fix(server): keep legacy host timezones from crash-looping Django (#3010).
  • fix(server): stream the backup download so large libraries don't time out (#3005).
  • fix(views): accept 12-hour AM/PM times in the asset edit form (#3002).
  • fix(server): surface the exception detail in GitHub update-check warnings (#3023) and log release-check failures at warning, not error (#3019).

Uploads

  • feat(server): offer HandBrake GUI steps for rejected video uploads (#3040).

Balena fleet automation

  • feat(balena): hourly job to unpin pinned fleet devices (#2980).
  • feat(balena): unpinner also rolls OS + supervisor updates (#2984).

Build & infra

  • fix(build): ship libwebpdemux2 so pi3 Pillow can save WebP (#3042).
  • fix(redis): persist data to the mounted volume so device identity survives recreation (#2983).
  • fix(docker): pull the BuildKit frontend via mirror.gcr.io (#3008).
  • Fixes SBOM (#2982).

Dependencies

  • Bump uvicorn 0.32.1 → 0.49.0 (#2991), pyyaml 6.0.2 → 6.0.3 (#2993), django-stubs 6.0.3 → 6.0.5 (#2989), types-python-dateutil (#2992), and the github-actions group (#2994).