From 84bd684013120341902068ec253452524e940bcc Mon Sep 17 00:00:00 2001 From: Scrub <72096833+ScrubN@users.noreply.github.com> Date: Sun, 11 Dec 2022 15:54:23 -0500 Subject: [PATCH] Add additional information to chat jsons (#440) * Add video/clip ID to json * Also store title and creation date in json * Add video length parameter * Put ChatRoot in namespace * Swap GQL and ChatRoot video class names * Add ChatRootInfo property for tracking chatroot version and creation date * Typo * I should think of all possible scenarios before committing * Make ChatRoot version not a string for easier parsing * Trim entries and index out of bounds protection, add int based constructor * Add ChatRootVersion.ToString() override * Move Gql responses to dedicated namespace, Move ChatRootInfo to dedicated class, add ChatRootVersion operators and methods * Remove string constructor due to complexity and unclear usage --- TwitchDownloaderCore/ChatDownloader.cs | 49 ++-- TwitchDownloaderCore/ChatRenderer.cs | 5 +- TwitchDownloaderCore/TwitchHelper.cs | 1 + .../TwitchObjects/ChatRoot.cs | 264 +++++++++--------- .../TwitchObjects/ChatRootInfo.cs | 98 +++++++ .../{ => Gql}/GqlCheerResponse.cs | 2 +- .../{ => Gql}/GqlClipResponse.cs | 2 +- .../{ => Gql}/GqlClipSearchResponse.cs | 2 +- .../{ => Gql}/GqlCommentResponse.cs | 2 +- .../{ => Gql}/GqlVideoResponse.cs | 7 +- .../{ => Gql}/GqlVideoSearchResponse.cs | 2 +- TwitchDownloaderWPF/PageChatDownload.xaml.cs | 4 +- TwitchDownloaderWPF/PageClipDownload.xaml.cs | 2 +- TwitchDownloaderWPF/PageVodDownload.xaml.cs | 2 +- .../WindowMassDownload.xaml.cs | 2 +- TwitchDownloaderWPF/WindowUrlList.xaml.cs | 2 +- 16 files changed, 277 insertions(+), 169 deletions(-) create mode 100644 TwitchDownloaderCore/TwitchObjects/ChatRootInfo.cs rename TwitchDownloaderCore/TwitchObjects/{ => Gql}/GqlCheerResponse.cs (95%) rename TwitchDownloaderCore/TwitchObjects/{ => Gql}/GqlClipResponse.cs (94%) rename TwitchDownloaderCore/TwitchObjects/{ => Gql}/GqlClipSearchResponse.cs (95%) rename TwitchDownloaderCore/TwitchObjects/{ => Gql}/GqlCommentResponse.cs (98%) rename TwitchDownloaderCore/TwitchObjects/{ => Gql}/GqlVideoResponse.cs (82%) rename TwitchDownloaderCore/TwitchObjects/{ => Gql}/GqlVideoSearchResponse.cs (96%) diff --git a/TwitchDownloaderCore/ChatDownloader.cs b/TwitchDownloaderCore/ChatDownloader.cs index c941cb19..238913de 100644 --- a/TwitchDownloaderCore/ChatDownloader.cs +++ b/TwitchDownloaderCore/ChatDownloader.cs @@ -1,7 +1,4 @@ -using NeoSmart.Unicode; using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using SkiaSharp; using System; using System.Collections.Generic; using System.IO; @@ -13,6 +10,7 @@ using System.Web; using TwitchDownloaderCore.Options; using TwitchDownloaderCore.TwitchObjects; +using TwitchDownloaderCore.TwitchObjects.Gql; namespace TwitchDownloaderCore { @@ -235,47 +233,60 @@ private List ConvertComments(CommentVideo video) public async Task DownloadAsync(IProgress progress, CancellationToken cancellationToken) { - DownloadType downloadType = downloadOptions.Id.All(x => Char.IsDigit(x)) ? DownloadType.Video : DownloadType.Clip; - string videoId = ""; + DownloadType downloadType = downloadOptions.Id.All(x => char.IsDigit(x)) ? DownloadType.Video : DownloadType.Clip; List comments = new List(); - ChatRoot chatRoot = new ChatRoot() { streamer = new Streamer(), video = new VideoTime(), comments = comments }; + ChatRoot chatRoot = new ChatRoot() { FileInfo = new ChatRootInfo() { Version = new ChatRootVersion(1, 1, 0) }, streamer = new Streamer(), video = new Video(), comments = comments }; + string videoId = ""; + string videoTitle = ""; + DateTime videoCreatedAt; double videoStart = 0.0; double videoEnd = 0.0; double videoDuration = 0.0; + double videoTotalLength; int connectionCount = downloadOptions.ConnectionCount; if (downloadType == DownloadType.Video) { videoId = downloadOptions.Id; - GqlVideoResponse taskInfo = await TwitchHelper.GetVideoInfo(Int32.Parse(videoId)); - chatRoot.streamer.name = taskInfo.data.video.owner.displayName; - chatRoot.streamer.id = int.Parse(taskInfo.data.video.owner.id); + GqlVideoResponse taskVideoInfo = await TwitchHelper.GetVideoInfo(int.Parse(videoId)); + chatRoot.streamer.name = taskVideoInfo.data.video.owner.displayName; + chatRoot.streamer.id = int.Parse(taskVideoInfo.data.video.owner.id); + videoTitle = taskVideoInfo.data.video.title; + videoCreatedAt = taskVideoInfo.data.video.createdAt; videoStart = downloadOptions.CropBeginning ? downloadOptions.CropBeginningTime : 0.0; - videoEnd = downloadOptions.CropEnding ? downloadOptions.CropEndingTime : taskInfo.data.video.lengthSeconds; + videoEnd = downloadOptions.CropEnding ? downloadOptions.CropEndingTime : taskVideoInfo.data.video.lengthSeconds; + videoTotalLength = taskVideoInfo.data.video.lengthSeconds; } else { - GqlClipResponse taskInfo = await TwitchHelper.GetClipInfo(downloadOptions.Id); + GqlClipResponse taskClipInfo = await TwitchHelper.GetClipInfo(downloadOptions.Id); - if (taskInfo.data.clip.video == null || taskInfo.data.clip.videoOffsetSeconds == null) + if (taskClipInfo.data.clip.video == null || taskClipInfo.data.clip.videoOffsetSeconds == null) throw new Exception("Invalid VOD for clip, deleted/expired VOD possibly?"); - videoId = taskInfo.data.clip.video.id; + videoId = taskClipInfo.data.clip.video.id; downloadOptions.CropBeginning = true; - downloadOptions.CropBeginningTime = (int)taskInfo.data.clip.videoOffsetSeconds; + downloadOptions.CropBeginningTime = (int)taskClipInfo.data.clip.videoOffsetSeconds; downloadOptions.CropEnding = true; - downloadOptions.CropEndingTime = downloadOptions.CropBeginningTime + taskInfo.data.clip.durationSeconds; - chatRoot.streamer.name = taskInfo.data.clip.broadcaster.displayName; - chatRoot.streamer.id = int.Parse(taskInfo.data.clip.broadcaster.id); - videoStart = (int)taskInfo.data.clip.videoOffsetSeconds; - videoEnd = (int)taskInfo.data.clip.videoOffsetSeconds + taskInfo.data.clip.durationSeconds; + downloadOptions.CropEndingTime = downloadOptions.CropBeginningTime + taskClipInfo.data.clip.durationSeconds; + chatRoot.streamer.name = taskClipInfo.data.clip.broadcaster.displayName; + chatRoot.streamer.id = int.Parse(taskClipInfo.data.clip.broadcaster.id); + videoTitle = taskClipInfo.data.clip.title; + videoCreatedAt = taskClipInfo.data.clip.createdAt; + videoStart = (int)taskClipInfo.data.clip.videoOffsetSeconds; + videoEnd = (int)taskClipInfo.data.clip.videoOffsetSeconds + taskClipInfo.data.clip.durationSeconds; + videoTotalLength = taskClipInfo.data.clip.durationSeconds; connectionCount = 1; } + chatRoot.video.title = videoTitle; + chatRoot.video.id = videoId; + chatRoot.video.created_at = videoCreatedAt; chatRoot.video.start = videoStart; chatRoot.video.end = videoEnd; + chatRoot.video.length = videoTotalLength; videoDuration = videoEnd - videoStart; SortedSet commentsSet = new SortedSet(new SortedCommentComparer()); diff --git a/TwitchDownloaderCore/ChatRenderer.cs b/TwitchDownloaderCore/ChatRenderer.cs index 7eed7697..063acb40 100644 --- a/TwitchDownloaderCore/ChatRenderer.cs +++ b/TwitchDownloaderCore/ChatRenderer.cs @@ -1100,10 +1100,7 @@ public static async Task ParseJsonStatic(string inputJson) if (jsonDocument.RootElement.TryGetProperty("video", out JsonElement videoJson)) { - if (videoJson.TryGetProperty("start", out JsonElement videoStartJson) && videoJson.TryGetProperty("end", out JsonElement videoEndJson)) - { - chatRoot.video = videoJson.Deserialize(); - } + chatRoot.video = videoJson.Deserialize