Use TV guide for livestreams
🏗️ Build Plugin / build (push) Successful in 2m53s
🧪 Test Plugin / test (push) Successful in 1m21s

This commit is contained in:
2025-12-07 17:41:48 +01:00
parent 198fc4c58d
commit 0548fe7dec
17 changed files with 650 additions and 299 deletions
@@ -73,7 +73,7 @@ public class StreamProxyService : IStreamProxyService
if (tokenExpiry.HasValue)
{
_logger.LogInformation(
_logger.LogDebug(
"Registered stream for item {ItemId} (token expires at {ExpiresAt} UTC): {Url}",
itemId,
tokenExpiry.Value,
@@ -81,7 +81,7 @@ public class StreamProxyService : IStreamProxyService
}
else
{
_logger.LogInformation("Registered stream for item {ItemId}: {Url}", itemId, authenticatedUrl);
_logger.LogDebug("Registered stream for item {ItemId}: {Url}", itemId, authenticatedUrl);
}
}
@@ -219,6 +219,50 @@ public class StreamProxyService : IStreamProxyService
}
}
// Fallback: Live TV channelId_guid format lookup
// For Live TV streams, itemId format is "channelId_urnGuid"
// Try matching by suffix (urnGuid part) or prefix (channelId part)
if (itemId.Contains('_', StringComparison.Ordinal))
{
var parts = itemId.Split('_', 2);
var prefix = parts[0]; // channelId part
var suffix = parts.Length > 1 ? parts[1] : null; // urnGuid part
foreach (var kvp in _streamMappings)
{
// Check if registered key contains the same suffix (urnGuid)
if (suffix != null && kvp.Key.Contains(suffix, StringComparison.OrdinalIgnoreCase))
{
_logger.LogInformation(
"Found stream by Live TV suffix match - Requested: {RequestedId}, Registered: {RegisteredId}",
itemId,
kvp.Key);
var url = await ValidateAndReturnStreamAsync(kvp.Key, kvp.Value, cancellationToken).ConfigureAwait(false);
if (url != null)
{
// Also register with the requested itemId for future lookups
_streamMappings.AddOrUpdate(itemId, kvp.Value, (key, old) => kvp.Value);
return url;
}
}
// Check if registered key starts with the same prefix (channelId)
if (kvp.Key.StartsWith(prefix + "_", StringComparison.OrdinalIgnoreCase))
{
_logger.LogInformation(
"Found stream by Live TV prefix match - Requested: {RequestedId}, Registered: {RegisteredId}",
itemId,
kvp.Key);
var url = await ValidateAndReturnStreamAsync(kvp.Key, kvp.Value, cancellationToken).ConfigureAwait(false);
if (url != null)
{
_streamMappings.AddOrUpdate(itemId, kvp.Value, (key, old) => kvp.Value);
return url;
}
}
}
}
// Last resort: Use active stream fallbacks (helps when Jellyfin creates random transcoding session IDs)
var activeStreams = _streamMappings.Where(kvp =>
{