Files
windows/Media/Contracts.cs
T

59 lines
2.7 KiB
C#
Raw Normal View History

namespace MusicBridge.Agent.Media;
internal sealed record MediaCommand(string Type, double? Value = null, string? Id = null);
internal sealed record CommandResult(bool Success, string Code, string Message, string? Id = null);
internal sealed record PlayerCapabilities(bool Play = false, bool Pause = false,
bool Toggle = false, bool Next = false, bool Previous = false, bool Seek = false);
internal sealed record MediaState
{
public int ProtocolVersion { get; init; } = 1;
public DateTimeOffset Timestamp { get; init; } = DateTimeOffset.UtcNow;
public bool HasSession { get; init; }
public string Title { get; init; } = "";
public string Artist { get; init; } = "";
public string Source { get; init; } = "";
public string PlaybackStatus { get; init; } = "Closed";
public double PositionSeconds { get; init; }
public double StartSeconds { get; init; }
public double EndSeconds { get; init; }
public double MinSeekSeconds { get; init; }
public double MaxSeekSeconds { get; init; }
public double PlaybackRate { get; init; } = 1;
public PlayerCapabilities Capabilities { get; init; } = new();
public float? Volume { get; init; }
public bool? Muted { get; init; }
public string? MediaError { get; init; }
public string? VolumeError { get; init; }
public string? ArtworkId { get; init; }
public string? ArtworkError { get; init; }
}
internal interface IMediaService
{
event Action? Changed;
Artwork? GetArtwork(string id);
Task<MediaState> ReadAsync(CancellationToken cancellationToken);
Task<CommandResult> ExecuteAsync(MediaCommand command, CancellationToken cancellationToken);
}
internal static class CommandValidation
{
public static CommandResult? Validate(MediaCommand command)
{
if (command.Id?.Length > 64) return Error("invalid_command", "Id длиннее 64 символов.");
var valid = command.Type switch
{
"play" or "pause" or "toggle" or "next" or "previous" or "toggleMute" => command.Value is null,
"seek" => command.Value is double s && double.IsFinite(s) && s >= 0 && s <= TimeSpan.MaxValue.TotalSeconds / 2,
"seekRelative" => command.Value is double d && double.IsFinite(d) && Math.Abs(d) <= 3600,
"volume" => command.Value is double v && double.IsFinite(v) && v >= 0 && v <= 1,
"volumeRelative" => command.Value is double d && double.IsFinite(d) && Math.Abs(d) <= 1,
_ => false
};
return valid ? null : Error("invalid_command", "Неизвестная команда или недопустимое значение.");
}
public static CommandResult Error(string code, string message) => new(false, code, message);
}