Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
92dc6d8203 | ||
|
|
d313b68975 |
@@ -183,7 +183,8 @@ public class StreamProxyController : ControllerBase
|
||||
try
|
||||
{
|
||||
// Fetch the variant manifest as a segment
|
||||
var manifestData = await _proxyService.GetSegmentAsync(actualItemId, fullPath, cancellationToken).ConfigureAwait(false);
|
||||
var queryString = Request.QueryString.HasValue ? Request.QueryString.Value : null;
|
||||
var manifestData = await _proxyService.GetSegmentAsync(actualItemId, fullPath, queryString, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (manifestData == null)
|
||||
{
|
||||
@@ -234,7 +235,9 @@ public class StreamProxyController : ControllerBase
|
||||
|
||||
try
|
||||
{
|
||||
var segmentData = await _proxyService.GetSegmentAsync(actualItemId, segmentPath, cancellationToken).ConfigureAwait(false);
|
||||
// Pass the original query string to preserve segment-specific parameters (e.g., ?m=timestamp)
|
||||
var queryString = Request.QueryString.HasValue ? Request.QueryString.Value : null;
|
||||
var segmentData = await _proxyService.GetSegmentAsync(actualItemId, segmentPath, queryString, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (segmentData == null)
|
||||
{
|
||||
|
||||
@@ -56,9 +56,10 @@ public interface IStreamProxyService
|
||||
/// </summary>
|
||||
/// <param name="itemId">The item ID.</param>
|
||||
/// <param name="segmentPath">The segment path.</param>
|
||||
/// <param name="queryString">The original query string from the request (preserves segment-specific parameters like timestamps).</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>The segment content as bytes.</returns>
|
||||
Task<byte[]?> GetSegmentAsync(string itemId, string segmentPath, CancellationToken cancellationToken = default);
|
||||
Task<byte[]?> GetSegmentAsync(string itemId, string segmentPath, string? queryString = null, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Cleans up old and expired stream mappings.
|
||||
|
||||
@@ -701,11 +701,13 @@ public class StreamProxyService : IStreamProxyService
|
||||
/// </summary>
|
||||
/// <param name="itemId">The item ID.</param>
|
||||
/// <param name="segmentPath">The segment path.</param>
|
||||
/// <param name="queryString">The original query string from the request (preserves segment-specific parameters like timestamps).</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>The segment content as bytes.</returns>
|
||||
public async Task<byte[]?> GetSegmentAsync(
|
||||
string itemId,
|
||||
string segmentPath,
|
||||
string? queryString = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var authenticatedUrl = await GetAuthenticatedUrlAsync(itemId, cancellationToken).ConfigureAwait(false);
|
||||
@@ -720,17 +722,29 @@ public class StreamProxyService : IStreamProxyService
|
||||
var baseUri = new Uri(authenticatedUrl);
|
||||
var baseUrl = $"{baseUri.Scheme}://{baseUri.Host}{string.Join('/', baseUri.AbsolutePath.Split('/')[..^1])}";
|
||||
|
||||
// Extract query parameters (auth tokens) from authenticated URL
|
||||
var queryParams = baseUri.Query;
|
||||
// Use the original query string from the request (preserves segment-specific params like ?m=timestamp)
|
||||
// If no query string is provided, check if we need to add auth params from the master manifest
|
||||
var queryParams = string.Empty;
|
||||
if (!string.IsNullOrEmpty(queryString))
|
||||
{
|
||||
// Use the original query string from the segment request
|
||||
queryParams = queryString.StartsWith('?') ? queryString : $"?{queryString}";
|
||||
}
|
||||
else if (!segmentPath.Contains("hdntl=", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// Only append master manifest query params if segment doesn't have path-based auth
|
||||
queryParams = baseUri.Query;
|
||||
}
|
||||
|
||||
// Build full segment URL
|
||||
var segmentUrl = $"{baseUrl}/{segmentPath}{queryParams}";
|
||||
|
||||
_logger.LogDebug(
|
||||
"Fetching segment - BaseUri: {BaseUri}, BaseUrl: {BaseUrl}, SegmentPath: {SegmentPath}, FullUrl: {FullUrl}",
|
||||
"Fetching segment - BaseUri: {BaseUri}, BaseUrl: {BaseUrl}, SegmentPath: {SegmentPath}, QueryString: {QueryString}, FullUrl: {FullUrl}",
|
||||
authenticatedUrl,
|
||||
baseUrl,
|
||||
segmentPath,
|
||||
queryString ?? "(none)",
|
||||
segmentUrl);
|
||||
using var httpClient = _httpClientFactory.CreateClient(NamedClient.Default);
|
||||
var segmentData = await httpClient.GetByteArrayAsync(segmentUrl, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
@@ -8,6 +8,14 @@
|
||||
"category": "Live TV",
|
||||
"imageUrl": "https://gitea.tourolle.paris/dtourolle/jellyfin-srfPlay/raw/branch/master/assests/main%20logo.png",
|
||||
"versions": [
|
||||
{
|
||||
"version": "1.0.14",
|
||||
"changelog": "Release 1.0.14",
|
||||
"targetAbi": "10.9.0.0",
|
||||
"sourceUrl": "https://gitea.tourolle.paris/dtourolle/jellyfin-srfPlay/releases/download/v1.0.14/srfplay_1.0.14.0.zip",
|
||||
"checksum": "49e6afe16f7abf95c099ecc1d016e725",
|
||||
"timestamp": "2025-12-30T12:38:41Z"
|
||||
},
|
||||
{
|
||||
"version": "1.0.13",
|
||||
"changelog": "Release 1.0.13",
|
||||
|
||||
Reference in New Issue
Block a user