Added
- TV & Display Power Button with Dual-Entity Pairing (Issue #60):
- Top-right circular frosted glass power button with unified
36pxdimensions across Active Playback, Ambient Showcase, and Idle Card states. - State-responsive visual styling: crisp white (
#ffffff, matching the pause icon) when ON or ready; dimmed gray-white (rgba(255, 255, 255, 0.45), matching the−volume button) when OFF or in standby. Zero cyan glow. - Multi-domain support for
media_player,switch,script,button,scene, andinput_boolean. - Automatic fallback:
power_entityis completely optional; if not specified, it automatically falls back to controlling the card's primary selected Media Player (entity). - Deterministic TV power: issues
media_player.turn_offandmedia_player.turn_onrather than toggling apps when controlling media players. - Dual-entity pairing via
power_state_entityfor stateless scripts/IR blasters combined with true state sensors (e.g. smart plugs or ping sensors). - Configurable
stop_on_power_off(defaulttrue) which automatically halts active Jellyfin playback and saves progress when the TV is powered down. - Haptic feedback (
_haptic('light')) on tap with visual depression:activeanimation and activating pulse. - Expanded 48px touch hit area around the frosted glass button for effortless, reliable tapping on wall tablets and touchscreens without altering card layout.
- Top-right circular frosted glass power button with unified
- Capsule Volume Slider with Tactile Scrubbing on Now Playing Card (Issue #60):
- Translucent pillow capsule row positioned above the progress timeline bar with continuous track, dominant fill, percentage readout, mute toggle, and discrete
−/+step buttons. - External audio routing via
volume_entityto control AVRs or soundbars while streaming video via Jellyfin (falls back to primary media player if unspecified). - Discrete
_haptic('selection')tactile notches triggered every 5% interval during continuous slider scrubbing. - Responsive layout: automatically collapses continuous slider track in compact/poster views while preserving mute toggle, percentage readout, and step buttons.
- Translucent pillow capsule row positioned above the progress timeline bar with continuous track, dominant fill, percentage readout, mute toggle, and discrete
- Play on Jellyfin Client Action & Remote Session Control (Feature Request #62):
- Added native
play-client("Play on Jellyfin Client") action toclick_action,hold_action, anddouble_tap_actionon the Library Card, and'client'target support tomodal_play_actionsin the More Information dialog. - Enables direct 1-tap playback to supported Jellyfin client applications (Android TV, Google TV, Fire TV, Moonfin for Android, Jellyfin Web, Desktop/JMP, Wholphin, Roku, etc.) via Jellyfin's remote session control API (
POST /Sessions/{sessionId}/Playing?playCommand=PlayNow&itemIds={itemId}), bypassing Chromecast transcoding overhead entirely. - Documented client compatibility: noted that the official Jellyfin Android mobile app and iOS/Swiftfin currently do not implement incoming remote playback initiation commands, and recommended Wholpin, Moonfin or similar for Android mobile playback.
- Added configurable
default_client_devicein the Library Card YAML configuration and visual editor (filtered to JellyHA client device media playersmedia_player.jellyha_device_*). - Added interactive client device picker fallback in the More Information modal when multiple active client sessions are online or when no default device is configured.
- Smart Cast Delegation: Updated
jellyha.play_on_chromecastto automatically intercept JellyHA client device and session media player entities (media_player.jellyha_device_*,media_player.jellyha_user_*) and seamlessly route them tojellyha.session_play, preventing confusing Google Cast media receiver failures when users select their Jellyfin TV client instead of a Chromecast.
- Added native
- Now Playing Card Inline Media Type, Runtime & Rating Badges:
- When
badge_styleis set to "Inline with Metadata" ('inline'), Media Type badges (MOVIE,S01E01,SERIES), Runtime, and Community Rating badges are relocated directly inline into the metadata line alongside release year and genres ([Badge] • Year • Runtime • [★ Rating] [Genre]), matching the screensaver / idle card layout.
- When
- Simultaneous Multi-Device "Now Playing" Overlays on Library Card Posters:
- Dynamically resolves active media players on a per-poster basis across
default_cast_device,default_client_device(e.g. Wholphin, Moonfin, Android TV), and active JellyHA hardware players (media_player.jellyha_*). - Supports multiple posters simultaneously displaying active playback overlays with live status (
playing,paused,buffering,REWINDING) when different media items play across separate devices at the same time. - Controls (Play/Pause, Stop, Rewind) on each poster independently target the specific media player responsible for that title.
- Expanded
shouldUpdatereactive observation on the Library Card to re-render in real-time when playback starts, pauses, or stops across all candidate devices.
- Dynamically resolves active media players on a per-poster basis across
- Browser Player PlaybackInfo-Driven HLS Transcoding Fallback (Fixes #61):
- Automatically queries Jellyfin's
PlaybackInfoendpoint with a standardized HTML5 browser device profile to determine stream compatibility. - Transparent HLS transcoding fallback for video containers and audio codecs unsupported natively by desktop browsers (e.g., AVI/Xvid, AC3, DTS, TrueHD) while preserving zero-overhead DirectPlay for browser-compatible formats (H.264/AAC in MP4/WebM).
- Code-split dynamic loading of
hls.json Chromium, Firefox, and Edge browsers, paired with native HLS playback on Apple Safari and iOS devices (application/vnd.apple.mpegurl). - Secure in-memory capability token proxy (
/api/jellyha/hls/{token}/{path}) that dynamically sanitizes.m3u8master and variant playlists, rewriting segment routes and completely stripping Jellyfin API keys from client network traffic. - Active transcode session lifecycle management: automatically terminates active ffmpeg encoding sessions (
DELETE /Videos/ActiveEncodingsandPOST /Sessions/Playing/Stopped) when the browser modal is closed or on background idle session expiration, preventing orphaned transcoding jobs and server CPU exhaustion.
- Automatically queries Jellyfin's
Changes
- Media Player User & Device Naming Differentiation:
- Differentiated per-user and per-device media players in the Home Assistant UI by prefixing entity display names with
UserandDevice(rendering asJellyHA User <username>andJellyHA Device <device_name>). - Home Assistant automatically suggests
media_player.jellyha_user_<username>andmedia_player.jellyha_device_<device_name>for new entities. - Full backwards compatibility: preserved existing entity unique IDs so existing installations, automations, and scripts continue operating seamlessly without breaking changes.
- Differentiated per-user and per-device media players in the Home Assistant UI by prefixing entity display names with
- Configuration Wizard Multi-Instance, Device Selection & Library Flow:
- Structured the integration setup wizard into dedicated, intuitive steps:
- Select Libraries: Focused solely on choosing which Jellyfin libraries to include (
CONF_LIBRARIES) and configuring the library refresh interval (CONF_REFRESH_INTERVAL). - Select Client Devices (Optional): Directly select discovered Jellyfin client devices to automatically generate dedicated hardware media players (
CONF_DEVICE_PLAYERS) for control in Home Assistant and the JellyHA Now Playing Card. - Configure Instance: Dedicated step for assigning an optional instance label (
CONF_INSTANCE_LABEL) with comprehensive multi-instance and multi-server guidance (JellyHA Movies,JellyHA Music,JellyHA Server01,JellyHA Server02), eliminating user confusion between library selection and instance labels.
- Select Libraries: Focused solely on choosing which Jellyfin libraries to include (
- Structured the integration setup wizard into dedicated, intuitive steps:
- Automatic Lovelace Resource Version Cache-Busting:
- Automatically registers and updates
/jellyha/jellyha-cards.js?v={version}in Home Assistant Lovelace resource registry on integration startup, eliminating stale frontend caches across releases.
- Automatically registers and updates
Security
- Media Streaming & Subtitle Proxy Authentication Hardening:
- Eliminated unauthenticated
authSigquery parameter check and spoofableRefererheader bypasses inJellyHAStreamViewandJellyHASubtitleView. - Enforced strict Home Assistant session authentication (
hass_user) or cryptographically verified HMAC signatures (hass_refresh_token_id), closing potential authentication bypass vulnerabilities.
- Eliminated unauthenticated
- Zero API Key Leakage Across Services, WebSocket & Logging:
- Replaced unproxied direct image URLs in
jellyha.get_playlistsandjellyha.get_collectionswith signed Home Assistant proxy paths (/api/jellyha/image/...), preventing leakage of cleartext Jellyfin API keys inServiceResponsepayloads returned to users, automations, and scripts. - Hardened library and music audio items in
coordinator.py: replaced directstream_url(which previously exposed&api_key=...&ApiKey=...query parameters to browser WebSocket clients and service queries) with cryptographically signed proxy paths (/api/jellyha/stream/...). - Hardened
jellyha.play_musicandjellyha.play_playlist: media URLs and cover art thumbnails are routed via signed Home Assistant proxy paths, preventing exposure of API keys in media player entity attributes (media_content_id,entity_picture). - Redacted query-string API keys in WebSocket connection logging (
ws_client.py). - Expanded diagnostics redaction (
diagnostics.py) to redact all key variants (ApiKey,token,Token,secret,auth_key).
- Replaced unproxied direct image URLs in
Fixed
- Non-Administrator User Login via Username/Password (Fixes #64):
- Resolved an issue where attempting to set up the integration using a Username and Password failed with
invalid_auth("Invalid authentication") for non-administrator accounts. - Jellyfin restricts
GET /Usersstrictly to server administrators, returning HTTP 403 Forbidden. The config flow now extracts the authenticated user ID and name directly from the login response (auth_data["User"]) and automatically advances to library selection when listing all users is prohibited. - Added dual HTTP authentication headers (
AuthorizationandX-Emby-Authorization, along withX-Emby-TokenandX-MediaBrowser-Token) to ensure reverse proxies and custom server configurations properly forward credentials. - Prevented infinite periodic
GET /Usersretry loops inJellyHASessionCoordinatorby falling back to the configured user profile when server-wide user enumeration is disallowed.
- Resolved an issue where attempting to set up the integration using a Username and Password failed with
- Chromecast Ultra Video & Audio Stalling on Transcoded Media (Fixes #63):
- Resolved an issue where casting transcoded media (e.g. MPEG-2 video, multi-channel surround) to a Chromecast Ultra displayed the title and thumbnail on the projection/TV screen but never started audio or video playback.
- Tuned modern transcoding audio channels: Google Cast hardware decoders natively support AAC strictly in stereo (2 channels) and fail when decoding 6-channel AAC. Set
TranscodingMaxAudioChannels=2for AAC transcoding to prevent receiver audio decoder stall. - Updated Chromecast HLS streaming content type to the canonical RFC MIME type
application/vnd.apple.mpegurl(replacing obsoleteapplication/x-mpegURL). - Synchronized streaming and WebSocket client
DeviceIdwith the integration's authenticated sessionDeviceId(jellyha), and includedUserIdand token query parameters in cast streaming URLs, resolving periodic authentication challenges ("CustomAuthentication was challenged / Invalid token").