using System.Text; using DotBased.Monads; namespace Manager.YouTube.Interpreter; public class JavaScriptEngineManager { private readonly PlayerEngineCollection _engines = []; public async Task> GetPlayerEngine(string playerUrl) { if (string.IsNullOrEmpty(playerUrl)) { return ResultError.Fail("player url is empty or null!"); } var version = GetScriptVersion(playerUrl); if (_engines.TryGetValue(version, out var engine)) { return engine; } var playerJsSourceResult = await DownloadPlayerScriptAsync(playerUrl); if (!playerJsSourceResult.IsSuccess) { return playerJsSourceResult.Error ?? ResultError.Fail("Download player script failed!"); } return new PlayerEngine(version, playerJsSourceResult.Value); } private static string GetScriptVersion(string relativePlayerUrl) { var split = relativePlayerUrl.Split('/', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); var v = split[2]; var lang = split[4]; return $"{v}-{lang}"; } private static async Task> DownloadPlayerScriptAsync(string relativeUrl, YouTubeClient? client = null) { var downloadRequest = new HttpRequestMessage(HttpMethod.Get, new Uri($"{NetworkService.Origin}/{relativeUrl}")); var downloadResponse = await NetworkService.DownloadBytesAsync(downloadRequest, client); if (!downloadResponse.IsSuccess) { return downloadResponse.Error ?? ResultError.Fail($"Failed to download script from url: {relativeUrl}"); } var playerJs = Encoding.UTF8.GetString(downloadResponse.Value.Data); if (string.IsNullOrWhiteSpace(playerJs)) { return ResultError.Fail("Script value is empty!"); } return playerJs; } }