mirror of
https://github.com/lampame/lampac-ukraine.git
synced 2026-06-17 12:08:54 +00:00
fix(uakino): add HTML page fallback when playlist API returns no data
Handle cases where UAKino playlist requests return empty results by resolving stream URLs directly from the content page HTML. Add a fallback parser that extracts video sources from `link[itemprop=video]` or `iframe#pre`, and use it to return playable movie or single-episode responses instead of failing immediately. Ensure Ashdi links consistently include `multivoice` for movie playback, including episode file URLs, to improve stream compatibility.
This commit is contained in:
parent
a54bc0e435
commit
80f0869401
@ -99,7 +99,37 @@ namespace LME.UAKino.Controllers
|
||||
|
||||
var voices = await invoke.GetPlaylist(newsId);
|
||||
if (voices == null || voices.Count == 0)
|
||||
{
|
||||
// Fallback: playlist API повернув ERR_NOT_DATA — пробуємо зі сторінки
|
||||
string fallbackUrl = await invoke.GetPageFallbackUrl(itemUrl);
|
||||
if (!string.IsNullOrEmpty(fallbackUrl))
|
||||
{
|
||||
if (serial == 1)
|
||||
{
|
||||
var voice_tpl = new VoiceTpl();
|
||||
var episode_tpl = new EpisodeTpl();
|
||||
string streamUrl = BuildStreamUrl(init, fallbackUrl);
|
||||
voice_tpl.Append("Озвучення", true, null);
|
||||
episode_tpl.Append("Епізод 1", title ?? original_title, s >= 0 ? s.ToString() : "1", "01", streamUrl);
|
||||
episode_tpl.Append(voice_tpl);
|
||||
return rjson
|
||||
? Content(episode_tpl.ToJson(), "application/json; charset=utf-8")
|
||||
: Content(episode_tpl.ToHtml(), "text/html; charset=utf-8");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ApnHelper.IsAshdiUrl(fallbackUrl) && !fallbackUrl.Contains("multivoice"))
|
||||
fallbackUrl += (fallbackUrl.Contains("?") ? "&" : "?") + "multivoice";
|
||||
string streamUrl = BuildStreamUrl(init, fallbackUrl);
|
||||
var movie_tpl = new MovieTpl(title, original_title);
|
||||
movie_tpl.Append("Фільм", streamUrl);
|
||||
return rjson
|
||||
? Content(movie_tpl.ToJson(), "application/json; charset=utf-8")
|
||||
: Content(movie_tpl.ToHtml(), "text/html; charset=utf-8");
|
||||
}
|
||||
}
|
||||
return OnError("lme_uakino", refresh_proxy: true);
|
||||
}
|
||||
|
||||
if (serial == 1)
|
||||
{
|
||||
@ -190,7 +220,11 @@ namespace LME.UAKino.Controllers
|
||||
if (voices.Count == 1 && voice.Episodes.Count > 1)
|
||||
label = ep.Title;
|
||||
|
||||
string streamUrl = BuildStreamUrl(init, ep.FileUrl);
|
||||
string fileUrl = ep.FileUrl;
|
||||
if (ApnHelper.IsAshdiUrl(fileUrl) && !fileUrl.Contains("multivoice"))
|
||||
fileUrl += (fileUrl.Contains("?") ? "&" : "?") + "multivoice";
|
||||
|
||||
string streamUrl = BuildStreamUrl(init, fileUrl);
|
||||
movie_tpl.Append(label, streamUrl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,6 +139,60 @@ namespace LME.UAKino
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fallback: отримати стрім з HTML сторінки фільму коли playlist API недоступний
|
||||
/// Парсить <link itemprop="video" value="..."> або <iframe id="pre" src="...">
|
||||
/// </summary>
|
||||
public async Task<string> GetPageFallbackUrl(string pageUrl)
|
||||
{
|
||||
if (string.IsNullOrEmpty(pageUrl))
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
_onLog?.Invoke($"UAKino page fallback: {pageUrl}");
|
||||
|
||||
var headers = new List<HeadersModel>()
|
||||
{
|
||||
new HeadersModel("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.3 Safari/605.1.15"),
|
||||
new HeadersModel("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"),
|
||||
new HeadersModel("Referer", _init.host)
|
||||
};
|
||||
|
||||
string html = await HttpGet(pageUrl, headers);
|
||||
if (string.IsNullOrEmpty(html))
|
||||
return null;
|
||||
|
||||
var doc = new HtmlDocument();
|
||||
doc.LoadHtml(html);
|
||||
|
||||
// Спершу пробуємо <link itemprop="video" value="...">
|
||||
var linkTag = doc.DocumentNode.SelectSingleNode("//link[@itemprop='video']");
|
||||
if (linkTag != null)
|
||||
{
|
||||
string value = linkTag.GetAttributeValue("value", "");
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
return NormalizeUrl(value);
|
||||
}
|
||||
|
||||
// Fallback до <iframe id="pre" src="...">
|
||||
var iframeTag = doc.DocumentNode.SelectSingleNode("//iframe[@id='pre']");
|
||||
if (iframeTag != null)
|
||||
{
|
||||
string src = iframeTag.GetAttributeValue("src", "");
|
||||
if (!string.IsNullOrEmpty(src))
|
||||
return NormalizeUrl(src);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_onLog?.Invoke($"UAKino page fallback error: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Витягнути news_id з URL контенту
|
||||
/// </summary>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user