tokens refresh on media start
🏗️ Build Plugin / build (push) Successful in 2m19s
🧪 Test Plugin / test (push) Successful in 1m8s
🚀 Release Plugin / build-and-release (push) Successful in 2m18s

This commit is contained in:
2025-11-15 17:51:14 +01:00
parent d48b515898
commit 8e86db100a
3 changed files with 38 additions and 86 deletions
@@ -119,37 +119,11 @@ public class SRFMediaProvider : IMediaSourceProvider
// Get stream URL based on quality preference
var streamUrl = _streamResolver.GetStreamUrl(chapter, config.QualityPreference);
// Check if this is an upcoming livestream that hasn't started yet
var isUpcomingLivestream = chapter.Type == "SCHEDULED_LIVESTREAM" && string.IsNullOrEmpty(streamUrl);
if (string.IsNullOrEmpty(streamUrl) && !isUpcomingLivestream)
// For scheduled livestreams, always fetch fresh data to ensure stream URL is current
if (chapter.Type == "SCHEDULED_LIVESTREAM" && string.IsNullOrEmpty(streamUrl))
{
_logger.LogWarning("Could not resolve stream URL for URN: {Urn}", urn);
return Task.FromResult<IEnumerable<MediaSourceInfo>>(sources);
}
_logger.LogDebug("URN {Urn}: Scheduled livestream has no stream URL, fetching fresh data", urn);
// For upcoming livestreams, check if the event has started
if (isUpcomingLivestream)
{
if (chapter.ValidFrom != null)
{
var eventStart = chapter.ValidFrom.Value.ToUniversalTime();
var now = DateTime.UtcNow;
if (eventStart > now)
{
_logger.LogInformation(
"URN {Urn}: Livestream '{Title}' hasn't started yet (starts at {ValidFrom}). User should refresh when live.",
urn,
chapter.Title,
chapter.ValidFrom);
// Return empty sources - event not yet playable
return Task.FromResult<IEnumerable<MediaSourceInfo>>(sources);
}
}
// Event should be live now - re-fetch media composition without cache
using var freshApiClient = new SRFApiClient(_loggerFactory);
var freshMediaComposition = freshApiClient.GetMediaCompositionByUrnAsync(urn, cancellationToken).GetAwaiter().GetResult();
@@ -163,19 +137,15 @@ public class SRFMediaProvider : IMediaSourceProvider
// Update cache with fresh data
_metadataCache.SetMediaComposition(urn, freshMediaComposition);
chapter = freshChapter;
_logger.LogInformation("URN {Urn}: Livestream is now live, got fresh stream URL", urn);
}
else
{
_logger.LogWarning("URN {Urn}: Livestream should be live but still no stream URL available", urn);
return Task.FromResult<IEnumerable<MediaSourceInfo>>(sources);
_logger.LogInformation("URN {Urn}: Got fresh stream URL for scheduled livestream", urn);
}
}
else
{
_logger.LogWarning("URN {Urn}: Failed to fetch fresh media composition for livestream", urn);
return Task.FromResult<IEnumerable<MediaSourceInfo>>(sources);
}
}
if (string.IsNullOrEmpty(streamUrl))
{
_logger.LogWarning("Could not resolve stream URL for URN: {Urn}", urn);
return Task.FromResult<IEnumerable<MediaSourceInfo>>(sources);
}
// Authenticate the stream URL (required for all SRF streams, especially livestreams)
@@ -188,13 +158,13 @@ public class SRFMediaProvider : IMediaSourceProvider
// Create media source
var mediaSource = new MediaSourceInfo
{
Id = urn,
Id = item.Id.ToString(), // Use item GUID, not URN string (required for transcoding)
Name = chapter.Title,
Path = streamUrl,
Protocol = MediaProtocol.Http,
Container = "m3u8",
SupportsDirectStream = true,
SupportsDirectPlay = true,
SupportsDirectPlay = false, // Disabled: auth tokens don't carry over to HLS segments in browser
SupportsTranscoding = true,
IsRemote = true,
Type = MediaSourceType.Default,