This commit is contained in:
fuenmao
2026-10-08 10:16:43 +08:00
parent af596104e2
commit 4a634ef4c2
8 changed files with 261 additions and 25 deletions
@@ -12,6 +12,8 @@ public sealed class TcmMusicTransitionService : IHostedService
private readonly TcmMusicOptions _options;
private readonly ILogger<TcmMusicTransitionService> _logger;
private readonly SemaphoreSlim _operationLock = new(1, 1);
private readonly object _statusLock = new();
private TcmMusicTransitionOutput _status = new();
private CancellationTokenSource? _activeCancellation;
private Task? _activeTask;
@@ -28,6 +30,18 @@ public sealed class TcmMusicTransitionService : IHostedService
public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask;
public TcmMusicTransitionOutput GetStatus()
{
lock (_statusLock)
return new TcmMusicTransitionOutput
{
Running = _status.Running,
HasVolume = _status.HasVolume,
VolumePercent = _status.VolumePercent,
Message = _status.Message
};
}
public async Task StopAsync(CancellationToken cancellationToken)
{
try { await StopMusicAsync(cancellationToken); }
@@ -56,6 +70,7 @@ public sealed class TcmMusicTransitionService : IHostedService
await CancelCurrentLoopAsync();
await _miAirX.SetVolumeAsync(_options.StartVolume, cancellationToken);
await _miAirX.PlayUrlAsync(tracks[0].Url, cancellationToken);
UpdateStatus(true, _options.StartVolume, "体质音乐正在自动渐弱");
_activeCancellation = new CancellationTokenSource();
_activeTask = RunFadeAsync(tracks, constitutionCode, _activeCancellation.Token);
}
@@ -69,6 +84,7 @@ public sealed class TcmMusicTransitionService : IHostedService
{
await CancelCurrentLoopAsync();
await _miAirX.PlayAsync(cancellationToken);
UpdateStatus(false, null, "正在播放测试音乐");
}
finally { _operationLock.Release(); }
}
@@ -81,6 +97,7 @@ public sealed class TcmMusicTransitionService : IHostedService
// 手动调音量接管当前播放,避免下一次自动渐弱立刻覆盖用户选择。
await CancelCurrentLoopAsync();
await _miAirX.SetVolumeAsync(volume, cancellationToken);
UpdateStatus(false, volume, "音量已手动设置");
}
finally { _operationLock.Release(); }
}
@@ -92,6 +109,7 @@ public sealed class TcmMusicTransitionService : IHostedService
{
await CancelCurrentLoopAsync();
await _miAirX.StopAsync(cancellationToken);
UpdateStatus(false, null, "音乐已停止");
}
finally { _operationLock.Release(); }
}
@@ -116,12 +134,14 @@ public sealed class TcmMusicTransitionService : IHostedService
{
currentVolume--;
await _miAirX.SetVolumeAsync(currentVolume, cancellationToken);
UpdateStatus(true, currentVolume, "体质音乐正在自动渐弱");
nextFadeSecond += _options.FadeStepSeconds;
}
if (currentVolume == 0)
{
await _miAirX.StopAsync(cancellationToken);
UpdateStatus(false, 0, "音量已降至 0,音乐已停止");
_logger.LogInformation("体质 {ConstitutionCode} 的助眠音乐已渐弱至 0 并停止", constitutionCode);
return;
}
@@ -140,6 +160,7 @@ public sealed class TcmMusicTransitionService : IHostedService
_logger.LogWarning(exception, "体质音乐渐弱或续播中断");
try { await _miAirX.StopAsync(CancellationToken.None); }
catch (Exception stopException) { _logger.LogWarning(stopException, "体质音乐中断后停止音箱失败"); }
UpdateStatus(false, null, "自动渐弱中断,请查看后端日志");
}
}
@@ -153,6 +174,21 @@ public sealed class TcmMusicTransitionService : IHostedService
cancellation.Cancel();
try { if (task is not null) await task; }
finally { cancellation.Dispose(); }
UpdateStatus(false, null, "自动渐弱已停止");
}
private void UpdateStatus(bool running, int? volume, string message)
{
lock (_statusLock)
{
_status.Running = running;
if (volume.HasValue)
{
_status.HasVolume = true;
_status.VolumePercent = volume.Value;
}
_status.Message = message;
}
}
private static bool IsValidTrack(TcmMusicTrackOptions track)
@@ -160,3 +196,11 @@ public sealed class TcmMusicTransitionService : IHostedService
Uri.TryCreate(track.Url, UriKind.Absolute, out var uri) &&
uri.Scheme is "http" or "https";
}
public sealed class TcmMusicTransitionOutput
{
public bool Running { get; set; }
public bool HasVolume { get; set; }
public int VolumePercent { get; set; }
public string Message { get; set; } = string.Empty;
}