From b63c8c5926ed45ada283ba2d44ddefc4c204fec0 Mon Sep 17 00:00:00 2001 From: minster586 <43217359+minster586@users.noreply.github.com> Date: Wed, 28 Oct 2026 19:14:38 -0400 Subject: [PATCH] Tiny little tweak to allow that if there is a live stream it looks at the duration it sees that it is zero and for SMTC it does not show the status that it is paused it merely shows that it is actively playing It also made a tiny change in the GUI for the time it shows the word live which is kind of cool --- RadioDJViewer/Main.cs | 109 +++++++++++++++++++++-- RadioDJViewer/Properties/AssemblyInfo.cs | 4 +- 2 files changed, 105 insertions(+), 8 deletions(-) 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")]