Track remote volume to prevent unexpcted changes change
All checks were successful
Build Plugin / build (push) Successful in 2m54s
Release Plugin / build-and-release (push) Successful in 2m43s

This commit is contained in:
Duncan Tourolle 2026-01-25 19:20:35 +01:00
parent f5f202794f
commit b85fbc2d90

View File

@ -59,6 +59,9 @@ public class LmsSessionController : ISessionController, IDisposable
_libraryManager = libraryManager;
_stateMachine = new PlaybackStateMachine(logger);
_statusPoller = new LmsStatusPoller(lmsClient, logger);
// Start status polling immediately to keep volume in sync
StartProgressTimer();
}
private static PluginConfiguration Config => Plugin.Instance?.Configuration ?? new PluginConfiguration();
@ -295,7 +298,7 @@ public class LmsSessionController : ISessionController, IDisposable
// Stop any existing timer
_progressTimer?.Dispose();
// Report progress every 2 seconds
// Poll status every 2 seconds (for progress reporting when playing and volume sync always)
_progressTimer = new Timer(
async _ => await ReportPlaybackProgressAsync().ConfigureAwait(false),
null,
@ -305,32 +308,37 @@ public class LmsSessionController : ISessionController, IDisposable
private void StopProgressTimer()
{
_progressTimer?.Dispose();
_progressTimer = null;
// Don't actually stop the timer - keep polling for volume updates
// This ensures Jellyfin stays in sync with the device volume
// even when not playing media
}
private async Task ReportPlaybackProgressAsync()
{
// Don't report during Loading, Seeking, or Error states
var currentState = _stateMachine.CurrentState;
if (currentState == PlaybackState.Loading
|| currentState == PlaybackState.Seeking
|| currentState == PlaybackState.Error
|| currentState == PlaybackState.Stopped
|| currentState == PlaybackState.Idle
|| !CurrentItemId.HasValue)
{
return;
}
try
{
// Always poll status to keep volume in sync, even when not playing
var status = await _lmsClient.GetPlayerStatusAsync(_player.MacAddress).ConfigureAwait(false);
if (status == null)
{
return;
}
// Update cached volume so Jellyfin stays in sync with device
_player.Volume = status.Volume;
// Don't report playback progress during Loading, Seeking, Error, Stopped, or Idle states
var currentState = _stateMachine.CurrentState;
if (currentState == PlaybackState.Loading
|| currentState == PlaybackState.Seeking
|| currentState == PlaybackState.Error
|| currentState == PlaybackState.Stopped
|| currentState == PlaybackState.Idle
|| !CurrentItemId.HasValue)
{
return;
}
// LMS reports time relative to the current stream, but after seeking
// we're playing a transcoded stream that starts at the seek position.
// Add the seek offset to get the actual track position.
@ -812,7 +820,9 @@ public class LmsSessionController : ISessionController, IDisposable
_cancellationTokenSource.Cancel();
_cancellationTokenSource.Dispose();
StopProgressTimer();
// Actually stop the timer when disposing
_progressTimer?.Dispose();
_progressTimer = null;
// Reset state machine
_stateMachine.Reset();