First POC with working playback
This commit is contained in:
@@ -0,0 +1,254 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Jellyfin.Plugin.JellyLMS.Models;
|
||||
|
||||
/// <summary>
|
||||
/// JSON-RPC request for LMS API.
|
||||
/// </summary>
|
||||
public class LmsJsonRpcRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the request ID.
|
||||
/// </summary>
|
||||
[JsonPropertyName("id")]
|
||||
public int Id { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the method name (always "slim.request").
|
||||
/// </summary>
|
||||
[JsonPropertyName("method")]
|
||||
public string Method { get; set; } = "slim.request";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the parameters [playerMac, [command, args...]].
|
||||
/// </summary>
|
||||
[JsonPropertyName("params")]
|
||||
public object[] Params { get; set; } = [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// JSON-RPC response from LMS API.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The result type.</typeparam>
|
||||
public class LmsJsonRpcResponse<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the request ID.
|
||||
/// </summary>
|
||||
[JsonPropertyName("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the result data.
|
||||
/// </summary>
|
||||
[JsonPropertyName("result")]
|
||||
public T? Result { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets any error message.
|
||||
/// </summary>
|
||||
[JsonPropertyName("error")]
|
||||
public string? Error { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Player count response.
|
||||
/// </summary>
|
||||
public class PlayerCountResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the count value.
|
||||
/// </summary>
|
||||
[JsonPropertyName("_count")]
|
||||
public int Count { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Players list response.
|
||||
/// </summary>
|
||||
public class PlayersListResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the player count.
|
||||
/// </summary>
|
||||
[JsonPropertyName("count")]
|
||||
public int Count { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the list of players.
|
||||
/// </summary>
|
||||
[JsonPropertyName("players_loop")]
|
||||
public List<LmsPlayerInfo> Players { get; set; } = [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Player info from LMS API.
|
||||
/// </summary>
|
||||
public class LmsPlayerInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the player name.
|
||||
/// </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the player ID (MAC address).
|
||||
/// </summary>
|
||||
[JsonPropertyName("playerid")]
|
||||
public string PlayerId { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the player IP address.
|
||||
/// </summary>
|
||||
[JsonPropertyName("ip")]
|
||||
public string Ip { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the player is connected.
|
||||
/// </summary>
|
||||
[JsonPropertyName("connected")]
|
||||
public int Connected { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the power state.
|
||||
/// </summary>
|
||||
[JsonPropertyName("power")]
|
||||
public int Power { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the player model.
|
||||
/// </summary>
|
||||
[JsonPropertyName("model")]
|
||||
public string Model { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the player model name.
|
||||
/// </summary>
|
||||
[JsonPropertyName("modelname")]
|
||||
public string ModelName { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Player status response.
|
||||
/// </summary>
|
||||
public class PlayerStatusResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the player name.
|
||||
/// </summary>
|
||||
[JsonPropertyName("player_name")]
|
||||
public string PlayerName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the player connected state.
|
||||
/// </summary>
|
||||
[JsonPropertyName("player_connected")]
|
||||
public int PlayerConnected { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the power state.
|
||||
/// </summary>
|
||||
[JsonPropertyName("power")]
|
||||
public int Power { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the playback mode (play, pause, stop).
|
||||
/// </summary>
|
||||
[JsonPropertyName("mode")]
|
||||
public string Mode { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current time position in seconds.
|
||||
/// </summary>
|
||||
[JsonPropertyName("time")]
|
||||
public double Time { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the mixer volume (0-100).
|
||||
/// </summary>
|
||||
[JsonPropertyName("mixer volume")]
|
||||
public int Volume { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the total duration in seconds.
|
||||
/// </summary>
|
||||
[JsonPropertyName("duration")]
|
||||
public double Duration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the sync master MAC address.
|
||||
/// </summary>
|
||||
[JsonPropertyName("sync_master")]
|
||||
public string? SyncMaster { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the list of synced player MACs.
|
||||
/// </summary>
|
||||
[JsonPropertyName("sync_slaves")]
|
||||
public string? SyncSlaves { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current track title.
|
||||
/// </summary>
|
||||
[JsonPropertyName("current_title")]
|
||||
public string? CurrentTitle { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// LMS server status.
|
||||
/// </summary>
|
||||
public class LmsServerStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the server version.
|
||||
/// </summary>
|
||||
public string Version { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the player count.
|
||||
/// </summary>
|
||||
public int PlayerCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the server is reachable.
|
||||
/// </summary>
|
||||
public bool IsConnected { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the last error message.
|
||||
/// </summary>
|
||||
public string? LastError { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sync group information.
|
||||
/// </summary>
|
||||
public class SyncGroup
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the master player MAC address.
|
||||
/// </summary>
|
||||
public string MasterMac { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the master player name.
|
||||
/// </summary>
|
||||
public string MasterName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the slave player MAC addresses.
|
||||
/// </summary>
|
||||
public List<string> SlaveMacs { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the slave player names.
|
||||
/// </summary>
|
||||
public List<string> SlaveNames { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the total number of players in this sync group.
|
||||
/// </summary>
|
||||
public int PlayerCount => 1 + SlaveMacs.Count;
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Jellyfin.Plugin.JellyLMS.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the current playback state.
|
||||
/// </summary>
|
||||
public enum PlaybackState
|
||||
{
|
||||
/// <summary>
|
||||
/// Playback is stopped.
|
||||
/// </summary>
|
||||
Stopped,
|
||||
|
||||
/// <summary>
|
||||
/// Playback is active.
|
||||
/// </summary>
|
||||
Playing,
|
||||
|
||||
/// <summary>
|
||||
/// Playback is paused.
|
||||
/// </summary>
|
||||
Paused
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents an active playback session bridging Jellyfin to LMS.
|
||||
/// </summary>
|
||||
public class LmsPlaybackSession
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the unique session identifier.
|
||||
/// </summary>
|
||||
public string SessionId { get; set; } = Guid.NewGuid().ToString();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Jellyfin session ID.
|
||||
/// </summary>
|
||||
public string? JellyfinSessionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Jellyfin item ID being played.
|
||||
/// </summary>
|
||||
public Guid ItemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item name for display.
|
||||
/// </summary>
|
||||
public string ItemName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the artist name (for audio).
|
||||
/// </summary>
|
||||
public string? Artist { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the album name (for audio).
|
||||
/// </summary>
|
||||
public string? Album { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the MAC addresses of LMS players in this session.
|
||||
/// </summary>
|
||||
public List<string> PlayerMacs { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current playback state.
|
||||
/// </summary>
|
||||
public PlaybackState State { get; set; } = PlaybackState.Stopped;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current playback position in ticks.
|
||||
/// </summary>
|
||||
public long PositionTicks { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the total runtime in ticks.
|
||||
/// </summary>
|
||||
public long RuntimeTicks { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets when this session started.
|
||||
/// </summary>
|
||||
public DateTime StartedAt { get; set; } = DateTime.UtcNow;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the audio stream URL being played on LMS.
|
||||
/// </summary>
|
||||
public string? StreamUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Jellyfin user ID who initiated playback.
|
||||
/// </summary>
|
||||
public Guid? UserId { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Jellyfin.Plugin.JellyLMS.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Represents an LMS player/zone.
|
||||
/// </summary>
|
||||
public class LmsPlayer
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the player's display name.
|
||||
/// </summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the player's MAC address (unique identifier).
|
||||
/// </summary>
|
||||
public string MacAddress { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the player's IP address.
|
||||
/// </summary>
|
||||
public string IpAddress { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the player is connected to LMS.
|
||||
/// </summary>
|
||||
public bool IsConnected { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the player is powered on.
|
||||
/// </summary>
|
||||
public bool IsPoweredOn { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the player's current volume (0-100).
|
||||
/// </summary>
|
||||
public int Volume { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the player model name.
|
||||
/// </summary>
|
||||
public string Model { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the MAC address of the sync master, if this player is synced.
|
||||
/// </summary>
|
||||
public string? SyncMaster { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the list of synced player MAC addresses (if this is a sync master).
|
||||
/// </summary>
|
||||
public List<string> SyncSlaves { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this player is part of a sync group.
|
||||
/// </summary>
|
||||
public bool IsSynced => !string.IsNullOrEmpty(SyncMaster) || SyncSlaves.Count > 0;
|
||||
}
|
||||
Reference in New Issue
Block a user