twitch clips support added

This commit is contained in:
2024-03-03 03:14:07 +01:00
Unverified
parent 1a57a039aa
commit 2d666ede27
46 changed files with 639 additions and 46 deletions

View File

@@ -0,0 +1,15 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VDownload.Sources.Twitch.Api.GQL.GetClipToken.Request
{
public class GetClipTokenExtensions
{
[JsonProperty("persistedQuery")]
public GetClipTokenPersistedQuery PersistedQuery { get; set; }
}
}

View File

@@ -0,0 +1,18 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VDownload.Sources.Twitch.Api.GQL.GetClipToken.Request
{
public class GetClipTokenPersistedQuery
{
[JsonProperty("version")]
public int Version { get; set; }
[JsonProperty("sha256Hash")]
public string Sha256Hash { get; set; }
}
}

View File

@@ -0,0 +1,21 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VDownload.Sources.Twitch.Api.GQL.GetClipToken.Request
{
public class GetClipTokenRequest
{
[JsonProperty("operationName")]
public string OperationName { get; set; }
[JsonProperty("variables")]
public GetClipTokenVariables Variables { get; set; }
[JsonProperty("extensions")]
public GetClipTokenExtensions Extensions { get; set; }
}
}

View File

@@ -0,0 +1,15 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VDownload.Sources.Twitch.Api.GQL.GetClipToken.Request
{
public class GetClipTokenVariables
{
[JsonProperty("slug")]
public string Slug { get; set; }
}
}

View File

@@ -0,0 +1,24 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VDownload.Sources.Twitch.Api.GQL.GetClipToken.Response
{
public class GetClipTokenClip
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("playbackAccessToken")]
public GetClipTokenPlaybackAccessToken PlaybackAccessToken { get; set; }
[JsonProperty("videoQualities")]
public List<GetClipTokenVideoQuality> VideoQualities { get; set; }
[JsonProperty("__typename")]
public string Typename { get; set; }
}
}

View File

@@ -0,0 +1,16 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VDownload.Sources.Twitch.Configuration.Models;
namespace VDownload.Sources.Twitch.Api.GQL.GetClipToken.Response
{
public class GetClipTokenData
{
[JsonProperty("clip")]
public GetClipTokenClip Clip { get; set; }
}
}

View File

@@ -0,0 +1,21 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VDownload.Sources.Twitch.Api.GQL.GetClipToken.Response
{
public class GetClipTokenExtensions
{
[JsonProperty("durationMilliseconds")]
public int DurationMilliseconds { get; set; }
[JsonProperty("operationName")]
public string OperationName { get; set; }
[JsonProperty("requestID")]
public string RequestID { get; set; }
}
}

View File

@@ -0,0 +1,21 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VDownload.Sources.Twitch.Api.GQL.GetClipToken.Response
{
public class GetClipTokenPlaybackAccessToken
{
[JsonProperty("signature")]
public string Signature { get; set; }
[JsonProperty("value")]
public string Value { get; set; }
[JsonProperty("__typename")]
public string Typename { get; set; }
}
}

View File

@@ -0,0 +1,19 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VDownload.Sources.Twitch.Api.GQL.GetClipToken.Request;
namespace VDownload.Sources.Twitch.Api.GQL.GetClipToken.Response
{
public class GetClipTokenResponse
{
[JsonProperty("data")]
public GetClipTokenData Data { get; set; }
[JsonProperty("extensions")]
public Response.GetClipTokenExtensions Extensions { get; set; }
}
}

View File

@@ -0,0 +1,24 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VDownload.Sources.Twitch.Api.GQL.GetClipToken.Response
{
public class GetClipTokenVideoQuality
{
[JsonProperty("frameRate")]
public double FrameRate { get; set; }
[JsonProperty("quality")]
public string Quality { get; set; }
[JsonProperty("sourceURL")]
public string SourceURL { get; set; }
[JsonProperty("__typename")]
public string Typename { get; set; }
}
}

View File

@@ -4,7 +4,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VDownload.Sources.Twitch.Api.GQL.GetVideoToken.Request;
namespace VDownload.Sources.Twitch.Api.GQL.GetVideoToken.Response
{

View File

@@ -5,7 +5,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VDownload.Sources.Twitch.Api.GQL.GetVideoToken.Request
namespace VDownload.Sources.Twitch.Api.GQL.GetVideoToken.Response
{
public class GetVideoTokenVideoPlaybackAccessToken
{

View File

@@ -0,0 +1,63 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VDownload.Sources.Twitch.Api.Helix.GetClips.Response
{
public class Data
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("url")]
public string Url { get; set; }
[JsonProperty("embed_url")]
public string EmbedUrl { get; set; }
[JsonProperty("broadcaster_id")]
public string BroadcasterId { get; set; }
[JsonProperty("broadcaster_name")]
public string BroadcasterName { get; set; }
[JsonProperty("creator_id")]
public string CreatorId { get; set; }
[JsonProperty("creator_name")]
public string CreatorName { get; set; }
[JsonProperty("video_id")]
public string VideoId { get; set; }
[JsonProperty("game_id")]
public string GameId { get; set; }
[JsonProperty("language")]
public string Language { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("view_count")]
public long ViewCount { get; set; }
[JsonProperty("created_at")]
public DateTime CreatedAt { get; set; }
[JsonProperty("thumbnail_url")]
public string ThumbnailUrl { get; set; }
[JsonProperty("duration")]
public double Duration { get; set; }
[JsonProperty("vod_offset")]
public int VodOffset { get; set; }
[JsonProperty("is_featured")]
public bool IsFeatured { get; set; }
}
}

View File

@@ -0,0 +1,19 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VDownload.Sources.Twitch.Api.Helix.GetVideos.Response;
namespace VDownload.Sources.Twitch.Api.Helix.GetClips.Response
{
public class GetClipsResponse
{
[JsonProperty("data")]
public List<Data> Data { get; set; }
[JsonProperty("pagination")]
public Pagination Pagination { get; set; }
}
}

View File

@@ -0,0 +1,15 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VDownload.Sources.Twitch.Api.Helix.GetClips.Response
{
public class Pagination
{
[JsonProperty("cursor")]
public string Cursor { get; set; }
}
}

View File

@@ -1,8 +1,13 @@
using VDownload.Services.Data.Configuration;
using System.Diagnostics;
using VDownload.Services.Data.Configuration;
using VDownload.Services.Utility.HttpClient;
using VDownload.Sources.Twitch.Api.GQL.GetClipToken.Request;
using VDownload.Sources.Twitch.Api.GQL.GetClipToken.Response;
using VDownload.Sources.Twitch.Api.GQL.GetVideoToken.Response;
using VDownload.Sources.Twitch.Api.Helix.GetClips.Response;
using VDownload.Sources.Twitch.Api.Helix.GetUsers.Response;
using VDownload.Sources.Twitch.Api.Helix.GetVideos.Response;
using VDownload.Sources.Twitch.Configuration.Models;
using VDownload.Sources.Twitch.Search.Models.GetVideoToken.Request;
namespace VDownload.Sources.Twitch.Api
@@ -11,9 +16,11 @@ namespace VDownload.Sources.Twitch.Api
{
Task<string> AuthValidate(byte[] token);
Task<GetVideoTokenResponse> GQLGetVideoToken(string id);
Task<GetClipTokenResponse> GQLGetClipToken(string id);
Task<GetUsersResponse> HelixGetUser(string login, byte[] token);
Task<GetVideosResponse> HelixGetVideo(string id, byte[] token);
Task<GetVideosResponse> HelixGetUserVideos(string user_id, byte[] token, int count, string? cursor = null);
Task<GetClipsResponse> HelixGetClip(string id, byte[] token);
Task<string> UsherGetVideoPlaylist(string id, string videoToken, string videoTokenSignature);
}
@@ -99,6 +106,20 @@ namespace VDownload.Sources.Twitch.Api
return await _httpClientService.SendRequestAsync<GetVideosResponse>(request);
}
public async Task<GetClipsResponse> HelixGetClip(string id, byte[] token)
{
Token tokenData = new Token(_configurationService.Twitch.Api.Helix.TokenSchema, token);
HttpRequest request = new HttpRequest(HttpMethodType.GET, _configurationService.Twitch.Api.Helix.Endpoints.GetClips);
request.Query.Add("id", id);
request.Headers.Add("Authorization", tokenData.ToString());
request.Headers.Add("Client-Id", _configurationService.Twitch.Api.Helix.ClientId);
return await _httpClientService.SendRequestAsync<GetClipsResponse>(request);
}
public async Task<GetVideoTokenResponse> GQLGetVideoToken(string id)
{
GetVideoTokenRequest requestBody = new GetVideoTokenRequest
@@ -123,6 +144,36 @@ namespace VDownload.Sources.Twitch.Api
return await _httpClientService.SendRequestAsync<GetVideoTokenResponse>(request);
}
public async Task<GetClipTokenResponse> GQLGetClipToken(string id)
{
Gql config = _configurationService.Twitch.Api.Gql;
GetClipTokenRequest requestBody = new GetClipTokenRequest
{
OperationName = config.Queries.GetClipToken.OperationName,
Variables = new GetClipTokenVariables
{
Slug = id
},
Extensions = new GQL.GetClipToken.Request.GetClipTokenExtensions
{
PersistedQuery = new GetClipTokenPersistedQuery
{
Version = config.Queries.GetClipToken.PersistedQueryVersion,
Sha256Hash = config.Queries.GetClipToken.PersistedQueryHash,
}
}
};
HttpRequest request = new HttpRequest(HttpMethodType.POST, config.Endpoint)
{
Body = requestBody,
};
request.Headers.Add("Client-Id", config.ClientId);
return await _httpClientService.SendRequestAsync<GetClipTokenResponse>(request);
}
public async Task<string> UsherGetVideoPlaylist(string id, string videoToken, string videoTokenSignature)
{
string url = string.Format(_configurationService.Twitch.Api.Usher.Endpoints.GetVideoPlaylist, id);