Releases: tousled/home-cinema-control
Releases · tousled/home-cinema-control
Home Cinema Control 1.1.3-rc.2
Added
-
Added opt-in product telemetry and roadmap feedback controls on the Diagnostics screen. Telemetry is disabled by
default, uses a random anonymous installation ID, retries failed sends through a bounded local queue, and documents
exactly what is sent and why. HCC never sends media titles, libraries, paths, URLs, IPs, tokens, logs, scripts, or
custom commands in telemetry payloads. -
Added a new poll for user feedback on the Diagnostics screen. Next features can be voted on in the poll.
The most qualified features will be implemented first.
Fixed
- Denon and Marantz AV receivers now query their available inputs dynamically via the
SSSOD ?TCP command instead
of returning a fixed hardcoded list. Only inputs the receiver reports as enabled (USE) are shown. If the receiver
is unreachable during detection, HCC falls back to a built-in catalog that now includes AUX 1 and AUX 2 — the two
entries previously missing that prevented users with an OPPO connected to those inputs from selecting the correct
source. A fixed bug in the Denon fallback list sentGAME\ninstead ofSIGAME\n, which would have silently
ignored the command.
Home Cinema Control 1.1.3-rc.1
Docker images published for 1.1.3-rc.1.
See CHANGELOG.md for the full project history.
Home Cinema Control 1.1.2
Fixed
- Fixed the Logs and Diagnostics copy buttons for browsers that block or hide the Clipboard API. Copying the visible
log lines and the support summary now falls back to the browser's legacy copy path instead of showing errors such as
Cannot read properties of undefined (reading 'writeText')or failing when clipboard permission changes.
Home Cinema Control 1.1.1
Added
- Release tag pushes now create a GitHub Release automatically after the Docker image publishes, with release notes
extracted from the matchingCHANGELOG.mdsection and release-candidate tags falling back to their base version
section when there is no exact RC changelog heading. - Added mobile-friendly log sharing controls to the Logs screen: the console now defaults to the latest 100 visible
lines, offers larger preset ranges, and can copy the currently filtered/shown lines directly to the clipboard.
Fixed
- Fixed Jellyfin 12.0 RC1 compatibility after Jellyfin's
20260531160000_DisableLegacyAuthorizationmigration disables
legacy authorization. HCC now sends Jellyfin REST credentials through the modern
Authorization: MediaBrowser ... Token=...
header and opens the Jellyfin WebSocket with modernAuthorizationplus legacy token headers, and both modern
ApiKeyand legacyapi_keyquery parameters. This addresses Jellyfin 12 startup failures that showed
403 Forbiddenduring WebSocket handshake and401from/Devices,/Library/VirtualFolders, or
/Sessions/Capabilities/Fullwithout breaking Jellyfin 10.x WebSocket authentication. - Fixed Diagnostics version display and rollback guidance for release-candidate Docker tags. Runtime versions produced
bysetuptools_scmare now shown in Docker tag form (1.1.1-rc.1, not1.1.1rc1), update-triggered rollback stores
that tag form, and installs whose config only contains the build fallback (0.0.0.dev0) derive a rollback target from
GitHub releases/tags instead of showing the fallback as a real image version. - Fixed version checks so the "include pre-release versions" toggle selects the expected release channel: disabled shows
the latest stable release, enabled shows the latest release candidate/pre-release when one exists. - Fixed rollback target selection for release candidates so
1.1.1-rc.2rolls back to1.1.1-rc.1, while
1.1.1-rc.1prefers the same-base stable1.1.1over older release candidates such as1.1.0-rc.5. - Updated the Docker Hub overview to mention Jellyfin support and the current log copy/download support flow.
Home Cinema Control 1.1.1-rc.3
Added
- Release tag pushes now create a GitHub Release automatically after the Docker image publishes, with release notes
extracted from the matchingCHANGELOG.mdsection and release-candidate tags falling back to their base version
section when there is no exact RC changelog heading. - Added mobile-friendly log sharing controls to the Logs screen: the console now defaults to the latest 100 visible
lines, offers larger preset ranges, and can copy the currently filtered/shown lines directly to the clipboard.
Fixed
- Fixed Jellyfin 12.0 RC1 compatibility after Jellyfin's
20260531160000_DisableLegacyAuthorizationmigration disables
legacy authorization. HCC now sends Jellyfin REST credentials through the modern
Authorization: MediaBrowser ... Token=...
header and opens the Jellyfin WebSocket with modernAuthorizationplus legacy token headers, and both modern
ApiKeyand legacyapi_keyquery parameters. This addresses Jellyfin 12 startup failures that showed
403 Forbiddenduring WebSocket handshake and401from/Devices,/Library/VirtualFolders, or
/Sessions/Capabilities/Fullwithout breaking Jellyfin 10.x WebSocket authentication. - Fixed Diagnostics version display and rollback guidance for release-candidate Docker tags. Runtime versions produced
bysetuptools_scmare now shown in Docker tag form (1.1.1-rc.1, not1.1.1rc1), update-triggered rollback stores
that tag form, and installs whose config only contains the build fallback (0.0.0.dev0) derive a rollback target from
GitHub releases/tags instead of showing the fallback as a real image version. - Fixed version checks so the "include pre-release versions" toggle selects the expected release channel: disabled shows
the latest stable release, enabled shows the latest release candidate/pre-release when one exists. - Fixed rollback target selection for release candidates so
1.1.1-rc.2rolls back to1.1.1-rc.1, while
1.1.1-rc.1prefers the same-base stable1.1.1over older release candidates such as1.1.0-rc.5. - Updated the Docker Hub overview to mention Jellyfin support and the current log copy/download support flow.
Home Cinema Control 1.1.1-rc.2
Added
- Release tag pushes now create a GitHub Release automatically after the Docker image publishes, with release notes
extracted from the matchingCHANGELOG.mdsection and release-candidate tags falling back to their base version
section when there is no exact RC changelog heading.
Fixed
- Fixed Jellyfin 12.0 RC1 compatibility after Jellyfin's
20260531160000_DisableLegacyAuthorizationmigration disables
legacy authorization. HCC now sends Jellyfin REST credentials through the modern
Authorization: MediaBrowser ... Token=...
header and opens the Jellyfin WebSocket with modernAuthorizationplus legacy token headers, and both modern
ApiKeyand legacyapi_keyquery parameters. This addresses Jellyfin 12 startup failures that showed
403 Forbiddenduring WebSocket handshake and401from/Devices,/Library/VirtualFolders, or
/Sessions/Capabilities/Fullwithout breaking Jellyfin 10.x WebSocket authentication. - Fixed Diagnostics version display and rollback guidance for release-candidate Docker tags. Runtime versions produced
bysetuptools_scmare now shown in Docker tag form (1.1.1-rc.1, not1.1.1rc1), update-triggered rollback stores
that tag form, and installs whose config only contains the build fallback (0.0.0.dev0) derive a rollback target from
GitHub releases/tags instead of showing the fallback as a real image version.
Jellyfin compatibility 12.0 RC1
[1.1.1] - 2026-06-27
Fixed
- Fixed Jellyfin 12.0 RC1 compatibility after Jellyfin's
20260531160000_DisableLegacyAuthorizationmigration disables
legacy authorization. HCC now sends Jellyfin REST credentials through the modern
Authorization: MediaBrowser ... Token=...
header and opens the Jellyfin WebSocket with modernAuthorizationplus legacy token headers, and both modern
ApiKeyand legacyapi_keyquery parameters. This addresses Jellyfin 12 startup failures that showed
403 Forbiddenduring WebSocket handshake and401from/Devices,/Library/VirtualFolders, or
/Sessions/Capabilities/Fullwithout breaking Jellyfin 10.x WebSocket authentication.
Jellyfin Integration
[1.1.0] - 2026-06-26
Added
- Path mappings, detected libraries, the library-filter preference, and the monitored device now persist
independently per media-server provider (media_servers.providers[type].playback), instead of one shared block
used by whichever provider happened to be active. Switching between Emby and Jellyfin now shows each provider's
own mappings/libraries/device, and switching back restores them exactly as left — the same guarantee already
shipped for auth in 1.0.5. Includes an automatic, one-time migration of existing installs' config. - Added toast feedback for the Media Server provider switch: a confirmation when the switch lands on an
already-authorized provider (previously silent — the only feedback was a transient "connecting…" state), and a
distinct message when the switch succeeds but the target provider still needs login. - Added a provider-branded Media Server hero mark that surfaces the selected Emby/Jellyfin provider without repeating
the server URL, user, or readiness details already shown in the configuration panels. The mark stays visible as
setup context while the provider is pending authorization, but renders muted until the provider is authorized. - Updated the Media Server installation screenshots to show provider selection, the Jellyfin hero mark, and the muted
provider state shown before authorization. - Added a compact active-provider badge to Media Paths so the detected-library and route-mapping workflow keeps the
configured Emby/Jellyfin context visible without overloading the refresh action. - Added a shared, provider-neutral
find_controlling_session_idpolicy (media_servers/common/models.py) that
resolves which client session actually issued a remote Play command, used by both Emby and Jellyfin. - Instrumented two previously invisible OPPO startup phases — mounting the network share (
mount_oppo_network_share,
includes the device-list-ready wait) and waiting for the OPPO to actually report active playback
(wait_for_oppo_playback_active, the QPL telnet poll after launching the file) — into the existing
PlaybackStartupTimer. Before this, a slow OPPO response in either phase showed up as an unexplained gap between
the named steps and the printedtotalin "Playback startup timing summary," with no way to tell from the log
alone whether the OPPO, the TV/AV output switch, or something else caused it. No behavior change: both are
optional, timer-only wrapping. - Added a first-run modal offering to import a legacy XNOPPO
config.json(the predecessor project this app
replaces) on a fresh install with nothing configured yet, separate from the existing "legacy config already on
disk" migration modal. The user picks the oldconfig.jsonfile, HCC migrates AV/TV/OPPO/playback settings the
same way the existing migration pipeline already does, moves the Emby server URL into the new multi-provider
config shape, and makes a best-effort live login with the file's username/password to obtain a real access token
— if that login fails (e.g. the Emby server isn't reachable yet), the provider is just left unauthenticated, same
as any freshly added provider, and the existing sidebar readiness indicator shows it needs attention.
Fixed
- Fixed the Media Server setup screen treating saved provider data as live success when the active Emby/Jellyfin server
is unavailable. The form now renders from saved config immediately instead of waiting for slow device/library
discovery timeouts, failed device discovery is shown explicitly, affected panels no longer stay green, and the
sidebar setup dot is downgraded while the current provider cannot be reached. - Fixed the monitored-device selector showing blank rows when a provider returned devices in a non-canonical shape or
without display labels. Device options are now normalized defensively and invisible rows are filtered out. - Fixed media-server provider switches activating/restarting the runtime listener before the target provider was usable.
Selecting an unconfigured provider now saves it as a draft only; expired or unreachable targets leave the current
websocket listener untouched; configured targets are checked before any active-playback confirmation or listener swap. - Fixed Jellyfin playback-startup notifications never being sent at all. Jellyfin's
Playwebsocket message has the
same gap Emby's already-shipped fix (1.0.5) covers — it never identifies the controlling client's own session,
only the bridge's target session — but the fix was never ported to Jellyfin. Every notification silently no-opped
with "no active source session is available." - Fixed Jellyfin source-client cleanup at playback finish using the bridge target session when Jellyfin's
Play
command only providedId. HCC now treatsIdas the target session, resolves the real controlling client
session, and sends the same doubleStopused for Emby so the Jellyfin app clears its stale playback screen when
the OPPO is stopped from the remote. - Fixed Jellyfin Web/App remote-control screens remaining on a frozen playback view after OPPO remote Stop by applying
the same best-effort doubleStopdelivery used for Emby to Jellyfin's source client session. - Fixed Jellyfin multi-client cleanup when the same user has the web UI and mobile app open for the same HCC playback.
HCC now resolves active Jellyfin sessions for that user, excludes its own bridge session, skips only sessions that
explicitly report a different now-playing item, and sends best-effort doubleStopto each stale client instead of
only the single session that originally issued Play. - Fixed
JellyfinClient.send_session_messagesendingText/Header/TimeoutMsas query-string parameters (Emby's
shape) instead of the JSON request body Jellyfin's server actually requires, and sending an emptydata={}body
that omitted theContent-Typeheader entirely, which Jellyfin's server rejects with415 Unsupported Media Type. Confirmed against a real Jellyfin server's own error responses. - Fixed
JellyfinClient.get_user_viewscalling a route that does not exist (/Users/{userId}/Views). The real
route isGET /UserViews?userId=.... Jellyfin library detection had likely never worked on any real install —
masked by theModuleMediaServerSetupServicebug below, which silently absorbed the resulting failure. - Fixed
ModuleMediaServerSetupService.load_devices/load_libraries/load_selectable_foldersdiscarding the
provider module's actual return value and always returning the pre-call config unchanged. Freshly detected
libraries, devices, and path mappings were computed correctly and then thrown away before reaching the UI, for
both Emby and Jellyfin. - Fixed
MediaServerLibraryreading every library as inactive for any install whoseplayback.librariespredates
this value object (every install before this provider-boundary refactor) — those entries use raw
Id/Name/Active(capitalized) instead of the model'sid/name/active. A model validator now normalizes
the legacy shape instead of silently defaultingactivetoFalse. find_controlling_session_id's Jellyfin-side session lookup now narrows server-side via the confirmed
controllableByUserIdquery parameter instead of fetching every active session on the server for every single
Play command.- Fixed the existing "legacy config found" migration silently discarding
emby_server/user_name/user_password
from an XNOPPO-era flatconfig.jsoninstead of migrating them — those keys were already listed as legacy
(so they got removed) but no step ever moved the server URL anywhere first.TV_KEY/TV_DeviceName(no current
equivalent — LG pairing now goes through a separate key store) are now dropped instead of lingering as orphaned
fields. - Fixed the Docker image being unable to complete a truly fresh install (no existing config volume at all):
the multi-stage build refactor droppedconfig.example.jsonfrom the final runtime stage, so
ensure_config_exists()had nothing to seedconfig.jsonfrom and crashed on every container start. - Fixed
secrets.jsoncarrying a stale, empty single-providermedia_serverstub forever. It was seeded by
default for every install before the multi-providermedia_servers.providers.*shape existed, and was only ever
cleaned up when the public config also had real legacymedia_serverdata — which an XNOPPO-era flat config
never has. It's no longer seeded for new installs, and existing installs self-heal it on the next config save or
container restart. - Fixed the "include pre-release versions" checkbox on the Diagnostics page never actually persisting — it was a
local-only UI ref, never read from saved config on load and never saved when toggled, so it silently reset to
off on every page reload. As a result the version check always ran with pre-releases excluded no matter how the
checkbox looked, even though the backend filtering logic itself (fixed in 1.1.0-rc.2) was already correct. The
checkbox now loads its saved state and persists immediately on toggle. - Fixed
compose.yaml(the file users/NAS deployments actually run) carrying bothimage:andbuild:. Several
Docker GUIs (Portainer's "deploy stack from Git" pointed at a tag, among others) build from the compose file's
build:section instead of pulling the named image — silently producing a locally-rebuilt image stamped
0.0.0.dev0(theSETUPTOOLS_SCM_PRETEND_VERSIONbuild-arg's fallback, since nothing setsHCC_VERSIONin that
flow) instead of the real, correctly-versioned image from the registry.compose.yamlis now pull-only; the
build:section moved to a local-only, untracked override file for development.
Changed
- Documented that Jellyfin...