fix(jellyfin): fix discovery loop, device identity, tray state, and Disc

- Derive device identity from OS hostname; remove legacy configurable client/device fields
- Prevent discovery playback from reloading active item, misreporting pause state, and duplicate overlay restores
- Restart stale tray discovery sessions without re-login when server drops SubMiner cast target
- Sync tray discovery checkbox state on Linux after CLI/startup/remote-session changes
- Stop Discord presence falling back to stream URLs; prime title before tokenized stream loads
- Fix picker library discovery when log level is above info
- Fix config.example.jsonc trailing commas and array formatting
This commit is contained in:
2026-05-22 01:36:11 -07:00
parent 85d838ac96
commit 2f2dfa3e91
72 changed files with 2063 additions and 589 deletions
+15 -12
View File
@@ -75,6 +75,7 @@ export function createPlayJellyfinItemInMpvHandler(deps: {
}) => void;
showMpvOsd: (text: string) => void;
recordJellyfinPlaybackMetadata?: (metadata: JellyfinPlaybackStatsMetadata) => void;
updateCurrentMediaTitle?: (title: string) => void;
}) {
return async (params: {
session: JellyfinAuthSession;
@@ -106,24 +107,26 @@ export function createPlayJellyfinItemInMpvHandler(deps: {
deps.applyJellyfinMpvDefaults(mpvClient);
deps.sendMpvCommand(['set_property', 'sub-auto', 'no']);
const playbackUrl = applyStartTimeTicksToPlaybackUrl(plan.url, params.startTimeTicksOverride);
deps.recordJellyfinPlaybackMetadata?.({
mediaPath: playbackUrl,
displayTitle: plan.title,
itemTitle: plan.itemTitle,
seriesTitle: plan.seriesTitle,
seasonNumber: plan.seasonNumber,
episodeNumber: plan.episodeNumber,
itemId: params.itemId,
});
deps.updateCurrentMediaTitle?.(plan.title);
try {
deps.recordJellyfinPlaybackMetadata?.({
mediaPath: playbackUrl,
displayTitle: plan.title,
itemTitle: plan.itemTitle,
seriesTitle: plan.seriesTitle,
seasonNumber: plan.seasonNumber,
episodeNumber: plan.episodeNumber,
itemId: params.itemId,
});
} catch {
// Best-effort stats metadata must not block playback startup.
}
deps.sendMpvCommand(['loadfile', playbackUrl, 'replace']);
if (params.setQuitOnDisconnectArm !== false) {
deps.armQuitOnDisconnect();
}
deps.sendMpvCommand(['set_property', 'force-media-title', plan.title]);
deps.sendMpvCommand(['set_property', 'sid', 'no']);
deps.schedule(() => {
deps.sendMpvCommand(['set_property', 'sid', 'no']);
}, 500);
const startTimeTicks =
typeof params.startTimeTicksOverride === 'number'