passthrough not transcode
This commit is contained in:
parent
cd0f680981
commit
e26f2a2ab1
@ -7,6 +7,7 @@ using System.Text;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Jellyfin.Plugin.SRFPlay.Services;
|
using Jellyfin.Plugin.SRFPlay.Services;
|
||||||
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Controller.Channels;
|
using MediaBrowser.Controller.Channels;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Channels;
|
using MediaBrowser.Model.Channels;
|
||||||
@ -27,6 +28,7 @@ public class SRFPlayChannel : IChannel, IHasCacheKey
|
|||||||
private readonly StreamUrlResolver _streamResolver;
|
private readonly StreamUrlResolver _streamResolver;
|
||||||
private readonly StreamProxyService _proxyService;
|
private readonly StreamProxyService _proxyService;
|
||||||
private readonly CategoryService? _categoryService;
|
private readonly CategoryService? _categoryService;
|
||||||
|
private readonly IServerApplicationHost _appHost;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="SRFPlayChannel"/> class.
|
/// Initializes a new instance of the <see cref="SRFPlayChannel"/> class.
|
||||||
@ -35,12 +37,14 @@ public class SRFPlayChannel : IChannel, IHasCacheKey
|
|||||||
/// <param name="contentRefreshService">The content refresh service.</param>
|
/// <param name="contentRefreshService">The content refresh service.</param>
|
||||||
/// <param name="streamResolver">The stream resolver.</param>
|
/// <param name="streamResolver">The stream resolver.</param>
|
||||||
/// <param name="proxyService">The stream proxy service.</param>
|
/// <param name="proxyService">The stream proxy service.</param>
|
||||||
|
/// <param name="appHost">The server application host.</param>
|
||||||
/// <param name="categoryService">The category service (optional).</param>
|
/// <param name="categoryService">The category service (optional).</param>
|
||||||
public SRFPlayChannel(
|
public SRFPlayChannel(
|
||||||
ILoggerFactory loggerFactory,
|
ILoggerFactory loggerFactory,
|
||||||
ContentRefreshService contentRefreshService,
|
ContentRefreshService contentRefreshService,
|
||||||
StreamUrlResolver streamResolver,
|
StreamUrlResolver streamResolver,
|
||||||
StreamProxyService proxyService,
|
StreamProxyService proxyService,
|
||||||
|
IServerApplicationHost appHost,
|
||||||
CategoryService? categoryService = null)
|
CategoryService? categoryService = null)
|
||||||
{
|
{
|
||||||
_loggerFactory = loggerFactory;
|
_loggerFactory = loggerFactory;
|
||||||
@ -48,6 +52,7 @@ public class SRFPlayChannel : IChannel, IHasCacheKey
|
|||||||
_contentRefreshService = contentRefreshService;
|
_contentRefreshService = contentRefreshService;
|
||||||
_streamResolver = streamResolver;
|
_streamResolver = streamResolver;
|
||||||
_proxyService = proxyService;
|
_proxyService = proxyService;
|
||||||
|
_appHost = appHost;
|
||||||
_categoryService = categoryService;
|
_categoryService = categoryService;
|
||||||
|
|
||||||
if (_categoryService == null)
|
if (_categoryService == null)
|
||||||
@ -471,9 +476,13 @@ public class SRFPlayChannel : IChannel, IHasCacheKey
|
|||||||
// Register stream with proxy service
|
// Register stream with proxy service
|
||||||
_proxyService.RegisterStream(itemId, streamUrl);
|
_proxyService.RegisterStream(itemId, streamUrl);
|
||||||
|
|
||||||
|
// Get the server's local API URL so remote clients can access the proxy
|
||||||
|
// Use the published server address configured in Jellyfin's network settings
|
||||||
|
var serverUrl = _appHost.GetSmartApiUrl(string.Empty);
|
||||||
|
|
||||||
// Create proxy URL as absolute HTTP URL (required for ffmpeg)
|
// Create proxy URL as absolute HTTP URL (required for ffmpeg)
|
||||||
// Use localhost as Jellyfin should be able to access its own endpoints
|
// Use the actual server URL so remote clients can access it
|
||||||
var proxyUrl = $"http://localhost:8096/Plugins/SRFPlay/Proxy/{itemId}/master.m3u8";
|
var proxyUrl = $"{serverUrl}/Plugins/SRFPlay/Proxy/{itemId}/master.m3u8";
|
||||||
|
|
||||||
// Build overview
|
// Build overview
|
||||||
var overview = chapter.Description ?? chapter.Lead;
|
var overview = chapter.Description ?? chapter.Lead;
|
||||||
|
|||||||
@ -5,6 +5,7 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Jellyfin.Plugin.SRFPlay.Api;
|
using Jellyfin.Plugin.SRFPlay.Api;
|
||||||
using Jellyfin.Plugin.SRFPlay.Services;
|
using Jellyfin.Plugin.SRFPlay.Services;
|
||||||
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
@ -24,6 +25,7 @@ public class SRFMediaProvider : IMediaSourceProvider
|
|||||||
private readonly MetadataCache _metadataCache;
|
private readonly MetadataCache _metadataCache;
|
||||||
private readonly StreamUrlResolver _streamResolver;
|
private readonly StreamUrlResolver _streamResolver;
|
||||||
private readonly StreamProxyService _proxyService;
|
private readonly StreamProxyService _proxyService;
|
||||||
|
private readonly IServerApplicationHost _appHost;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="SRFMediaProvider"/> class.
|
/// Initializes a new instance of the <see cref="SRFMediaProvider"/> class.
|
||||||
@ -32,17 +34,20 @@ public class SRFMediaProvider : IMediaSourceProvider
|
|||||||
/// <param name="metadataCache">The metadata cache.</param>
|
/// <param name="metadataCache">The metadata cache.</param>
|
||||||
/// <param name="streamResolver">The stream URL resolver.</param>
|
/// <param name="streamResolver">The stream URL resolver.</param>
|
||||||
/// <param name="proxyService">The stream proxy service.</param>
|
/// <param name="proxyService">The stream proxy service.</param>
|
||||||
|
/// <param name="appHost">The server application host.</param>
|
||||||
public SRFMediaProvider(
|
public SRFMediaProvider(
|
||||||
ILoggerFactory loggerFactory,
|
ILoggerFactory loggerFactory,
|
||||||
MetadataCache metadataCache,
|
MetadataCache metadataCache,
|
||||||
StreamUrlResolver streamResolver,
|
StreamUrlResolver streamResolver,
|
||||||
StreamProxyService proxyService)
|
StreamProxyService proxyService,
|
||||||
|
IServerApplicationHost appHost)
|
||||||
{
|
{
|
||||||
_loggerFactory = loggerFactory;
|
_loggerFactory = loggerFactory;
|
||||||
_logger = loggerFactory.CreateLogger<SRFMediaProvider>();
|
_logger = loggerFactory.CreateLogger<SRFMediaProvider>();
|
||||||
_metadataCache = metadataCache;
|
_metadataCache = metadataCache;
|
||||||
_streamResolver = streamResolver;
|
_streamResolver = streamResolver;
|
||||||
_proxyService = proxyService;
|
_proxyService = proxyService;
|
||||||
|
_appHost = appHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -174,10 +179,14 @@ public class SRFMediaProvider : IMediaSourceProvider
|
|||||||
var itemIdStr = item.Id.ToString("N"); // Use hex format without dashes
|
var itemIdStr = item.Id.ToString("N"); // Use hex format without dashes
|
||||||
_proxyService.RegisterStream(itemIdStr, streamUrl);
|
_proxyService.RegisterStream(itemIdStr, streamUrl);
|
||||||
|
|
||||||
|
// Get the server's local API URL so remote clients can access the proxy
|
||||||
|
// Use the published server address configured in Jellyfin's network settings
|
||||||
|
var serverUrl = _appHost.GetSmartApiUrl(string.Empty);
|
||||||
|
|
||||||
// Create proxy URL as absolute HTTP URL (required for ffmpeg)
|
// Create proxy URL as absolute HTTP URL (required for ffmpeg)
|
||||||
// Use localhost as Jellyfin should be able to access its own endpoints
|
// Use the actual server URL so remote clients can access it
|
||||||
// Include item ID as query parameter to preserve it during transcoding
|
// Include item ID as query parameter to preserve it during transcoding
|
||||||
var proxyUrl = $"http://localhost:8096/Plugins/SRFPlay/Proxy/{itemIdStr}/master.m3u8?itemId={itemIdStr}";
|
var proxyUrl = $"{serverUrl}/Plugins/SRFPlay/Proxy/{itemIdStr}/master.m3u8?itemId={itemIdStr}";
|
||||||
|
|
||||||
_logger.LogInformation("Using proxy URL for item {ItemId}: {ProxyUrl}", itemIdStr, proxyUrl);
|
_logger.LogInformation("Using proxy URL for item {ItemId}: {ProxyUrl}", itemIdStr, proxyUrl);
|
||||||
|
|
||||||
|
|||||||
@ -87,6 +87,17 @@ public class StreamUrlResolver : IDisposable
|
|||||||
chapter.Id,
|
chapter.Id,
|
||||||
hlsResources.Count);
|
hlsResources.Count);
|
||||||
|
|
||||||
|
// Log all HLS resources with their quality info to help debug quality selection
|
||||||
|
foreach (var resource in hlsResources)
|
||||||
|
{
|
||||||
|
_logger.LogInformation(
|
||||||
|
"Available HLS resource - Quality={Quality}, Protocol={Protocol}, Streaming={Streaming}, URL={Url}",
|
||||||
|
resource.Quality ?? "NULL",
|
||||||
|
resource.Protocol ?? "NULL",
|
||||||
|
resource.Streaming ?? "NULL",
|
||||||
|
resource.Url);
|
||||||
|
}
|
||||||
|
|
||||||
if (hlsResources.Count == 0)
|
if (hlsResources.Count == 0)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("No HLS resources found for chapter: {ChapterId}", chapter.Id);
|
_logger.LogWarning("No HLS resources found for chapter: {ChapterId}", chapter.Id);
|
||||||
@ -114,6 +125,10 @@ public class StreamUrlResolver : IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Select based on quality preference
|
// Select based on quality preference
|
||||||
|
_logger.LogInformation(
|
||||||
|
"Selecting stream with quality preference: {QualityPreference}",
|
||||||
|
qualityPreference);
|
||||||
|
|
||||||
Resource? selectedResource = qualityPreference switch
|
Resource? selectedResource = qualityPreference switch
|
||||||
{
|
{
|
||||||
QualityPreference.HD => SelectHDResource(hlsResources) ?? SelectBestAvailableResource(hlsResources),
|
QualityPreference.HD => SelectHDResource(hlsResources) ?? SelectBestAvailableResource(hlsResources),
|
||||||
@ -124,10 +139,10 @@ public class StreamUrlResolver : IDisposable
|
|||||||
|
|
||||||
if (selectedResource != null)
|
if (selectedResource != null)
|
||||||
{
|
{
|
||||||
_logger.LogDebug(
|
_logger.LogInformation(
|
||||||
"Selected stream for chapter {ChapterId}: Quality={Quality}, Protocol={Protocol}, URL={Url}",
|
"✅ Selected stream for chapter {ChapterId}: Quality={Quality}, Protocol={Protocol}, URL={Url}",
|
||||||
chapter.Id,
|
chapter.Id,
|
||||||
selectedResource.Quality,
|
selectedResource.Quality ?? "NULL",
|
||||||
selectedResource.Protocol,
|
selectedResource.Protocol,
|
||||||
selectedResource.Url);
|
selectedResource.Url);
|
||||||
return selectedResource.Url;
|
return selectedResource.Url;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user