refactor to unify data fetching and define abstract API for re-use
🏗️ Build Plugin / build (push) Successful in 2m35s
🧪 Test Plugin / test (push) Successful in 1m14s

This commit is contained in:
2025-12-06 17:29:05 +01:00
parent 0fea57a4f9
commit a0e7663323
26 changed files with 595 additions and 254 deletions
@@ -8,6 +8,7 @@ using System.Threading.Tasks;
using System.Web;
using Jellyfin.Plugin.SRFPlay.Api;
using Jellyfin.Plugin.SRFPlay.Configuration;
using Jellyfin.Plugin.SRFPlay.Services.Interfaces;
using Microsoft.Extensions.Logging;
namespace Jellyfin.Plugin.SRFPlay.Services;
@@ -15,11 +16,11 @@ namespace Jellyfin.Plugin.SRFPlay.Services;
/// <summary>
/// Service for proxying SRF Play streams and managing authentication.
/// </summary>
public class StreamProxyService : IDisposable
public class StreamProxyService : IStreamProxyService, IDisposable
{
private readonly ILogger<StreamProxyService> _logger;
private readonly ILoggerFactory _loggerFactory;
private readonly StreamUrlResolver _streamResolver;
private readonly IStreamUrlResolver _streamResolver;
private readonly IMediaCompositionFetcher _compositionFetcher;
private readonly HttpClient _httpClient;
private readonly ConcurrentDictionary<string, StreamInfo> _streamMappings;
private bool _disposed;
@@ -28,13 +29,16 @@ public class StreamProxyService : IDisposable
/// Initializes a new instance of the <see cref="StreamProxyService"/> class.
/// </summary>
/// <param name="logger">The logger.</param>
/// <param name="loggerFactory">The logger factory (for creating API clients).</param>
/// <param name="streamResolver">The stream URL resolver.</param>
public StreamProxyService(ILogger<StreamProxyService> logger, ILoggerFactory loggerFactory, StreamUrlResolver streamResolver)
/// <param name="compositionFetcher">The media composition fetcher.</param>
public StreamProxyService(
ILogger<StreamProxyService> logger,
IStreamUrlResolver streamResolver,
IMediaCompositionFetcher compositionFetcher)
{
_logger = logger;
_loggerFactory = loggerFactory;
_streamResolver = streamResolver;
_compositionFetcher = compositionFetcher;
_httpClient = new HttpClient
{
Timeout = TimeSpan.FromSeconds(30)
@@ -306,8 +310,8 @@ public class StreamProxyService : IDisposable
try
{
using var apiClient = new SRFApiClient(_loggerFactory);
var mediaComposition = apiClient.GetMediaCompositionByUrnAsync(streamInfo.Urn, CancellationToken.None)
// Use short cache duration (5 min) for livestreams
var mediaComposition = _compositionFetcher.GetMediaCompositionAsync(streamInfo.Urn, CancellationToken.None, 5)
.GetAwaiter().GetResult();
if (mediaComposition?.ChapterList == null || mediaComposition.ChapterList.Count == 0)