diff --git a/RadioDJViewer/Main.cs b/RadioDJViewer/Main.cs index d4c5d26..6bf8278 100644 --- a/RadioDJViewer/Main.cs +++ b/RadioDJViewer/Main.cs @@ -32,6 +32,7 @@ namespace RadioDJViewer private double _playbackElapsedSeconds = 0; private double _playbackDurationSeconds = 0; private bool _playbackPaused = true; + private bool _playbackIsLiveStream = false; private DateTime _playbackBaseUtc = DateTime.UtcNow; private string selectedFolderPath = string.Empty; private string outputFolderPath = string.Empty; @@ -182,6 +183,7 @@ namespace RadioDJViewer _playbackElapsedSeconds = 0; _playbackDurationSeconds = 0; _playbackPaused = true; + _playbackIsLiveStream = false; _playbackTrackKey = string.Empty; time_data_label.Text = "No Data"; WidgetServer.CachedElapsed = "0"; @@ -478,13 +480,34 @@ namespace RadioDJViewer { double elapsedSeconds; double durationSeconds; - if (!TryParseSeconds(elapsedText, out elapsedSeconds) || !TryParseSeconds(durationText, out durationSeconds) || durationSeconds <= 0) + + bool hasDuration = TryParseSeconds(durationText, out durationSeconds); + bool isLiveStream = hasDuration && durationSeconds <= 0; + + if (isLiveStream) + { + playbackTimer.Stop(); + _playbackTrackKey = trackKey ?? string.Empty; + _playbackElapsedSeconds = 0; + _playbackDurationSeconds = 0; + _playbackPaused = false; + _playbackIsLiveStream = true; + time_data_label.Text = "LIVE"; + WidgetServer.CachedElapsed = "0"; + WidgetServer.CachedDuration = "0"; + WidgetServer.CachedTime = "LIVE"; + WidgetServer.CachedPaused = false; + return; + } + + if (!TryParseSeconds(elapsedText, out elapsedSeconds) || !hasDuration || durationSeconds <= 0) { playbackTimer.Stop(); _playbackTrackKey = trackKey ?? string.Empty; _playbackElapsedSeconds = 0; _playbackDurationSeconds = 0; _playbackPaused = true; + _playbackIsLiveStream = false; time_data_label.Text = "No Data"; WidgetServer.CachedElapsed = "0"; WidgetServer.CachedDuration = "0"; @@ -502,6 +525,7 @@ namespace RadioDJViewer _playbackDurationSeconds = durationSeconds; _playbackBaseUtc = DateTime.UtcNow; _playbackPaused = sameTrack && sameElapsed && sameDuration; + _playbackIsLiveStream = false; if (_playbackPaused) playbackTimer.Stop(); @@ -643,7 +667,14 @@ namespace RadioDJViewer #if DEBUG System.Diagnostics.Debug.WriteLine($"[SMTC] Resolved artwork path: '{smtcImagePath}' (exists={(!string.IsNullOrWhiteSpace(smtcImagePath) && File.Exists(smtcImagePath))})"); #endif - SmtcService.PublishNowPlaying(titleText, artistText, smtcImagePath, _playbackPaused); + SmtcService.PublishNowPlaying( + titleText, + artistText, + smtcImagePath, + _playbackPaused, + _playbackIsLiveStream, + GetCurrentElapsedSeconds(), + _playbackDurationSeconds); } else SmtcService.Disable(); @@ -675,6 +706,7 @@ namespace RadioDJViewer _playbackElapsedSeconds = 0; _playbackDurationSeconds = 0; _playbackPaused = true; + _playbackIsLiveStream = false; time_data_label.Text = "No Data"; WidgetServer.CachedElapsed = "0"; WidgetServer.CachedDuration = "0"; @@ -1115,7 +1147,7 @@ namespace RadioDJViewer catch { } } - public static void PublishNowPlaying(string title, string artist, string imagePath, bool paused) + public static void PublishNowPlaying(string title, string artist, string imagePath, bool paused, bool isLiveStream, double elapsedSeconds, double durationSeconds) { try { @@ -1123,12 +1155,17 @@ namespace RadioDJViewer return; SetPropertyIfExists(_smtc, "IsEnabled", true); - SetPropertyIfExists(_smtc, "IsPlayEnabled", true); - SetPropertyIfExists(_smtc, "IsPauseEnabled", true); + SetPropertyIfExists(_smtc, "IsPlayEnabled", !isLiveStream); + SetPropertyIfExists(_smtc, "IsPauseEnabled", !isLiveStream); SetPropertyIfExists(_smtc, "IsStopEnabled", true); SetPropertyIfExists(_smtc, "IsNextEnabled", false); SetPropertyIfExists(_smtc, "IsPreviousEnabled", false); - SetPlaybackStatus(paused ? "Paused" : "Playing"); + SetPlaybackStatus(isLiveStream ? "Playing" : (paused ? "Paused" : "Playing")); + + if (isLiveStream) + TryClearTimelineProperties(); + else + TryUpdateTimelineProperties(elapsedSeconds, durationSeconds); object updater = GetPropertyValue(_smtc, "DisplayUpdater"); if (updater == null) @@ -1230,6 +1267,66 @@ namespace RadioDJViewer catch { } } + private static void TryUpdateTimelineProperties(double elapsedSeconds, double durationSeconds) + { + try + { + if (_smtc == null || durationSeconds <= 0) + return; + + double clampedElapsed = elapsedSeconds; + if (clampedElapsed < 0) + clampedElapsed = 0; + if (clampedElapsed > durationSeconds) + clampedElapsed = durationSeconds; + + Type timelineType = Type.GetType("Windows.Media.SystemMediaTransportControlsTimelineProperties, Windows, ContentType=WindowsRuntime"); + if (timelineType == null) + return; + + object timeline = Activator.CreateInstance(timelineType); + TimeSpan start = TimeSpan.Zero; + TimeSpan position = TimeSpan.FromSeconds(clampedElapsed); + TimeSpan end = TimeSpan.FromSeconds(durationSeconds); + + SetPropertyIfExists(timeline, "StartTime", start); + SetPropertyIfExists(timeline, "MinSeekTime", start); + SetPropertyIfExists(timeline, "Position", position); + SetPropertyIfExists(timeline, "MaxSeekTime", end); + SetPropertyIfExists(timeline, "EndTime", end); + + MethodInfo updateTimelineMethod = _smtc.GetType().GetMethod("UpdateTimelineProperties", BindingFlags.Public | BindingFlags.Instance, null, new[] { timelineType }, null); + updateTimelineMethod?.Invoke(_smtc, new[] { timeline }); + } + catch { } + } + + private static void TryClearTimelineProperties() + { + try + { + if (_smtc == null) + return; + + Type timelineType = Type.GetType("Windows.Media.SystemMediaTransportControlsTimelineProperties, Windows, ContentType=WindowsRuntime"); + if (timelineType == null) + return; + + object timeline = Activator.CreateInstance(timelineType); + TimeSpan zero = TimeSpan.Zero; + + SetPropertyIfExists(timeline, "StartTime", zero); + SetPropertyIfExists(timeline, "MinSeekTime", zero); + SetPropertyIfExists(timeline, "Position", zero); + SetPropertyIfExists(timeline, "MaxSeekTime", zero); + SetPropertyIfExists(timeline, "EndTime", zero); + + MethodInfo updateTimelineMethod = _smtc.GetType().GetMethod("UpdateTimelineProperties", BindingFlags.Public | BindingFlags.Instance, null, new[] { timelineType }, null); + updateTimelineMethod?.Invoke(_smtc, new[] { timeline }); + } + catch { } + } + private static string CreateSmtcThumbnailTempFile(string sourcePath) { try diff --git a/RadioDJViewer/Properties/AssemblyInfo.cs b/RadioDJViewer/Properties/AssemblyInfo.cs index 2ac9191..d66c9d1 100644 --- a/RadioDJViewer/Properties/AssemblyInfo.cs +++ b/RadioDJViewer/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("1.15.0")] -[assembly: AssemblyFileVersion("1.15.0")] +[assembly: AssemblyVersion("1.15.1")] +[assembly: AssemblyFileVersion("1.15.1")]