diff --git a/TwitchDownloaderCore/ChatDownloader.cs b/TwitchDownloaderCore/ChatDownloader.cs index bd012188..05850f94 100644 --- a/TwitchDownloaderCore/ChatDownloader.cs +++ b/TwitchDownloaderCore/ChatDownloader.cs @@ -5,7 +5,6 @@ using System.Net.Http; using System.Net.Http.Json; using System.Text; -using System.Text.Json; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; @@ -37,10 +36,10 @@ private static async Task DownloadSection(double videoStart, double videoEnd, st //GQL only wants ints videoStart = Math.Floor(videoStart); double videoDuration = videoEnd - videoStart; - double latestMessage = videoStart; + double latestMessage = videoStart - 1; + bool isFirst = true; string cursor = ""; int errorCount = 0; - List alreadyAdded = new List(); while (latestMessage < videoEnd) { @@ -54,9 +53,16 @@ private static async Task DownloadSection(double videoStart, double videoEnd, st RequestUri = new Uri("https://gql.twitch.tv/gql"), Method = HttpMethod.Post }; - request.Headers.Add("Client-ID", "kimne78kx3ncx6brgo4mv6wki5h1ko"); + request.Headers.Add("Client-ID", "kd1unb4b3q4t58fwlpcbzcbnm76a8fp"); - request.Content = new StringContent("[{\"operationName\":\"VideoCommentsByOffsetOrCursor\",\"variables\":{\"videoID\":\"" + videoId + "\",\"contentOffsetSeconds\":" + (int)Math.Floor(latestMessage) + "},\"extensions\":{\"persistedQuery\":{\"version\":1,\"sha256Hash\":\"b70a3591ff0f4e0313d126c6a1502d79a1c02baebb288227c582044aa76adf6a\"}}}]", Encoding.UTF8, "application/json"); + if (isFirst) + { + request.Content = new StringContent("[{\"operationName\":\"VideoCommentsByOffsetOrCursor\",\"variables\":{\"videoID\":\"" + videoId + "\",\"contentOffsetSeconds\":" + videoStart + "},\"extensions\":{\"persistedQuery\":{\"version\":1,\"sha256Hash\":\"b70a3591ff0f4e0313d126c6a1502d79a1c02baebb288227c582044aa76adf6a\"}}}]", Encoding.UTF8, "application/json"); + } + else + { + request.Content = new StringContent("[{\"operationName\":\"VideoCommentsByOffsetOrCursor\",\"variables\":{\"videoID\":\"" + videoId + "\",\"cursor\":\"" + cursor + "\"},\"extensions\":{\"persistedQuery\":{\"version\":1,\"sha256Hash\":\"b70a3591ff0f4e0313d126c6a1502d79a1c02baebb288227c582044aa76adf6a\"}}}]", Encoding.UTF8, "application/json"); + } using (var httpResponse = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false)) { @@ -83,29 +89,28 @@ private static async Task DownloadSection(double videoStart, double videoEnd, st continue; } - bool addedComment = false; var convertedComments = ConvertComments(commentResponse[0].data.video); lock (commentLock) { foreach (var comment in convertedComments) { - if (latestMessage < videoEnd && comment.content_offset_seconds > videoStart && !alreadyAdded.Contains(comment._id)) - { - alreadyAdded.Add(comment._id); + if (latestMessage < videoEnd && comment.content_offset_seconds > videoStart) comments.Add(comment); - addedComment = true; - } - if (comment.content_offset_seconds > latestMessage) - latestMessage = comment.content_offset_seconds; + latestMessage = comment.content_offset_seconds; } } - - if (!addedComment) - latestMessage = Math.Min(Math.Floor(latestMessage) + 1, videoEnd); + if (!commentResponse[0].data.video.comments.pageInfo.hasNextPage) + break; + else + cursor = commentResponse[0].data.video.comments.edges.Last().cursor; int percent = (int)Math.Floor((latestMessage - videoStart) / videoDuration * 100); progress.Report(new ProgressReport() { ReportType = ReportType.Percent, Data = percent }); + + if (isFirst) + isFirst = false; + } } diff --git a/TwitchDownloaderCore/TwitchHelper.cs b/TwitchDownloaderCore/TwitchHelper.cs index d6683d01..88c4e3fa 100644 --- a/TwitchDownloaderCore/TwitchHelper.cs +++ b/TwitchDownloaderCore/TwitchHelper.cs @@ -102,7 +102,7 @@ public static async Task GetGqlVideos(string channelName Method = HttpMethod.Post, Content = new StringContent("{\"query\":\"query{user(login:\\\"" + channelName + "\\\"){videos(first: " + limit + "" + (cursor == "" ? "" : ",after:\\\"" + cursor + "\\\"") + ") { edges { node { title, id, lengthSeconds, previewThumbnailURL(height: 180, width: 320), createdAt, viewCount }, cursor }, pageInfo { hasNextPage, hasPreviousPage }, totalCount }}}\",\"variables\":{}}", Encoding.UTF8, "application/json") }; - request.Headers.Add("Client-ID", "kimne78kx3ncx6brgo4mv6wki5h1ko"); + request.Headers.Add("Client-ID", "kd1unb4b3q4t58fwlpcbzcbnm76a8fp"); using var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); response.EnsureSuccessStatusCode(); return await response.Content.ReadFromJsonAsync(); @@ -116,7 +116,7 @@ public static async Task GetGqlClips(string channelName, Method = HttpMethod.Post, Content = new StringContent("{\"query\":\"query{user(login:\\\"" + channelName + "\\\"){clips(first: " + limit + (cursor == "" ? "" : ", after: \\\"" + cursor + "\\\"") +", criteria: { period: " + period + " }) { edges { cursor, node { id, slug, title, createdAt, durationSeconds, thumbnailURL, viewCount } }, pageInfo { hasNextPage, hasPreviousPage } }}}\",\"variables\":{}}", Encoding.UTF8, "application/json") }; - request.Headers.Add("Client-ID", "kimne78kx3ncx6brgo4mv6wki5h1ko"); + request.Headers.Add("Client-ID", "kd1unb4b3q4t58fwlpcbzcbnm76a8fp"); using var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); response.EnsureSuccessStatusCode(); return await response.Content.ReadFromJsonAsync();