track progress
This commit is contained in:
parent
2f5a182afd
commit
83741d7980
@ -1,9 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
using Jellyfin.Plugin.JellyLMS.Models;
|
using Jellyfin.Plugin.JellyLMS.Models;
|
||||||
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Session;
|
using MediaBrowser.Controller.Session;
|
||||||
using MediaBrowser.Model.Session;
|
using MediaBrowser.Model.Session;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
@ -219,6 +221,72 @@ public class LmsDeviceDiscoveryService : IHostedService, IDisposable
|
|||||||
player.MacAddress,
|
player.MacAddress,
|
||||||
session.Id);
|
session.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Report playback progress if the controller has an active item
|
||||||
|
if (controller is LmsSessionController lmsController)
|
||||||
|
{
|
||||||
|
await ReportPlaybackProgressAsync(sessionManager, session, lmsController).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ReportPlaybackProgressAsync(
|
||||||
|
ISessionManager sessionManager,
|
||||||
|
SessionInfo session,
|
||||||
|
LmsSessionController controller)
|
||||||
|
{
|
||||||
|
if (!controller.IsPlaying || !controller.CurrentItemId.HasValue)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Get current playback status from LMS
|
||||||
|
var status = await _lmsClient.GetPlayerStatusAsync(controller.PlayerMac).ConfigureAwait(false);
|
||||||
|
if (status == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the item from Jellyfin library
|
||||||
|
var libraryManager = _serviceProvider.GetService<ILibraryManager>();
|
||||||
|
if (libraryManager == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var item = libraryManager.GetItemById(controller.CurrentItemId.Value);
|
||||||
|
if (item == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate position in ticks
|
||||||
|
var positionTicks = (long)(status.Time * TimeSpan.TicksPerSecond);
|
||||||
|
|
||||||
|
// Determine if paused
|
||||||
|
var isPaused = status.Mode == "pause";
|
||||||
|
|
||||||
|
// Create playback progress info
|
||||||
|
var progressInfo = new PlaybackProgressInfo
|
||||||
|
{
|
||||||
|
ItemId = controller.CurrentItemId.Value,
|
||||||
|
SessionId = session.Id,
|
||||||
|
IsPaused = isPaused,
|
||||||
|
PositionTicks = positionTicks,
|
||||||
|
PlayMethod = PlayMethod.DirectStream,
|
||||||
|
CanSeek = true,
|
||||||
|
IsMuted = status.Volume == 0,
|
||||||
|
VolumeLevel = status.Volume
|
||||||
|
};
|
||||||
|
|
||||||
|
// Report progress to session manager
|
||||||
|
await sessionManager.OnPlaybackProgress(progressInfo).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogDebug(ex, "Error reporting playback progress for player {Name}", controller.PlayerMac);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@ -39,8 +39,23 @@ public class LmsSessionController : ISessionController
|
|||||||
_session = session;
|
_session = session;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the currently playing item ID.
|
||||||
|
/// </summary>
|
||||||
|
public Guid? CurrentItemId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether playback is currently active.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsPlaying { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether playback is paused.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsPaused { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool IsSessionActive => _player.IsConnected && _player.IsPoweredOn;
|
public bool IsSessionActive => _player.IsConnected;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool SupportsMediaControl => true;
|
public bool SupportsMediaControl => true;
|
||||||
@ -57,10 +72,11 @@ public class LmsSessionController : ISessionController
|
|||||||
T data,
|
T data,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
_logger.LogDebug(
|
_logger.LogInformation(
|
||||||
"LMS Session Controller received message {MessageType} for player {PlayerName}",
|
"LMS Session Controller received message {MessageType} for player {PlayerName} ({Mac})",
|
||||||
name,
|
name,
|
||||||
_player.Name);
|
_player.Name,
|
||||||
|
_player.MacAddress);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -118,6 +134,11 @@ public class LmsSessionController : ISessionController
|
|||||||
_logger.LogInformation("Playing stream URL: {Url}", streamUrl);
|
_logger.LogInformation("Playing stream URL: {Url}", streamUrl);
|
||||||
await _lmsClient.PlayUrlAsync(_player.MacAddress, streamUrl).ConfigureAwait(false);
|
await _lmsClient.PlayUrlAsync(_player.MacAddress, streamUrl).ConfigureAwait(false);
|
||||||
|
|
||||||
|
// Track current playback state
|
||||||
|
CurrentItemId = itemId;
|
||||||
|
IsPlaying = true;
|
||||||
|
IsPaused = false;
|
||||||
|
|
||||||
// Seek to start position if specified
|
// Seek to start position if specified
|
||||||
if (playRequest.StartPositionTicks.HasValue && playRequest.StartPositionTicks.Value > 0)
|
if (playRequest.StartPositionTicks.HasValue && playRequest.StartPositionTicks.Value > 0)
|
||||||
{
|
{
|
||||||
@ -135,29 +156,60 @@ public class LmsSessionController : ISessionController
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogDebug(
|
_logger.LogInformation(
|
||||||
"Playstate command {Command} for player {PlayerName}",
|
"Playstate command {Command} for player {PlayerName} ({Mac})",
|
||||||
playstateRequest.Command,
|
playstateRequest.Command,
|
||||||
_player.Name);
|
_player.Name,
|
||||||
|
_player.MacAddress);
|
||||||
|
|
||||||
switch (playstateRequest.Command)
|
switch (playstateRequest.Command)
|
||||||
{
|
{
|
||||||
case PlaystateCommand.Stop:
|
case PlaystateCommand.Stop:
|
||||||
await _lmsClient.StopAsync(_player.MacAddress).ConfigureAwait(false);
|
var stopResult = await _lmsClient.StopAsync(_player.MacAddress).ConfigureAwait(false);
|
||||||
|
_logger.LogInformation("Stop command result: {Result}", stopResult);
|
||||||
|
IsPlaying = false;
|
||||||
|
IsPaused = false;
|
||||||
|
CurrentItemId = null;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PlaystateCommand.Pause:
|
case PlaystateCommand.Pause:
|
||||||
await _lmsClient.PauseAsync(_player.MacAddress).ConfigureAwait(false);
|
var pauseResult = await _lmsClient.PauseAsync(_player.MacAddress).ConfigureAwait(false);
|
||||||
|
_logger.LogInformation("Pause command result: {Result}", pauseResult);
|
||||||
|
IsPaused = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PlaystateCommand.Unpause:
|
case PlaystateCommand.Unpause:
|
||||||
await _lmsClient.PlayAsync(_player.MacAddress).ConfigureAwait(false);
|
var playResult = await _lmsClient.PlayAsync(_player.MacAddress).ConfigureAwait(false);
|
||||||
|
_logger.LogInformation("Unpause/Play command result: {Result}", playResult);
|
||||||
|
IsPaused = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PlaystateCommand.PlayPause:
|
||||||
|
// Toggle play/pause - check current state first
|
||||||
|
var currentState = await _lmsClient.GetPlayerStatusAsync(_player.MacAddress).ConfigureAwait(false);
|
||||||
|
if (currentState?.Mode == "play")
|
||||||
|
{
|
||||||
|
var togglePauseResult = await _lmsClient.PauseAsync(_player.MacAddress).ConfigureAwait(false);
|
||||||
|
_logger.LogInformation("PlayPause toggle (pause) result: {Result}", togglePauseResult);
|
||||||
|
IsPaused = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var togglePlayResult = await _lmsClient.PlayAsync(_player.MacAddress).ConfigureAwait(false);
|
||||||
|
_logger.LogInformation("PlayPause toggle (play) result: {Result}", togglePlayResult);
|
||||||
|
IsPaused = false;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PlaystateCommand.Seek:
|
case PlaystateCommand.Seek:
|
||||||
if (playstateRequest.SeekPositionTicks.HasValue)
|
if (playstateRequest.SeekPositionTicks.HasValue)
|
||||||
{
|
{
|
||||||
var positionSeconds = playstateRequest.SeekPositionTicks.Value / TimeSpan.TicksPerSecond;
|
var positionSeconds = playstateRequest.SeekPositionTicks.Value / TimeSpan.TicksPerSecond;
|
||||||
|
_logger.LogInformation(
|
||||||
|
"Seeking player {PlayerName} to {Seconds} seconds",
|
||||||
|
_player.Name,
|
||||||
|
positionSeconds);
|
||||||
await _lmsClient.SeekAsync(_player.MacAddress, positionSeconds).ConfigureAwait(false);
|
await _lmsClient.SeekAsync(_player.MacAddress, positionSeconds).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user