diff --git a/LME.UAKino/Controller.cs b/LME.UAKino/Controller.cs
index ef65682..0315d5d 100644
--- a/LME.UAKino/Controller.cs
+++ b/LME.UAKino/Controller.cs
@@ -118,10 +118,14 @@ namespace LME.UAKino.Controllers
}
else
{
- string resolvedUrl = await invoke.ResolveAshdiVod(fallbackUrl);
- string streamUrl = BuildStreamUrl(init, resolvedUrl);
- var movie_tpl = new MovieTpl(title, original_title);
- movie_tpl.Append("Фільм", streamUrl);
+ var resolvedStreams = await invoke.ResolveAshdiVodAll(fallbackUrl);
+ var movie_tpl = new MovieTpl(title, original_title, resolvedStreams.Count);
+ foreach (var (file, label) in resolvedStreams)
+ {
+ string displayLabel = !string.IsNullOrEmpty(label) ? label : "Фільм";
+ string streamUrl = BuildStreamUrl(init, file);
+ movie_tpl.Append(displayLabel, streamUrl);
+ }
return rjson
? Content(movie_tpl.ToJson(), "application/json; charset=utf-8")
: Content(movie_tpl.ToHtml(), "text/html; charset=utf-8");
diff --git a/LME.UAKino/UAKinoInvoke.cs b/LME.UAKino/UAKinoInvoke.cs
index 24ce2c6..f334078 100644
--- a/LME.UAKino/UAKinoInvoke.cs
+++ b/LME.UAKino/UAKinoInvoke.cs
@@ -270,6 +270,78 @@ namespace LME.UAKino
}
}
+ ///
+ /// Резолв Ashdi VOD з ?multivoice: повертає ВСІ стріми з JSON масиву
+ ///
+ public async Task> ResolveAshdiVodAll(string vodUrl)
+ {
+ var result = new List<(string file, string title)>();
+
+ if (string.IsNullOrEmpty(vodUrl) || !ApnHelper.IsAshdiUrl(vodUrl))
+ {
+ if (!string.IsNullOrEmpty(vodUrl))
+ result.Add((vodUrl, null));
+ return result;
+ }
+
+ try
+ {
+ _onLog?.Invoke($"UAKino resolve Ashdi all: {vodUrl}");
+
+ var headers = new List()
+ {
+ new HeadersModel("User-Agent", Http.UserAgent),
+ new HeadersModel("Referer", "https://ashdi.vip/")
+ };
+
+ string fetchUrl = vodUrl;
+ if (ApnHelper.IsEnabled(_init) && string.IsNullOrWhiteSpace(_init.webcorshost))
+ fetchUrl = ApnHelper.WrapUrl(_init, fetchUrl);
+
+ string html = await HttpGet(fetchUrl, headers);
+ if (string.IsNullOrEmpty(html))
+ {
+ result.Add((vodUrl, null));
+ return result;
+ }
+
+ int arrayStart = FindAshdiJsonArray(html);
+ if (arrayStart >= 0)
+ {
+ string jsonArray = ExtractBalancedBrackets(html, arrayStart);
+ if (!string.IsNullOrEmpty(jsonArray))
+ {
+ try
+ {
+ using var arr = JsonDocument.Parse(jsonArray);
+ if (arr.RootElement.ValueKind == JsonValueKind.Array)
+ {
+ foreach (var item in arr.RootElement.EnumerateArray())
+ {
+ string file = item.GetProperty("file").GetString();
+ string title = item.TryGetProperty("title", out var t) ? t.GetString() : null;
+ if (!string.IsNullOrEmpty(file))
+ result.Add((file, title?.Trim()));
+ }
+ }
+ }
+ catch { }
+ }
+ }
+
+ if (result.Count == 0)
+ result.Add((vodUrl, null));
+
+ return result;
+ }
+ catch (Exception ex)
+ {
+ _onLog?.Invoke($"UAKino resolve Ashdi all error: {ex.Message}");
+ result.Add((vodUrl, null));
+ return result;
+ }
+ }
+
///
/// Знайти позицію JSON масиву `[{...}]` після `file:'`
///