private async Task <CourseExtraInfo> GetCourseExtraInfo(string productId, CancellationToken token) { HttpHelper httpHelper = new HttpHelper { AcceptHeader = AcceptHeader.JsonTextPlain, AcceptEncoding = string.Empty, ContentType = ContentType.AppJsonUtf8, Cookies = Cookies, Referrer = new Uri("https://" + Settings.Default.SiteHostName), UserAgent = _userAgent }; string graphQlRequest = GraphQlHelper.GetCourseExtraInfoRequest(productId); ResponseEx response = await httpHelper.SendRequest(HttpMethod.Post, new Uri("https://" + Settings.Default.SiteHostName + "/player/api/graphql"), graphQlRequest, Settings.Default.RetryOnRequestFailureCount, token); return(JsonConvert.DeserializeObject <CourseExtraInfo>(response.Content)); }
private async Task DownloadModule(Course course, string courseDirectory, int moduleCounter, Module module) { var moduleDirectory = CreateModuleDirectory(courseDirectory, moduleCounter, module.Title); var clipCounter = 0; string referrer = $"https://{Settings.Default.SiteHostName}/player?course={course.Id}&author={module.AuthorId}&name={module.ModuleId}&clip=0&mode=live"; HttpHelper httpHelper = new HttpHelper { AcceptEncoding = string.Empty, AcceptHeader = AcceptHeader.All, ContentType = ContentType.AppJsonUtf8, Cookies = Cookies, Referrer = new Uri(referrer), UserAgent = _userAgent }; string moduleInfoPayload = GraphQlHelper.GetModuleInfoRequest(course.Id); ResponseEx courseRpcResponse = await httpHelper.SendRequest(HttpMethod.Post, new Uri("https://" + Settings.Default.SiteHostName + "/player/api/graphql"), moduleInfoPayload, Settings.Default.RetryOnRequestFailureCount, _token); CourseRpcData courceRpcData = JsonConvert.DeserializeObject <CourseRpcData>(courseRpcResponse.Content); foreach (var clip in module.Clips) { ++clipCounter; var fileName = GetFullFileNameWithoutExtension(clipCounter, moduleDirectory, clip); if (!File.Exists($"{fileName}.{Settings.Default.ClipExtensionMp4}")) { httpHelper.Referrer = new Uri($"https://{Settings.Default.SiteHostName}/player?course={course.Id}&author={module.AuthorId}&name={module.ModuleId}&clip=0&mode=live"); string s = GraphQlHelper.GetClipsRequest(courceRpcData, module.Id.Split('|')[1], module.Id.Split('|')[2], clipCounter - 1); ResponseEx viewclipResponse = await httpHelper.SendRequest(HttpMethod.Post, new Uri("https://" + Settings.Default.SiteHostName + "/player/api/graphql"), s, Settings.Default.RetryOnRequestFailureCount, _token); if (viewclipResponse.Content == "Unauthorized") { throw new UnauthorizedException(Resources.CheckYourSubscription); } var clipData = JsonConvert.DeserializeObject <ClipData>(viewclipResponse.Content); if (course.HasTranscript) { string unformattedSubtitlesJson = await _subtitleService.DownloadAsync(httpHelper, clip.ClipId.ToString(), _token); Caption[] unformattedSubtitles = JsonConvert.DeserializeObject <Caption[]>(unformattedSubtitlesJson); if (unformattedSubtitles.Length > 0) { TimeSpan totalDurationTs = XmlConvert.ToTimeSpan(clip.Duration); IList <SrtRecord> formattedSubtitles = GetFormattedSubtitles(unformattedSubtitles, totalDurationTs); _subtitleService.Write($"{fileName}.{Settings.Default.SubtitilesExtensionMp4}", formattedSubtitles); } } await DownloadClip(clipData.Data.ViewClip.Urls[1].UrlUrl, fileName, clipCounter, course.Modules.Sum(m => m.Clips.Length)); } } }