Commit Graph

2135 Commits

Author SHA1 Message Date
Uruk
b38064e2da feat(music): register music PlaybackController 2026-05-22 02:19:13 +02:00
Uruk
5b823a8efd feat(player): register native-video PlaybackController 2026-05-22 02:17:30 +02:00
Uruk
750caba038 feat(casting): register cast PlaybackController for remote control 2026-05-22 02:11:20 +02:00
Uruk
d3ee6c8239 feat(playback): handle remote-control messages over WebSocket 2026-05-22 02:07:10 +02:00
Uruk
7e2ef0f2da feat(playback): add useRemoteControl dispatch hook 2026-05-22 02:06:12 +02:00
Uruk
ca2e657eac feat(playback): add pure remote-command mapper 2026-05-22 02:05:10 +02:00
Uruk
288b390e5b feat(playback): add PlaybackController contract and registry 2026-05-22 02:03:36 +02:00
Uruk
c04924fe9e docs(casting): add session reporting & remote control plan
10-task plan for sub-project D: PlaybackController registry, pure
remote-command mapper, useRemoteControl dispatch, per-player
registration, PlayMethod fix, conditional episode buttons, loadEpisode
race fix.
2026-05-22 02:02:17 +02:00
Uruk
525a6b39fa docs(casting): add session reporting & remote control design spec
Design for sub-project D: correct PlayMethod reporting, conditional
episode buttons, loadEpisode race fix, and app-wide Jellyfin remote
control (Playstate/GeneralCommand) routed via a PlaybackController.
2026-05-22 01:58:30 +02:00
Uruk
1ea7f0f491 refactor(casting): extract useCastPlayerProgress hook 2026-05-22 01:32:21 +02:00
Uruk
79c2829444 refactor(casting): extract useCastDismissGesture hook 2026-05-22 01:22:21 +02:00
Uruk
87e0b0006b refactor(casting): extract useCastEpisodes hook 2026-05-22 01:18:08 +02:00
Uruk
3c71c08591 refactor(casting): extract useCastPlayerItem hook 2026-05-22 01:15:29 +02:00
Uruk
9f4f0fa7d1 refactor(casting): extract CastPlayerTransportControls 2026-05-22 01:10:30 +02:00
Uruk
0d922b75d6 refactor(casting): extract CastPlayerProgressBar 2026-05-22 01:08:04 +02:00
Uruk
0ee1d43d16 refactor(casting): extract CastPlayerEpisodeControls 2026-05-22 01:02:37 +02:00
Uruk
ec49d03cf1 refactor(casting): extract CastPlayerPoster 2026-05-22 00:59:57 +02:00
Uruk
02df2477d8 refactor(casting): extract CastPlayerHeader and CastPlayerTitle 2026-05-22 00:57:55 +02:00
Uruk
8c9506c7b5 docs(casting): add casting-player split implementation plan
10-task plan for sub-project C: extract 6 presentational components +
4 hooks from casting-player.tsx, leaving a thin orchestrator. Purely
mechanical, behaviour-neutral.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 00:56:21 +02:00
Uruk
b225286f57 docs(casting): add casting-player split design spec 2026-05-22 00:53:17 +02:00
Uruk
23b4f20d18 fix(casting): track menus from full item, keep quality on version switch, stable resume position
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 00:05:14 +02:00
Uruk
88d96603e4 feat(casting): reliable track switching with CastSelection truth 2026-05-21 23:58:22 +02:00
Uruk
6e513b8f9e feat(player): expand shared BITRATES ladder 2026-05-21 23:50:21 +02:00
Uruk
4f50ec6665 feat(casting): add useCastSelection hook 2026-05-21 23:49:23 +02:00
Uruk
0e25a5936c feat(casting): resolve and embed full CastSelection on load 2026-05-21 23:48:29 +02:00
Uruk
e9fee79130 feat(casting): embed CastSelection in cast customData 2026-05-21 23:47:23 +02:00
Uruk
3d65c3bb7a feat(casting): add CastSelection model and resolution helpers 2026-05-21 23:46:19 +02:00
Uruk
e5d61bf3ea docs(casting): add track switching implementation plan
6-task plan for sub-project B: CastSelection model, customData source of
truth, useCastSelection hook, expanded BITRATES, casting-player and
settings-menu rework.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 23:44:05 +02:00
Uruk
5eac91190e docs(casting): quality filter by media bitrate + device cap
Per review: filter quality tiers by both ceilings; correct the shared
BITRATES file reference to BitrateSelector.tsx.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 23:43:44 +02:00
Uruk
95d63e3c8a docs(casting): quality menu reuses expanded shared BITRATES
Per review: the cast quality selector reuses the app-wide BITRATES
constant (expanded to the Jellyfin Android TV ladder) instead of a
cast-specific list, filtered by device capability.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 23:30:18 +02:00
Uruk
6d0ca44308 docs(casting): add track switching & multi-version design spec
Design for sub-project B: a single CastSelection source of truth carried
in cast customData (approach A3), fixing audio/subtitle/quality desync,
plus a real multi-version selector.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 23:23:19 +02:00
Uruk
73214f5d45 fix(casting): apply conservative bitrate cap on downgrade retry
The status-2100 downgrade retry overrode only the device profile's
MaxStreamingBitrate. Jellyfin uses the explicit getStreamUrl maxBitrate
request param as the effective ceiling, so a quality-menu bitrate would
survive the retry. Clamp options.maxBitrate to the fallback cap too.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 02:36:25 +02:00
Uruk
5cfd110ad5 docs(casting): add Chromecast cast test matrix 2026-05-21 02:33:12 +02:00
Uruk
6e63afc61a feat(casting): replace H265 toggle with Chromecast profile selector 2026-05-21 02:32:18 +02:00
Uruk
bcf6b705e1 refactor(casting): route all cast loads through loadCastMedia
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 02:27:20 +02:00
Uruk
fb8c649f6f feat(casting): add unified loadCastMedia with downgrade-on-failure 2026-05-21 02:20:06 +02:00
Uruk
6ecadecb87 feat(casting): add chromecastProfile and chromecastMaxBitrate settings 2026-05-21 02:17:59 +02:00
Uruk
e3f105691b feat(casting): add Chromecast device profile builder 2026-05-21 02:16:29 +02:00
Uruk
bcfa8c6d63 feat(casting): add Chromecast capability detection 2026-05-21 02:13:31 +02:00
Uruk
17450e3811 docs(casting): add device profiles implementation plan
7-task TDD plan for sub-project A: capability detection, profile builder,
unified loadCastMedia, call-site rewiring, settings UI, test matrix.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 02:09:44 +02:00
Uruk
9759d84aa2 docs(casting): drop settings migration from profiles design
Per review: break enableH265ForChromecast outright instead of carrying
migration code. Users reconfigure; chromecastProfile defaults to auto.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 01:46:57 +02:00
Uruk
28d8b28c73 docs(casting): add device profiles & capability detection design spec
Design for sub-project A of the Chromecast refactor: per-device capability
detection, profile builder replacing the two static profiles, unified cast
load, and load-path bug fixes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 01:42:04 +02:00
Uruk
a4e47e5cb7 feat(casting): improve track selection and session handling
implements automatic initialization of audio and subtitle tracks based on server-provided defaults. ensures subtitle selection persists correctly during stream reloads by resolving track indices more reliably.

replaces crypto-based uuid generation with a math-based fallback to ensure compatibility with environments lacking global crypto support. adds missing media source metadata to cast info to improve consistency between the client and receiver.
2026-05-21 00:48:37 +02:00
Uruk
fcd7e46599 fix: resolve 13 review issues across casting components
- casting-player: remove redundant self-navigation useEffect
- casting-player: derive Type from metadata instead of hardcoding 'Movie'
- casting-player: pass null to useTrickplay instead of empty BaseItemDto
- casting-player: use != null for skip time labels (allow 0 to render)
- Chromecast: case-insensitive m3u8 detection via regex
- Chromecast: fix UUID hyphen indices to 4,6,8,10 for proper v4 format
- CastingMiniPlayer: use SeriesPrimaryImageTag for series poster URL
- ChromecastConnectionMenu: send rounded volume to castSession.setVolume
- ChromecastConnectionMenu: use isMutedRef in onValueChange to avoid stale closure
- ChromecastDeviceSheet: skip volume sync during active sliding
- ChromecastDeviceSheet: move unmute logic from onValueChange to onSlidingStart
- useCasting: detect playback start via isPlaying/playerState, not just progress>0
- useCasting: derive isChromecastAvailable from castState instead of hardcoding true
- useTrickplay: accept BaseItemDto|null with null guards on Id access
2026-05-21 00:47:31 +02:00
Uruk
a841619d78 Fix: Generates UUID v4 for play session ID
Fixes the play session ID generation to use UUID v4 format.

This ensures a more robust and standard identifier for tracking play sessions.
2026-05-21 00:47:31 +02:00
Uruk
6c72a2803f fix(chromecast): replace Math.random with crypto.getRandomValues for session ID 2026-05-21 00:47:31 +02:00
Uruk
6bf00abb9b fix: Refactors casting player and components
Refactors the casting player screen and related components for improved code clarity, performance, and maintainability.

- Removes unused code and simplifies logic, especially around audio track selection and recommended stereo track handling.
- Improves the formatting of trickplay time displays for consistency.
- Streamlines UI elements and removes unnecessary conditional checks.
- Updates the Chromecast component to use hooks for side effects, ensuring the Chromecast session remains active.
- Improves the display of the language in the audio track display.
2026-05-21 00:47:31 +02:00
Uruk
ac405af3b2 Fix: Improves Chromecast casting experience
Fixes several issues and enhances the Chromecast casting experience:

- Prevents errors when loading media by slimming down the customData payload to avoid exceeding message size limits.
- Improves logic for selecting custom data from media status.
- Fixes an issue with subtitle track selection.
- Recommends stereo audio tracks for better Chromecast compatibility.
- Improves volume control and mute synchronization between the app and the Chromecast device.
- Adds error handling for `loadMedia` in `PlayButton`.
- Fixes image caching issue for season posters in mini player.
- Implements cleanup for scroll retry timeout in episode list.
- Ensures segment skipping functions are asynchronous.
- Resets `hasReportedStartRef` after stopping casting.
- Prevents seeking past the end of Outro segments.
- Reports playback progress more accurately by also taking player state changes into account.
2026-05-21 00:47:31 +02:00
Uruk
9ec81cfa1d Fix: Improves Chromecast casting experience
Fixes several issues and improves the overall Chromecast casting experience:

- Implements an AbortController for fetching item data to prevent race conditions.
- Syncs live progress in the mini player more accurately using elapsed real time.
- Prevents event propagation in the mini player's play/pause button.
- Ensures the disconnect callback in the connection menu is always called.
- Retries scrolling in the episode list on failure.
- Handles unmute failures gracefully in volume controls.
- Clamps seek positions to prevent exceeding duration.
- Fixes reporting playback start multiple times
- Improves segment calculation in `useChromecastSegments`
- Prevents race condition with `isPlaying` state in `Controls` component

Also includes minor UI and timing adjustments for a smoother user experience.
2026-05-21 00:47:31 +02:00
Uruk
28bf1489c1 Fix: Improve casting and segment skipping
Fixes several issues and improves the casting player experience.

- Adds the ability to disable segment skipping options based on plugin settings.
- Improves Chromecast integration by:
  - Adding PlaySessionId for better tracking.
  - Improves audio track selection
  - Uses mediaInfo builder for loading media.
  - Adds support for loading next/previous episodes
  - Translation support
- Updates progress reporting to Jellyfin to be more accurate and reliable.
- Fixes an error message in the direct player.
2026-05-21 00:47:31 +02:00