Releases: Unknownplanet40/CapsStream
Release list
CapsStream v2.61.0.0
Type: minor
From: 2.60.0.0
To: 2.61.0.0
Commits:
- feat(ui): update background logo and calibrate top 10 rank heights (25773bb)
Summary
Updates the application's central background watermark mask to use the new circular emblem logo and precisely calibrates the Top 10 rank number typography so glyph heights match the media card poster height.Added
- Added
static/img/new-logo.pngto the repository assets and service workerPRECACHE_ASSETSlist.
Changed
- Updated
body::beforemask instatic/css/main.cssto use/static/img/new-logo.pngwith theme accent colorization and ambient breathing glow. - Calibrated
.top10-rank-numberfont-size (calc(var(--top10-h) * 1.41)) and vertical offset (translateY(calc(var(--top10-h) * 0.05))) to align digit glyph ink flush with the top and bottom of.media-card. - Unified rank
"10"height scaling with single digits and tuned desktop/mobile horizontal overlaps.
- Added
Auto-released via conventional commits.
Full Changelog: v2.60.0.0...v2.61.0.0
CapsStream v2.60.0.0
Type: minor
From: 2.59.2.0
To: 2.60.0.0
Commits:
-
feat(settings): add toggle to disable trailers across homepage, media cards, and details (978d259)
Closes #12Summary
Introduces a new "Trailers & Video Previews" toggle in Settings under Playback Defaults that allows users to disable trailer playback across the homepage hero banner, TV layout previews, media cards hover popouts, and detail pages.
Added
- Added
enable_trailerssetting to default playback configuration inbackend/settings.pyand the frontend reactive store. - Added "Trailers & Video Previews" toggle switch to the Settings page under Player & Subtitle Defaults.
Changed
MediaCard: Popout preview skips trailer fetching and video stream fallback when trailers are disabled.HeroBanner: Ambient trailer playback and trailer action buttons are hidden/disabled when trailers are turned off.TvContentRow/TvHero: Video preview embeds and quick trailer actions are suppressed when disabled.DetailPageand global trailer modal: Explicit trailer watch attempts display an informative toast and prevent loading if trailers are disabled.- App startup now loads and syncs
store.playbacksettings alongside system features.
- Added
-
feat(profiles): auto-select single profile if no pin is set and redirect to homepage (
a88d1ec)
Closes #11Summary
Automatically authenticates and activates the profile on startup when only a single profile exists without a PIN configured, directing the user straight to the homepage instead of halting on the profile selection screen.
Added
- Automatic authentication and direct homepage redirection for single PIN-less profile setups on application startup.
Changed
- App initialization session check in
static/js/app.jsnow evaluates profile count and PIN protection status before falling back to the/profilesselector. - Retains prompt on the profile selector screen (
/profiles) whenever multiple profiles exist or when the single profile has a PIN configured.
-
feat(player): suppress player controller on rewind/forward seek on desktop (
9718dd3)
Closes #10Summary
Suppresses the player controller UI overlay on desktop devices when seeking via the rewind/forward buttons, keyboard arrow keys, or media keys, ensuring the video view remains unobstructed.
Added
- Desktop device detection helper (
isDesktopDevice) combining fine-pointer media query and viewport/touch heuristics. - Seek-time controls suppression window (
suppressControlsUntil) to prevent mouse jitter and resume events from unhiding the controller.
Changed
skip()now accepts asuppressControlsoption to keep controls hidden on desktop seeking.onVideoPlaying()now checks desktop device status and respects hidden controls on playback resume following a seek.- Controller rewind (
#ctrl-rewind) and forward (#ctrl-forward) buttons now callskip()with@click.stopand controls suppression enabled on desktop. - Keyboard shortcuts (
ArrowLeft,ArrowRight,j,l,MediaFastForward,MediaRewind, and0-9) now suppress controller reveal on desktop.
- Desktop device detection helper (
-
feat(player): conditionally show subtitle options between controller and settings (
664b866)
Closes #9Summary
Conditionally display subtitle selection between the main player controller bar and the player settings menu: when multiple subtitles exist, the dedicated controller button handles selection and it is omitted from the settings menu; when only one subtitle is available, it is shown in the settings menu instead.
Changed
- Updated the subtitles navigation row in the player settings menu to only display when
subtitles.length <= 1, avoiding duplicate controls when the dedicated player controller subtitle menu is already visible.
- Updated the subtitles navigation row in the player settings menu to only display when
-
fix(core): bundle vendor scripts and fonts locally for 100% offline self-hosting (
26a1f65)
Closes #8Summary
Bundle all runtime dependencies (Vue 3, Vue Router 4, Hls.js, Phosphor Icons) and Google Fonts locally to allow CapsStream to load and run seamlessly without an internet connection, fixing crashes when offline.
Added
- Local vendor runtime scripts under
static/vendor/:vue.global.prod.js(Vue 3)vue-router.global.prod.js(Vue Router 4)hls.min.js(Hls.js)@phosphor-icons/webstylesheets and woff2 font files (regular,bold,fill,light,thin,duotone) with mastericons.cssbundle.
- Local web fonts in
static/fonts/:Anton,Bebas Neue,Geist, andPlus Jakarta Sanswoff2 files with self-containedfonts.css.
Changed
- Replaced external CDN
<script>and<link>tags intemplates/index.htmlwith local/static/vendor/and/static/fonts/paths. - Updated
static/sw.jsto cache-first local/static/vendor/and/static/fonts/assets and bumped cache version tocapsstream-core-v2.60.0.
Fixed
- Fixed
net::ERR_NETWORK_CHANGEDandReferenceError: Vue is not definedcrash when launching or reloading CapsStream offline or without active internet access.
- Local vendor runtime scripts under
-
feat(ui): add floating dynamic island connection loss banner and polish media cards (
ab8e965)
Closes #7Summary
Add a floating dynamic island notification for network disconnection / server unreachability with a retry action, lock the Top 10 row height to prevent vertical scrollbars, restrict hover glow strictly to Top 10 rank numerals, and adopt full-bleed clean media card styling without hover scaling across all library views.
Added
- Dynamic floating island connection banner (
.connection-island) with glassmorphic styling, pulsing red status dot, and retry button on connection loss. - Reconnect animation state showing a green checkmark and "Back Online" message with auto-dismiss after 2.5s.
AntonandBebas Neuefont imports in templates/index.html for crisp, condensed Top 10 numbers.
Changed
- Applied full-bleed, borderless media card styling (
padding: 0,border-radius: 4px) across all cards. - Locked Top 10 row height with
--top10-h: 260px(desktop) and165px(mobile), and hidden vertical scrollers. - Restyled Top 10 rank numbers to match media card height 1:1 using condensed display typography.
- Restricted hover glow strictly to Top 10 rank numbers (removed white border and scaling on card hover).
- Removed scale transform (
scale(...)/translateY(...)) from media cards and continue watching cards for a stable, clean browsing experience. - Cleaned up obsolete static
.offline-bannerfrom.banners-container.
- Dynamic floating island connection banner (
-
fix(ui): polish Top 10 rank numbers and add glassmorphic popout info box (
bfe69cf)Summary
Visual polish pass on the Top 10 row rank numbers (position, color,
spacing) and adds 50% transparency + backdrop blur to the media card
popout info box for a glassmorphic look.Changed
.top10-rank-number: switched from faded semi-transparent gradient to
solid dark fill (#0d0e15) with crisp white stroke (3.5px, 0.9 alpha)
andpaint-order: stroke fillfor clean edges. Increased font size to
clamp(80px, 10vw, 130px), tightenedline-heightto 0.85 so the
number baseline aligns with the card bottom edge rather than floating
below it. Stronger drop-shadow for depth..top10-card-wrapper: removed hover scale/translate animation
(transition: none), addedmargin-right: 38pxfor consistent card
spacing, reducedmargin-leftto -20px..top10-scroller: addedalign-items: flex-endto anchor all wrappers
to the same baseline; added explicitpadding-right: calc(var(--page-gutter) + 56px)
so the last rank+card pair is never clipped when scrolled to the end..top10-rank-number[data-rank="10"]: adjusted sizes and margins for the
two-digit case. Mobile breakpoint values updated to match..popout-info-box: replaced solid#161622background with
rgba(22, 22, 34, 0.5)+backdrop-filter: blur(16px)for a
glassmorphic card info panel.
-
fix(library): fix 500 on /api/home caused by m.type alias in Top 10 subquery (
Summary
Stage 3 of get_top_10() used {type_sql} (which references m.type)
inside an inner subquery that selects from media with no table alias,
causing sqlite3.OperationalError: no such column: m.type and a 500 on
every /api/home request.
Fixed
-
Added
type_sql_barevariant (unaliased:type = 'movie'/
type IN ('series', 'anime')) inbackend/db/media.py. -
Stage 3 inner subquery now uses
{type_sql_bare}so the column
reference matches the unaliasedFROM mediacontext. -
feat(library): add Top 10 Movies and Top 10 TV Shows rows (
2af0083)Summary
Implements Netflix-style Top 10 rows on the Home page (both Movies and
Series), and on the Movies, Series, and Anime library tabs. Rankings use
a three-stage hybrid: profile watch history → global household watch
history → TMDb rating/popularity fallback, with Kids Mode filtering.Added
get_top_10(media_type, profile_id, limit)inbackend/db/media.py:
three-stage hybrid ranking (profile watch time → global watch time →
TMDb rating) with deduplication byCOALESCE(tmdb_id, title)group
and disabled-path filtering. Attaches a 1-basedrankfield to every
returned item.- Exported
get_top_10frombackend/db/__init__.py. GET /api/top10?type=movie|seriesendpoint inbackend/routes/media.py
for standalone use by library tab pages, respects Kids Mode.- Injected "Top 10 Movies Today" and "Top 10 TV Shows Today" rows into
/api/homeresponse (profile-scoped, after Continue Watching, before
cached catalog rows). top10-row,top10-scroller,top10-card-wrapper, and
top10-rank-numberCSS classes instatic/css/main.css:
giant outlined/gradient rank numbers (clamp 72–115 px desktop,
58 px mobile), negative-margin overlap ...
CapsStream v2.59.2.0
Type: patch
From: 2.59.1.0
To: 2.59.2.0
Commits:
- fix(ui): restore wrapped story layout, fix volume slider visibility, and polish player controls (dfeffa1)
Summary
Restores the broken layout and missing slide styling across CapsStream Wrapped stories, centers the volume slider thumb and resolves unhovered container bleed, moves Picture-in-Picture and Edit Skip Markers into standard player settings navigation rows, and elevates the dynamic island with smooth in/out transitions.Added
- Complete slide styles for Wrapped story modal (hero watch-time card, obsession spotlight card, genre leaderboard, speed binge records, audio & subtitle DNA card, viewing rhythm card, talent cast grid, UHD cinema tech specs, archetype grand reveal, and poster export slide).
- Missing rarity badges (.rarity-badge bronze, silver, gold, platinum) for Wrapped achievements and obsession cards.
- Dedicated Subtitles submenu pane in the player settings panel (activeSettingsSubmenu === 'subtitles') with full track selection, online search, and custom file loading.
- Apple-grade scale and blur transition states for the player dynamic island.
Changed
- Elevated .player-dynamic-island position across desktop (+30px), mobile portrait (+24px), and mobile landscape (+20px) to provide clear separation from seekbar and control docks.
- Converted Picture-in-Picture (PiP) and Edit Skip Markers into standard .player-menu-nav-row elements grouped with top navigation items before the divider.
- Subtitle quick-access button (#ctrl-subs) now hides when there is <= 1 subtitle track (matching audio tracks behavior), deferring single-track control to Player Settings.
- Improved Wrapped story header typography and chip responsiveness to eliminate 2-line title and profile wrapping on compact viewports.
Fixed
- Restored unstyled/broken Wrapped story slides caused by missing inner slide CSS rules.
- Fixed volume slider circle thumb vertical centering by explicitly locking -webkit-slider-runnable-track and -moz-range-track heights to 4px with a -5px margin offset.
- Fixed volume slider thumb and track peeking out when unhovered by setting width: 0, opacity: 0, padding: 0, and pointer-events: none on .volume-slider-container while idle.
- Added flex-shrink: 0 to .volume-slider to prevent range input deformation during width collapse/expand transitions.
Auto-released via conventional commits.
Full Changelog: v2.59.1.0...v2.59.2.0
CapsStream v2.59.1.0
Type: patch
From: 2.59.0.0
To: 2.59.1.0
Commits:
- fix(launcher): resolve post-update server boot failure due to mutex race condition (1074251)
Summary
After an update restart, the_finish_update_helper.pyrelaunchedsilent_launcher.py --restarted
while the previous launcher instance was still in itsfinallycleanup block, holding the
CapsStream_Launcher_Instance_Mutex. The new instance saw the mutex as already held and
immediately exited with "Another silent launcher instance is already active", leaving the
server process orphaned and never booted.Fixed
_acquire_launcher_mutex()now usesbInitialOwner=Trueso the mutex is owned on creation,
making it a proper synchronization primitive. The function accepts atimeout_secparameter
and willWaitForSingleObjectfor that duration onERROR_ALREADY_EXISTS.main()now reads--restartedbefore the mutex check and passesmutex_timeout=15when
invoked from a restart, giving the exiting launcher up to 15 seconds to release the mutex.data/launcher.pidis written on startup and deleted in thefinallyblock so the restart
helper can identify and wait for the old launcher process.start_server()now passesCAPSSTREAM_LAUNCHER_PIDin the server's environment so
spawn_restart_helper()can read it without touching the filesystem.
Changed
spawn_restart_helper()readsCAPSSTREAM_LAUNCHER_PIDfrom env (fallback:data/launcher.pid)
and appends the launcher PID assys.argv[3]to the helper invocation._RESTART_HELPER_SRCnow waits for the old launcher process to exit (up to 15 s, then
forcibly kills it), then waits for theCapsStream_Launcher_Instance_Mutexto release
(up to 10 s) before spawning the newsilent_launcher --restarted, guaranteeing no race.pid_alive()in the helper guards againsttarget <= 0before calling Win32 APIs.
Added
test_spawn_restart_helper_passes_launcher_pidinbackend/tests/test_updater.pyverifies
the launcher PID is appended to the helper command line whenCAPSSTREAM_LAUNCHER_PIDis set.
Auto-released via conventional commits.
Full Changelog: v2.59.0.0...v2.59.1.0
CapsStream v2.59.0.0
Type: minor
From: 2.58.0.0
To: 2.59.0.0
Commits:
- feat(media): add missing artwork and recache manager, enhanced TMDb lookup, and player touch scrubbing (1f0a964)
Summary
Introduces an automated Missing Artwork & Re-cache Manager in settings with automatic background artwork healing during library scans. Extends TMDb matching with direct IMDb ID, numeric ID, and batch episode overrides. Enhances the media player with mobile touch scrubbing, magnetic snapping, and a consolidated dynamic notice system, alongside robust offline drive detection and standard layout defaulting for Android TV.Added
- Missing Artwork & Re-cache Manager in Settings allowing one-click batch re-caching of media missing local posters or backdrops with a live progress bar and offline filtering.
- get_media_needing_recache() database helper and authenticated GET /api/media/needs-recache endpoint.
- _heal_missing_artwork() scanner routine to automatically restore missing artwork for online matched titles during library scans.
- Direct IMDb ID (tt\d+) and numeric TMDb ID lookup support in search_tmdb().
- Batch media_ids matching support in api_override() to sync all episodes of an unmatched series simultaneously.
- Touch scrubbing support (touchstart, touchmove, touchend) on the player seekbar with magnetic snapping near chapter and intro/outro markers.
- Clamped seekbar hover tooltip with real-time time delta indicator (+m:ss / -m:ss).
- Progressive loading indicator card with gentle status messaging for massive TV series libraries.
- Comprehensive test suite for the re-cache manager in backend/tests/test_recache_manager.py.
Changed
- clear_cache() in backend/settings.py now purges all media records, watch progress, collection items, favorites, playlist items, resets sqlite sequence, and wipes in-memory matcher caches for a true clean slate.
- Enhanced api_system_drives_status() to discover drives containing indexed media files directly from the database even if omitted from explicit scanner paths.
- Consolidated player warning notices (low memory, 4K stutter, codec notices, auto-switch, freeze alerts) into a single computed activeDynamicNotice to prevent visual overlapping.
- Android TV MainActivity.kt defaults interface layout mode to standard and safely clears legacy auto-activated TV mode.
- Relocated Keyboard Shortcuts trigger to the user profile dropdown in both standard and TV headers.
- Updated search pagination, recommendations, and home rows to respect the hideOfflineMedia setting consistently.
Auto-released via conventional commits.
Full Changelog: v2.58.0.0...v2.59.0.0
CapsStream v2.58.0.0
Type: minor
From: 2.57.2.0
To: 2.58.0.0
Commits:
- feat(android-tv): add dynamic versioning to companion APK builds and refine release workflows (5edeba2)
Summary
Inject the dynamic release version tag into the Android TV companion app Gradle build, streamline CI release packaging to publish versioned APK assets, and update user documentation and agent guidelines.Added
- Support for dynamic
versionNameproperty injection inclients/android-tv/app/build.gradlevia-PversionName. - Direct links in
README.mdguiding users to download the Android TV companion APK from GitHub Releases.
Changed
- Updated
.github/workflows/auto-release.ymland.github/workflows/release.ymlto pass the release version to the Gradle build step. - Streamlined release APK publishing and checksum calculation to target the versioned APK asset (
CapsStream-AndroidTV-${VERSION}.apk). - Updated
AGENTS.mdto reflect the Android TV client architecture, native tray integration, and current release conventions.
- Support for dynamic
Auto-released via conventional commits.
Full Changelog: v2.57.2.0...v2.58.0.0
CapsStream v2.57.2.0
Type: patch
From: 2.57.1.0
To: 2.57.2.0
Commits:
- fix(ui): improve keyboard shortcuts modal, profile schema fallback, resolution badges, and APK build workflows (ac05ddc)
Summary
Redesign the keyboard shortcuts modal with reactive search, category tabs, and elevated z-index positioning above the navbar; fix schema fallbacks for legacy profile tables missing theme/admin columns; correct UHD BluRay 1080p resolution matching; and include Android TV Companion APK generation in main CI and release workflows.Added
- Dynamic search and category filters for keyboard shortcuts cheatsheet with real-time matching.
- Automatic Android TV Companion APK building on push to
maininbuild-android-tv.yml. - Inclusion of
CapsStream-AndroidTV*.apkcompanion build and checksums in GitHub Release workflows. - Test coverage for UHD BluRay resolution probing and fallback query execution.
Changed
- Elevated keyboard shortcuts modal backdrop to
z-index: 2500with top safe-padding offset to prevent navbar overlap. - Modernized genre tags into sleek glassmorphic pill chips with responsive wrapping and tactile feedback.
- Placed media quality badge into a dedicated row beneath
detail-meta.
Fixed
- Prevented
OperationalErrorwhen querying profiles on legacy or unmigrated SQLite databases lackingthemeoris_admincolumns. - Corrected media resolution probe hierarchy so explicit 1080p/720p tokens take precedence over source markers like UHD BluRay.
- Prevented 4K playback auto-switch guard from triggering on 1080p UHD BluRay encodes.
- Added mock for
backend.scannerin route unit test suite to isolate test executions.
Auto-released via conventional commits.
Full Changelog: v2.57.1.0...v2.57.2.0
CapsStream v2.57.1.0
Type: patch
From: 2.57.0.0
To: 2.57.1.0
Commits:
- fix(settings): hide Supabase relay section when requests feature is inactive (1f67593)
Summary
Conditionally hide the Supabase Cloud Relay inputs and divider in Settings when the media requests feature is inactive so obsolete configuration controls are not shown.Fixed
- Hide the Supabase Cloud Relay setting row and separator in the Settings metadata section when
store.features?.requestsis inactive.
- Hide the Supabase Cloud Relay setting row and separator in the Settings metadata section when
Auto-released via conventional commits.
Full Changelog: v2.57.0.0...v2.57.1.0
CapsStream v2.57.0.0
Type: minor
From: 2.56.1.0
To: 2.57.0.0
Commits:
- feat(requests): enable media requests and add online cloud relay integration (ccda32a)
Summary
Enables the media requests system by default and adds an online cloud relay powered by Supabase REST API (PostgREST) so external clients outside the local network (Desktop 2) can submit requests to the server (Desktop 1) seamlessly without port forwarding or VPNs. Includes full TMDb digital release status tracking, overhauled card and modal layouts, and enhanced player controls.Added
- Online media request cloud relay via Supabase REST API (
backend/utils/supabase_client.py) using zero-dependency urllib HTTP client with connection testing and automatic fallback. - Supabase PostgreSQL schema and Row Level Security policies (
docs/supabase_schema.sql) for client isolation and DEV mode management. - Digital release availability detection (
backend/matcher.py) querying TMDb theatrical and digital release dates to inform users if requested titles have home media copies. - Unit and integration tests for online requests, digital release detection, and collection-to-playlist generation (
backend/tests/test_online_requests.py,backend/tests/test_digital_release_detection.py,backend/tests/test_collection_to_playlist.py). - Digital release status indicators and pills in Vue frontend (
static/js/app.js,static/css/main.css).
Changed
- Enabled
features.requestsandfeatures.online_requestsby default inDEFAULT_CONFIG(backend/settings.py). - Refactored media request item cards (
.req-item-card) with separated metadata and action rows to eliminate button cramping and avatar collisions across screen sizes. - Enhanced request modal to display real-time digital release indicators, countdowns, and library availability before submission.
- Updated player controls and audio/subtitle switching workflows in
static/js/player.js.
Fixed
- Fixed layout collision between requester avatar/date and fulfillment action buttons in DEV mode.
- Fixed long theatrical status chips causing status badges to wrap onto secondary rows.
- Online media request cloud relay via Supabase REST API (
Auto-released via conventional commits.
Full Changelog: v2.56.1.0...v2.57.0.0
CapsStream v2.56.1.0
Type: patch
From: 2.56.0.0
To: 2.56.1.0
Commits:
- fix(tests): stabilize test suite across POSIX and mock environments (fb9c785)
Summary
Resolves test suite failures in CI and POSIX environments by removing hardcoded Windows binary assumptions, broadening chapter skip classifiers, normalizing drive status path separators, and refining schema migration fallbacks.Fixed
- Streaming Routes: Dispatched module-level streamer helpers so unit test patches on backend.streamer and backend.routes.streaming are honored properly without relying on inline imports.
- Profiles Fallback: Removed theme column from initial sqlite3.OperationalError fallback query and defaulted missing columns so older schemas load without errors.
- Chapter Skip Detection: Broadened chapter marker keyword matching for opening, ending, and preview tags; handled FileNotFoundError gracefully when ffprobe is missing.
- Drive Health: Normalized path separators to forward slashes when calculating media file counts per drive, fixing mismatches between Windows paths and POSIX separators.
- FFmpeg Binary Resolution: Added system PATH resolution fallback via shutil.which when bundled Windows executables are absent, and removed hard file existence checks that bypassed mocks in describe_hw_encoder and find_keyframe_before.
- Mount Checking: Corrected POSIX mount detection for Windows-style drive letters and test mock paths so media items are properly recognized as mounted during automated testing.
Auto-released via conventional commits.
Full Changelog: v2.56.0.0...v2.56.1.0