Clean up dead code, consolidate duplication, fix redundancies
🏗️ Build Plugin / build (push) Failing after 9s
🧪 Test Plugin / test (push) Successful in 1m28s
🚀 Release Plugin / build-and-release (push) Failing after 5s

Remove 9 dead methods, 6 unused constants, and redundant
ReaderWriterLockSlim from MetadataCache. Consolidate repeated
patterns into HasChapters, IsPlayable, and ToLowerString helpers.
Extract shared API methods in SRFApiClient. Move variant manifest
rewriting from controller to StreamProxyService. Make Auto quality
distinct from HD. Update README architecture section.
This commit is contained in:
2026-02-28 11:34:45 +01:00
parent 873e531599
commit 7c76402a4a
23 changed files with 245 additions and 625 deletions
@@ -196,7 +196,23 @@ public class StreamProxyController : ControllerBase
var manifestContent = System.Text.Encoding.UTF8.GetString(manifestData);
var scheme = GetProxyScheme();
var baseProxyUrl = $"{scheme}://{Request.Host}/Plugins/SRFPlay/Proxy/{itemId}";
var rewrittenContent = RewriteSegmentUrls(manifestContent, baseProxyUrl);
// Extract query parameters from the current request to propagate them
string queryParams;
if (Request.Query.TryGetValue("token", out var tokenVal) && !string.IsNullOrEmpty(tokenVal))
{
queryParams = $"?token={tokenVal}";
}
else if (Request.Query.TryGetValue("itemId", out var itemIdVal) && !string.IsNullOrEmpty(itemIdVal))
{
queryParams = $"?itemId={itemIdVal}";
}
else
{
queryParams = string.Empty;
}
var rewrittenContent = _proxyService.RewriteVariantManifestUrls(manifestContent, baseProxyUrl, queryParams);
// Set cache headers based on stream type (live vs VOD)
AddManifestCacheHeaders(actualItemId);
@@ -311,81 +327,6 @@ public class StreamProxyController : ControllerBase
return pathItemId;
}
/// <summary>
/// Rewrites segment URLs in a manifest to point to proxy.
/// </summary>
/// <param name="manifestContent">The manifest content.</param>
/// <param name="baseProxyUrl">The base proxy URL.</param>
/// <returns>The rewritten manifest.</returns>
private string RewriteSegmentUrls(string manifestContent, string baseProxyUrl)
{
// Extract query parameters from the current request to propagate them
string queryParams;
if (Request.Query.TryGetValue("token", out var token) && !string.IsNullOrEmpty(token))
{
queryParams = $"?token={token}";
}
else if (Request.Query.TryGetValue("itemId", out var itemId) && !string.IsNullOrEmpty(itemId))
{
queryParams = $"?itemId={itemId}";
}
else
{
queryParams = string.Empty;
}
// Helper function to rewrite a single URL
string RewriteUrl(string url)
{
if (url.Contains("://", StringComparison.Ordinal))
{
// Absolute URL - extract filename and rewrite
var uri = new Uri(url.Trim());
var segments = uri.AbsolutePath.Split('/');
var fileName = segments[^1];
return $"{baseProxyUrl}/{fileName}{queryParams}";
}
// Relative URL - rewrite to proxy
return $"{baseProxyUrl}/{url.Trim()}{queryParams}";
}
var lines = manifestContent.Split('\n');
var result = new System.Text.StringBuilder();
foreach (var line in lines)
{
if (string.IsNullOrWhiteSpace(line))
{
result.AppendLine(line);
}
else if (line.StartsWith('#'))
{
// HLS tag line - check for URI="..." attributes (e.g., #EXT-X-MAP:URI="init.mp4")
if (line.Contains("URI=\"", StringComparison.Ordinal))
{
var rewrittenLine = System.Text.RegularExpressions.Regex.Replace(
line,
@"URI=""([^""]+)""",
match => $"URI=\"{RewriteUrl(match.Groups[1].Value)}\"");
result.AppendLine(rewrittenLine);
}
else
{
// Keep other metadata lines as-is
result.AppendLine(line);
}
}
else
{
// Non-tag line with URL - rewrite it
result.AppendLine(RewriteUrl(line));
}
}
return result.ToString();
}
/// <summary>
/// Proxies image requests from SRF CDN, fixing Content-Type headers.
/// </summary>