From 903be6b72588ab50e6fe7ffaa5b86acb79e64040 Mon Sep 17 00:00:00 2001 From: kirill Date: Tue, 8 Aug 2023 17:16:56 +0300 Subject: [PATCH 1/3] Media variants support --- src/JsonOption/MediaConverter.cs | 19 ++++++++++++++++++- src/Request/AdvancedSearch/MediaOption.cs | 8 +++++++- src/Response/RMedia/Media.cs | 1 + 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/JsonOption/MediaConverter.cs b/src/JsonOption/MediaConverter.cs index b210ed5..8607671 100644 --- a/src/JsonOption/MediaConverter.cs +++ b/src/JsonOption/MediaConverter.cs @@ -45,12 +45,29 @@ public override Media Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSe Width = TryGetProperty(elem, "width")?.GetInt32(), DurationMs = TryGetProperty(elem, "duration_ms")?.GetInt32(), PreviewImageUrl = TryGetProperty(elem, "preview_image_url")?.GetString(), - Url = TryGetProperty(elem, "url")?.GetString() + Url = TryGetProperty(elem, "url")?.GetString(), + Variants = GetMediaVariants(elem) }; + return media; } } + private MediaVariant[] GetMediaVariants(JsonElement mediaElement) + { + var mediaVariants = Array.Empty(); + + if(mediaElement.TryGetProperty("variants", out var variants)) + { + mediaVariants = JsonSerializer.Deserialize(variants.GetRawText(), new JsonSerializerOptions + { + PropertyNamingPolicy = new SnakeCaseNamingPolicy() + }); + } + + return mediaVariants; + } + public override void Write(Utf8JsonWriter writer, Media value, JsonSerializerOptions options) { throw new NotImplementedException(); diff --git a/src/Request/AdvancedSearch/MediaOption.cs b/src/Request/AdvancedSearch/MediaOption.cs index ec09cc5..5e12c6f 100644 --- a/src/Request/AdvancedSearch/MediaOption.cs +++ b/src/Request/AdvancedSearch/MediaOption.cs @@ -25,6 +25,12 @@ public enum MediaOption /// /// URL to the image of the content /// - Url + Url, + + /// + /// Each media object may have multiple display or playback variants, with different resolutions or formats. + /// For videos, each variant will also contain URLs to the video in each format. + /// + Variants } } diff --git a/src/Response/RMedia/Media.cs b/src/Response/RMedia/Media.cs index 38601e6..26e0ea3 100644 --- a/src/Response/RMedia/Media.cs +++ b/src/Response/RMedia/Media.cs @@ -10,5 +10,6 @@ public class Media public int? DurationMs { init; get; } public string PreviewImageUrl { init; get; } public string Url { init; get; } + public MediaVariant[] Variants { init; get; } } } From fe7168544b15324db549d855b4d94b9e59de2e2d Mon Sep 17 00:00:00 2001 From: kirill Date: Tue, 8 Aug 2023 17:21:01 +0300 Subject: [PATCH 2/3] media variant class --- src/Response/RMedia/MediaVariant.cs | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/Response/RMedia/MediaVariant.cs diff --git a/src/Response/RMedia/MediaVariant.cs b/src/Response/RMedia/MediaVariant.cs new file mode 100644 index 0000000..65444d0 --- /dev/null +++ b/src/Response/RMedia/MediaVariant.cs @@ -0,0 +1,9 @@ +namespace TwitterSharp.Response.RMedia +{ + public class MediaVariant + { + public int? BitRate { init; get; } + public string ContentType { init; get; } + public string Url { init; get; } + } +} \ No newline at end of file From 6f19ea8c2477bc545460597591bf9dab2d1715e8 Mon Sep 17 00:00:00 2001 From: kirill Date: Tue, 15 Aug 2023 13:34:41 +0300 Subject: [PATCH 3/3] media variants unit test --- test/TestMedia.cs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/test/TestMedia.cs b/test/TestMedia.cs index 2825189..41b225e 100644 --- a/test/TestMedia.cs +++ b/test/TestMedia.cs @@ -1,5 +1,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using System; +using System.Linq; using System.Threading.Tasks; using TwitterSharp.Client; using TwitterSharp.Request.AdvancedSearch; @@ -78,5 +79,31 @@ public async Task GetTweetWithMediaPreview() Assert.IsNotNull(a.Attachments.Media[0].PreviewImageUrl); Assert.AreEqual("https://pbs.twimg.com/ext_tw_video_thumb/1237543944570847233/pu/img/kRBUlSd7M7ju_QK1.jpg", a.Attachments.Media[0].PreviewImageUrl); } + + [TestMethod] + public async Task GetTweetWithVideoMediaVariants() + { + var client = new TwitterClient(Environment.GetEnvironmentVariable("TWITTER_TOKEN")); + var answer = await client.GetTweetsAsync(new[] { "1688848776612691968" }, new TweetSearchOptions + { + TweetOptions = new[] { TweetOption.Attachments }, + MediaOptions = new [] { MediaOption.Variants } + }); + Assert.IsTrue(answer.Length == 1); + var a = answer[0]; + Assert.IsNotNull(a.Attachments); + Assert.IsNotNull(a.Attachments.Media); + Assert.AreEqual(1, a.Attachments.Media.Length); + Assert.AreEqual("13_1688840150338428928", a.Attachments.Media[0].Key); + Assert.IsNotNull(a.Attachments.Media[0].Type); + Assert.AreEqual(MediaType.Video, a.Attachments.Media[0].Type); + Assert.IsNull(a.Attachments.Media[0].PreviewImageUrl); + + Assert.IsNotNull(a.Attachments.Media[0].Variants); + Assert.IsTrue(a.Attachments.Media[0].Variants.Length > 0); + Assert.IsTrue(a.Attachments.Media[0].Variants.Any(v => v.ContentType == "video/mp4")); + Assert.IsTrue(a.Attachments.Media[0].Variants.Any(v => v.BitRate.HasValue)); + Assert.IsTrue(a.Attachments.Media[0].Variants.All(v => string.IsNullOrWhiteSpace(v.Url) == false)); + } } }