1
0
Fork 0
mirror of https://codeberg.org/ashley/poke.git synced 2025-06-24 04:47:02 -04:00
This commit is contained in:
Ashley 2022-08-05 22:33:38 +03:00 committed by GitHub
parent f431111611
commit 72143fede3
100 changed files with 12438 additions and 0 deletions

View file

@ -0,0 +1,380 @@
using System;
using System.Xml;
using System.Xml.Linq;
namespace InnerTube.Models
{
public class DynamicItem
{
public string Id;
public string Title;
public Thumbnail[] Thumbnails;
public virtual XmlElement GetXmlElement(XmlDocument doc)
{
XmlElement item = doc.CreateElement("DynamicItem");
item.SetAttribute("id", Id);
XmlElement title = doc.CreateElement("Title");
title.InnerText = Title;
item.AppendChild(title);
foreach (Thumbnail t in Thumbnails ?? Array.Empty<Thumbnail>())
{
XmlElement thumbnail = doc.CreateElement("Thumbnail");
thumbnail.SetAttribute("width", t.Width.ToString());
thumbnail.SetAttribute("height", t.Height.ToString());
thumbnail.InnerText = t.Url;
item.AppendChild(thumbnail);
}
return item;
}
}
public class VideoItem : DynamicItem
{
public string UploadedAt;
public long Views;
public Channel Channel;
public string Duration;
public string Description;
public override XmlElement GetXmlElement(XmlDocument doc)
{
XmlElement item = doc.CreateElement("Video");
item.SetAttribute("id", Id);
item.SetAttribute("duration", Duration);
item.SetAttribute("views", Views.ToString());
item.SetAttribute("uploadedAt", UploadedAt);
XmlElement title = doc.CreateElement("Title");
title.InnerText = Title;
item.AppendChild(title);
if (Channel is not null)
item.AppendChild(Channel.GetXmlElement(doc));
foreach (Thumbnail t in Thumbnails ?? Array.Empty<Thumbnail>())
{
XmlElement thumbnail = doc.CreateElement("Thumbnail");
thumbnail.SetAttribute("width", t.Width.ToString());
thumbnail.SetAttribute("height", t.Height.ToString());
thumbnail.InnerText = t.Url;
item.AppendChild(thumbnail);
}
if (!string.IsNullOrWhiteSpace(Description))
{
XmlElement description = doc.CreateElement("Description");
description.InnerText = Description;
item.AppendChild(description);
}
return item;
}
}
public class PlaylistItem : DynamicItem
{
public int VideoCount;
public string FirstVideoId;
public Channel Channel;
public override XmlElement GetXmlElement(XmlDocument doc)
{
XmlElement item = doc.CreateElement("Playlist");
item.SetAttribute("id", Id);
item.SetAttribute("videoCount", VideoCount.ToString());
item.SetAttribute("firstVideoId", FirstVideoId);
XmlElement title = doc.CreateElement("Title");
title.InnerText = Title;
item.AppendChild(title);
item.AppendChild(Channel.GetXmlElement(doc));
foreach (Thumbnail t in Thumbnails ?? Array.Empty<Thumbnail>())
{
XmlElement thumbnail = doc.CreateElement("Thumbnail");
thumbnail.SetAttribute("width", t.Width.ToString());
thumbnail.SetAttribute("height", t.Height.ToString());
thumbnail.InnerText = t.Url;
item.AppendChild(thumbnail);
}
return item;
}
}
public class RadioItem : DynamicItem
{
public string FirstVideoId;
public Channel Channel;
public override XmlElement GetXmlElement(XmlDocument doc)
{
XmlElement item = doc.CreateElement("Radio");
item.SetAttribute("id", Id);
item.SetAttribute("firstVideoId", FirstVideoId);
XmlElement title = doc.CreateElement("Title");
title.InnerText = Title;
item.AppendChild(title);
item.AppendChild(Channel.GetXmlElement(doc));
foreach (Thumbnail t in Thumbnails ?? Array.Empty<Thumbnail>())
{
XmlElement thumbnail = doc.CreateElement("Thumbnail");
thumbnail.SetAttribute("width", t.Width.ToString());
thumbnail.SetAttribute("height", t.Height.ToString());
thumbnail.InnerText = t.Url;
item.AppendChild(thumbnail);
}
return item;
}
}
public class ChannelItem : DynamicItem
{
public string Url;
public string Description;
public long VideoCount;
public string Subscribers;
public override XmlElement GetXmlElement(XmlDocument doc)
{
XmlElement item = doc.CreateElement("Channel");
item.SetAttribute("id", Id);
item.SetAttribute("videoCount", VideoCount.ToString());
item.SetAttribute("subscribers", Subscribers);
if (!string.IsNullOrWhiteSpace(Url))
item.SetAttribute("customUrl", Url);
XmlElement title = doc.CreateElement("Name");
title.InnerText = Title;
item.AppendChild(title);
XmlElement description = doc.CreateElement("Description");
description.InnerText = Description;
item.AppendChild(description);
foreach (Thumbnail t in Thumbnails ?? Array.Empty<Thumbnail>())
{
XmlElement thumbnail = doc.CreateElement("Avatar");
thumbnail.SetAttribute("width", t.Width.ToString());
thumbnail.SetAttribute("height", t.Height.ToString());
thumbnail.InnerText = t.Url;
item.AppendChild(thumbnail);
}
return item;
}
}
public class ContinuationItem : DynamicItem
{
public override XmlElement GetXmlElement(XmlDocument doc)
{
XmlElement item = doc.CreateElement("Continuation");
item.SetAttribute("key", Id);
return item;
}
}
public class ShelfItem : DynamicItem
{
public DynamicItem[] Items;
public int CollapsedItemCount;
public BadgeItem[] Badges;
public override XmlElement GetXmlElement(XmlDocument doc)
{
XmlElement item = doc.CreateElement("Shelf");
item.SetAttribute("title", Title);
item.SetAttribute("collapsedItemCount", CollapsedItemCount.ToString());
foreach (Thumbnail t in Thumbnails ?? Array.Empty<Thumbnail>())
{
XmlElement thumbnail = doc.CreateElement("Thumbnail");
thumbnail.SetAttribute("width", t.Width.ToString());
thumbnail.SetAttribute("height", t.Height.ToString());
thumbnail.InnerText = t.Url;
item.AppendChild(thumbnail);
}
if (Badges.Length > 0)
{
XmlElement badges = doc.CreateElement("Badges");
foreach (BadgeItem badge in Badges) badges.AppendChild(badge.GetXmlElement(doc));
item.AppendChild(badges);
}
XmlElement items = doc.CreateElement("Items");
foreach (DynamicItem dynamicItem in Items) items.AppendChild(dynamicItem.GetXmlElement(doc));
item.AppendChild(items);
return item;
}
}
public class HorizontalCardListItem : DynamicItem
{
public DynamicItem[] Items;
public override XmlElement GetXmlElement(XmlDocument doc)
{
XmlElement item = doc.CreateElement("CardList");
item.SetAttribute("title", Title);
foreach (DynamicItem dynamicItem in Items) item.AppendChild(dynamicItem.GetXmlElement(doc));
return item;
}
}
public class CardItem : DynamicItem
{
public override XmlElement GetXmlElement(XmlDocument doc)
{
XmlElement item = doc.CreateElement("Card");
item.SetAttribute("title", Title);
foreach (Thumbnail t in Thumbnails ?? Array.Empty<Thumbnail>())
{
XmlElement thumbnail = doc.CreateElement("Thumbnail");
thumbnail.SetAttribute("width", t.Width.ToString());
thumbnail.SetAttribute("height", t.Height.ToString());
thumbnail.InnerText = t.Url;
item.AppendChild(thumbnail);
}
return item;
}
}
public class PlaylistVideoItem : DynamicItem
{
public long Index;
public Channel Channel;
public string Duration;
public override XmlElement GetXmlElement(XmlDocument doc)
{
XmlElement item = doc.CreateElement("Video");
item.SetAttribute("id", Id);
item.SetAttribute("index", Index.ToString());
item.SetAttribute("duration", Duration);
XmlElement title = doc.CreateElement("Title");
title.InnerText = Title;
item.AppendChild(title);
item.AppendChild(Channel.GetXmlElement(doc));
foreach (Thumbnail t in Thumbnails ?? Array.Empty<Thumbnail>())
{
XmlElement thumbnail = doc.CreateElement("Thumbnail");
thumbnail.SetAttribute("width", t.Width.ToString());
thumbnail.SetAttribute("height", t.Height.ToString());
thumbnail.InnerText = t.Url;
item.AppendChild(thumbnail);
}
return item;
}
}
public class ItemSectionItem : DynamicItem
{
public DynamicItem[] Contents;
public override XmlElement GetXmlElement(XmlDocument doc)
{
XmlElement section = doc.CreateElement("ItemSection");
foreach (DynamicItem item in Contents) section.AppendChild(item.GetXmlElement(doc));
return section;
}
}
public class MessageItem : DynamicItem
{
public override XmlElement GetXmlElement(XmlDocument doc)
{
XmlElement message = doc.CreateElement("Message");
message.InnerText = Title;
return message;
}
}
public class ChannelAboutItem : DynamicItem
{
public string Description;
public string Country;
public string Joined;
public string ViewCount;
public override XmlElement GetXmlElement(XmlDocument doc)
{
XmlElement about = doc.CreateElement("About");
XmlElement description = doc.CreateElement("Description");
description.InnerText = Description;
about.AppendChild(description);
XmlElement country = doc.CreateElement("Location");
country.InnerText = Country;
about.AppendChild(country);
XmlElement joined = doc.CreateElement("Joined");
joined.InnerText = Joined;
about.AppendChild(joined);
XmlElement viewCount = doc.CreateElement("ViewCount");
viewCount.InnerText = ViewCount;
about.AppendChild(viewCount);
return about;
}
}
public class BadgeItem : DynamicItem
{
public string Style;
public override XmlElement GetXmlElement(XmlDocument doc)
{
XmlElement badge = doc.CreateElement("Badge");
badge.SetAttribute("style", Style);
badge.InnerText = Title;
return badge;
}
}
public class StationItem : DynamicItem
{
public int VideoCount;
public string FirstVideoId;
public string Description;
public override XmlElement GetXmlElement(XmlDocument doc)
{
XmlElement item = doc.CreateElement("Station");
item.SetAttribute("id", Id);
item.SetAttribute("videoCount", VideoCount.ToString());
item.SetAttribute("firstVideoId", FirstVideoId);
XmlElement title = doc.CreateElement("Title");
title.InnerText = Title;
item.AppendChild(title);
XmlElement description = doc.CreateElement("Description");
description.InnerText = Description;
item.AppendChild(description);
foreach (Thumbnail t in Thumbnails ?? Array.Empty<Thumbnail>())
{
XmlElement thumbnail = doc.CreateElement("Thumbnail");
thumbnail.SetAttribute("width", t.Width.ToString());
thumbnail.SetAttribute("height", t.Height.ToString());
thumbnail.InnerText = t.Url;
item.AppendChild(thumbnail);
}
return item;
}
}
}

View file

@ -0,0 +1,67 @@
using System.Collections.Generic;
using Newtonsoft.Json;
namespace InnerTube.Models
{
public class RequestContext
{
[JsonProperty("context")] public Context Context;
public static string BuildRequestContextJson(Dictionary<string, object> additionalFields, string language = "en",
string region = "US", string clientName = "WEB", string clientVersion = "2.20220224.07.00")
{
RequestContext ctx = new()
{
Context = new Context(
new RequestClient(language, region, clientName, clientVersion),
new RequestUser(false))
};
string json1 = JsonConvert.SerializeObject(ctx);
Dictionary<string, object> json2 = JsonConvert.DeserializeObject<Dictionary<string, object>>(json1);
foreach (KeyValuePair<string,object> pair in additionalFields) json2.Add(pair.Key, pair.Value);
return JsonConvert.SerializeObject(json2);
}
}
public class Context
{
[JsonProperty("client")] public RequestClient RequestClient { get; set; }
[JsonProperty("user")] public RequestUser RequestUser { get; set; }
public Context(RequestClient requestClient, RequestUser requestUser)
{
RequestClient = requestClient;
RequestUser = requestUser;
}
}
public class RequestClient
{
[JsonProperty("hl")] public string Language { get; set; }
[JsonProperty("gl")] public string Region { get; set; }
[JsonProperty("clientName")] public string ClientName { get; set; }
[JsonProperty("clientVersion")] public string ClientVersion { get; set; }
[JsonProperty("deviceModel")] public string DeviceModel { get; set; }
public RequestClient(string language, string region, string clientName, string clientVersion)
{
Language = language;
Region = region;
ClientName = clientName;
ClientVersion = clientVersion;
if (clientName == "IOS") DeviceModel = "iPhone14,3";
}
}
public class RequestUser
{
[JsonProperty("lockedSafetyMode")] public bool LockedSafetyMode { get; set; }
public RequestUser(bool lockedSafetyMode)
{
LockedSafetyMode = lockedSafetyMode;
}
}
}

View file

@ -0,0 +1,71 @@
using System.Xml;
namespace InnerTube.Models
{
public class YoutubeChannel
{
public string Id;
public string Name;
public string Url;
public Thumbnail[] Avatars;
public Thumbnail[] Banners;
public string Description;
public DynamicItem[] Videos;
public string Subscribers;
public string GetHtmlDescription()
{
return Utils.GetHtmlDescription(Description);
}
public XmlDocument GetXmlDocument()
{
XmlDocument doc = new();
XmlElement channel = doc.CreateElement("Channel");
channel.SetAttribute("id", Id);
if (Id != Url)
channel.SetAttribute("customUrl", Url);
XmlElement metadata = doc.CreateElement("Metadata");
XmlElement name = doc.CreateElement("Name");
name.InnerText = Name;
metadata.AppendChild(name);
XmlElement avatars = doc.CreateElement("Avatars");
foreach (Thumbnail t in Avatars)
{
XmlElement thumbnail = doc.CreateElement("Thumbnail");
thumbnail.SetAttribute("width", t.Width.ToString());
thumbnail.SetAttribute("height", t.Height.ToString());
thumbnail.InnerText = t.Url;
avatars.AppendChild(thumbnail);
}
metadata.AppendChild(avatars);
XmlElement banners = doc.CreateElement("Banners");
foreach (Thumbnail t in Banners)
{
XmlElement thumbnail = doc.CreateElement("Thumbnail");
thumbnail.SetAttribute("width", t.Width.ToString());
thumbnail.SetAttribute("height", t.Height.ToString());
thumbnail.InnerText = t.Url;
banners.AppendChild(thumbnail);
}
metadata.AppendChild(banners);
XmlElement subscriberCount = doc.CreateElement("Subscribers");
subscriberCount.InnerText = Subscribers;
metadata.AppendChild(subscriberCount);
channel.AppendChild(metadata);
XmlElement contents = doc.CreateElement("Contents");
foreach (DynamicItem item in Videos) contents.AppendChild(item.GetXmlElement(doc));
channel.AppendChild(contents);
doc.AppendChild(channel);
return doc;
}
}
}

View file

@ -0,0 +1,40 @@
using System.Collections.Generic;
using System.Xml;
namespace InnerTube.Models
{
public class YoutubeLocals
{
public Dictionary<string, string> Languages { get; set; }
public Dictionary<string, string> Regions { get; set; }
public XmlDocument GetXmlDocument()
{
XmlDocument doc = new();
XmlElement locals = doc.CreateElement("Locals");
XmlElement languages = doc.CreateElement("Languages");
foreach (KeyValuePair<string, string> l in Languages)
{
XmlElement language = doc.CreateElement("Language");
language.SetAttribute("hl", l.Key);
language.InnerText = l.Value;
languages.AppendChild(language);
}
locals.AppendChild(languages);
XmlElement regions = doc.CreateElement("Regions");
foreach (KeyValuePair<string, string> r in Regions)
{
XmlElement region = doc.CreateElement("Region");
region.SetAttribute("gl", r.Key);
region.InnerText = r.Value;
regions.AppendChild(region);
}
locals.AppendChild(regions);
doc.AppendChild(locals);
return doc;
}
}
}

View file

@ -0,0 +1,230 @@
using System;
using System.Xml;
using Newtonsoft.Json;
namespace InnerTube.Models
{
public class YoutubePlayer
{
public string Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string[] Tags { get; set; }
public Channel Channel { get; set; }
public long? Duration { get; set; }
public bool IsLive { get; set; }
public Chapter[] Chapters { get; set; }
public Thumbnail[] Thumbnails { get; set; }
public Format[] Formats { get; set; }
public Format[] AdaptiveFormats { get; set; }
public string HlsManifestUrl { get; set; }
public Subtitle[] Subtitles { get; set; }
public string[] Storyboards { get; set; }
public string ExpiresInSeconds { get; set; }
public string ErrorMessage { get; set; }
public string GetHtmlDescription()
{
return Utils.GetHtmlDescription(Description);
}
public XmlDocument GetXmlDocument()
{
XmlDocument doc = new();
if (!string.IsNullOrWhiteSpace(ErrorMessage))
{
XmlElement error = doc.CreateElement("Error");
error.InnerText = ErrorMessage;
doc.AppendChild(error);
}
else
{
XmlElement player = doc.CreateElement("Player");
player.SetAttribute("id", Id);
player.SetAttribute("duration", Duration.ToString());
player.SetAttribute("isLive", IsLive.ToString());
player.SetAttribute("expiresInSeconds", ExpiresInSeconds);
XmlElement title = doc.CreateElement("Title");
title.InnerText = Title;
player.AppendChild(title);
XmlElement description = doc.CreateElement("Description");
description.InnerText = Description;
player.AppendChild(description);
XmlElement tags = doc.CreateElement("Tags");
foreach (string tag in Tags ?? Array.Empty<string>())
{
XmlElement tagElement = doc.CreateElement("Tag");
tagElement.InnerText = tag;
tags.AppendChild(tagElement);
}
player.AppendChild(tags);
player.AppendChild(Channel.GetXmlElement(doc));
XmlElement thumbnails = doc.CreateElement("Thumbnails");
foreach (Thumbnail t in Thumbnails)
{
XmlElement thumbnail = doc.CreateElement("Thumbnail");
thumbnail.SetAttribute("width", t.Width.ToString());
thumbnail.SetAttribute("height", t.Height.ToString());
thumbnail.InnerText = t.Url;
thumbnails.AppendChild(thumbnail);
}
player.AppendChild(thumbnails);
XmlElement formats = doc.CreateElement("Formats");
foreach (Format f in Formats ?? Array.Empty<Format>()) formats.AppendChild(f.GetXmlElement(doc));
player.AppendChild(formats);
XmlElement adaptiveFormats = doc.CreateElement("AdaptiveFormats");
foreach (Format f in AdaptiveFormats ?? Array.Empty<Format>()) adaptiveFormats.AppendChild(f.GetXmlElement(doc));
player.AppendChild(adaptiveFormats);
XmlElement storyboards = doc.CreateElement("Storyboards");
foreach (string s in Storyboards)
{
XmlElement storyboard = doc.CreateElement("Storyboard");
storyboard.InnerText = s;
storyboards.AppendChild(storyboard);
}
player.AppendChild(storyboards);
XmlElement subtitles = doc.CreateElement("Subtitles");
foreach (Subtitle s in Subtitles ?? Array.Empty<Subtitle>()) subtitles.AppendChild(s.GetXmlElement(doc));
player.AppendChild(subtitles);
doc.AppendChild(player);
}
return doc;
}
}
public class Chapter
{
[JsonProperty("title")] public string Title { get; set; }
[JsonProperty("start_time")] public long StartTime { get; set; }
[JsonProperty("end_time")] public long EndTime { get; set; }
}
public class Format
{
[JsonProperty("format")] public string FormatName { get; set; }
[JsonProperty("format_id")] public string FormatId { get; set; }
[JsonProperty("format_note")] public string FormatNote { get; set; }
[JsonProperty("filesize")] public long? Filesize { get; set; }
[JsonProperty("quality")] public long Quality { get; set; }
[JsonProperty("bitrate")] public double Bitrate { get; set; }
[JsonProperty("audio_codec")] public string AudioCodec { get; set; }
[JsonProperty("video_codec")] public string VideoCodec { get; set; }
[JsonProperty("audio_sample_rate")] public long? AudioSampleRate { get; set; }
[JsonProperty("resolution")] public string Resolution { get; set; }
[JsonProperty("url")] public string Url { get; set; }
[JsonProperty("init_range")] public Range InitRange { get; set; }
[JsonProperty("index_range")] public Range IndexRange { get; set; }
public XmlElement GetXmlElement(XmlDocument doc)
{
XmlElement format = doc.CreateElement("Format");
format.SetAttribute("id", FormatId);
format.SetAttribute("label", FormatName);
format.SetAttribute("filesize", Filesize.ToString());
format.SetAttribute("quality", Bitrate.ToString());
format.SetAttribute("audioCodec", AudioCodec);
format.SetAttribute("videoCodec", VideoCodec);
if (AudioSampleRate != null)
format.SetAttribute("audioSampleRate", AudioSampleRate.ToString());
else
format.SetAttribute("resolution", Resolution);
XmlElement url = doc.CreateElement("URL");
url.InnerText = Url;
format.AppendChild(url);
if (InitRange != null && IndexRange != null)
{
XmlElement initRange = doc.CreateElement("InitRange");
initRange.SetAttribute("start", InitRange.Start);
initRange.SetAttribute("end", InitRange.End);
format.AppendChild(initRange);
XmlElement indexRange = doc.CreateElement("IndexRange");
indexRange.SetAttribute("start", IndexRange.Start);
indexRange.SetAttribute("end", IndexRange.End);
format.AppendChild(indexRange);
}
return format;
}
}
public class Range
{
[JsonProperty("start")] public string Start { get; set; }
[JsonProperty("end")] public string End { get; set; }
public Range(string start, string end)
{
Start = start;
End = end;
}
}
public class Channel
{
[JsonProperty("name")] public string Name { get; set; }
[JsonProperty("id")] public string Id { get; set; }
[JsonProperty("subscriberCount")] public string SubscriberCount { get; set; }
[JsonProperty("avatars")] public Thumbnail[] Avatars { get; set; }
public XmlElement GetXmlElement(XmlDocument doc)
{
XmlElement channel = doc.CreateElement("Channel");
channel.SetAttribute("id", Id);
if (!string.IsNullOrWhiteSpace(SubscriberCount))
channel.SetAttribute("subscriberCount", SubscriberCount);
XmlElement name = doc.CreateElement("Name");
name.InnerText = Name;
channel.AppendChild(name);
foreach (Thumbnail avatarThumb in Avatars ?? Array.Empty<Thumbnail>())
{
XmlElement avatar = doc.CreateElement("Avatar");
avatar.SetAttribute("width", avatarThumb.Width.ToString());
avatar.SetAttribute("height", avatarThumb.Height.ToString());
avatar.InnerText = avatarThumb.Url;
channel.AppendChild(avatar);
}
return channel;
}
}
public class Subtitle
{
[JsonProperty("ext")] public string Ext { get; set; }
[JsonProperty("name")] public string Language { get; set; }
[JsonProperty("url")] public string Url { get; set; }
public XmlElement GetXmlElement(XmlDocument doc)
{
XmlElement subtitle = doc.CreateElement("Subtitle");
subtitle.SetAttribute("ext", Ext);
subtitle.SetAttribute("language", Language);
subtitle.InnerText = Url;
return subtitle;
}
}
public class Thumbnail
{
[JsonProperty("height")] public long Height { get; set; }
[JsonProperty("url")] public string Url { get; set; }
[JsonProperty("width")] public long Width { get; set; }
}
}

View file

@ -0,0 +1,68 @@
using System.Xml;
namespace InnerTube.Models
{
public class YoutubePlaylist
{
public string Id;
public string Title;
public string Description;
public string VideoCount;
public string ViewCount;
public string LastUpdated;
public Thumbnail[] Thumbnail;
public Channel Channel;
public DynamicItem[] Videos;
public string ContinuationKey;
public string GetHtmlDescription() => Utils.GetHtmlDescription(Description);
public XmlDocument GetXmlDocument()
{
XmlDocument doc = new();
XmlElement playlist = doc.CreateElement("Playlist");
playlist.SetAttribute("id", Id);
playlist.SetAttribute("continuation", ContinuationKey);
XmlElement metadata = doc.CreateElement("Metadata");
XmlElement title = doc.CreateElement("Title");
title.InnerText = Title;
metadata.AppendChild(title);
metadata.AppendChild(Channel.GetXmlElement(doc));
XmlElement thumbnails = doc.CreateElement("Thumbnails");
foreach (Thumbnail t in Thumbnail)
{
XmlElement thumbnail = doc.CreateElement("Thumbnail");
thumbnail.SetAttribute("width", t.Width.ToString());
thumbnail.SetAttribute("height", t.Height.ToString());
thumbnail.InnerText = t.Url;
thumbnails.AppendChild(thumbnail);
}
metadata.AppendChild(thumbnails);
XmlElement videoCount = doc.CreateElement("VideoCount");
XmlElement viewCount = doc.CreateElement("ViewCount");
XmlElement lastUpdated = doc.CreateElement("LastUpdated");
videoCount.InnerText = VideoCount;
viewCount.InnerText = ViewCount;
lastUpdated.InnerText = LastUpdated;
metadata.AppendChild(videoCount);
metadata.AppendChild(viewCount);
metadata.AppendChild(lastUpdated);
playlist.AppendChild(metadata);
XmlElement results = doc.CreateElement("Videos");
foreach (DynamicItem result in Videos) results.AppendChild(result.GetXmlElement(doc));
playlist.AppendChild(results);
doc.AppendChild(playlist);
return doc;
}
}
}

View file

@ -0,0 +1,39 @@
using System.Xml;
namespace InnerTube.Models
{
public class YoutubeSearchResults
{
public string[] Refinements;
public long EstimatedResults;
public DynamicItem[] Results;
public string ContinuationKey;
public XmlDocument GetXmlDocument()
{
XmlDocument doc = new();
XmlElement search = doc.CreateElement("Search");
search.SetAttribute("estimatedResults", EstimatedResults.ToString());
search.SetAttribute("continuation", ContinuationKey);
if (Refinements.Length > 0)
{
XmlElement refinements = doc.CreateElement("Refinements");
foreach (string refinementText in Refinements)
{
XmlElement refinement = doc.CreateElement("Refinement");
refinement.InnerText = refinementText;
refinements.AppendChild(refinement);
}
search.AppendChild(refinements);
}
XmlElement results = doc.CreateElement("Results");
foreach (DynamicItem result in Results) results.AppendChild(result.GetXmlElement(doc));
search.AppendChild(results);
doc.AppendChild(search);
return doc;
}
}
}

View file

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
namespace InnerTube.Models
{
public class YoutubeStoryboardSpec
{
public Dictionary<string, string> Urls = new();
public YoutubeStoryboardSpec(string specStr, long duration)
{
if (specStr is null) return;
List<string> spec = new(specStr.Split("|"));
string baseUrl = spec[0];
spec.RemoveAt(0);
spec.Reverse();
int L = spec.Count - 1;
for (int i = 0; i < spec.Count; i++)
{
string[] args = spec[i].Split("#");
int width = int.Parse(args[0]);
int height = int.Parse(args[1]);
int frameCount = int.Parse(args[2]);
int cols = int.Parse(args[3]);
int rows = int.Parse(args[4]);
string N = args[6];
string sigh = args[7];
string url = baseUrl
.Replace("$L", (spec.Count - 1 - i).ToString())
.Replace("$N", N) + "&sigh=" + sigh;
float fragmentCount = frameCount / (cols * rows);
float fragmentDuration = duration / fragmentCount;
for (int j = 0; j < Math.Ceiling(fragmentCount); j++)
Urls.TryAdd($"L{spec.Count - 1 - i}", url.Replace("$M", j.ToString()));
}
}
}
}

View file

@ -0,0 +1,70 @@
using System;
using System.Xml;
namespace InnerTube.Models
{
public class YoutubeTrends
{
public TrendCategory[] Categories;
public DynamicItem[] Videos;
public XmlDocument GetXmlDocument()
{
XmlDocument doc = new();
XmlElement explore = doc.CreateElement("Explore");
XmlElement categories = doc.CreateElement("Categories");
foreach (TrendCategory category in Categories ?? Array.Empty<TrendCategory>()) categories.AppendChild(category.GetXmlElement(doc));
explore.AppendChild(categories);
XmlElement contents = doc.CreateElement("Videos");
foreach (DynamicItem item in Videos ?? Array.Empty<DynamicItem>()) contents.AppendChild(item.GetXmlElement(doc));
explore.AppendChild(contents);
doc.AppendChild(explore);
return doc;
}
}
public class TrendCategory
{
public string Label;
public Thumbnail[] BackgroundImage;
public Thumbnail[] Icon;
public string Id;
public XmlElement GetXmlElement(XmlDocument doc)
{
XmlElement category = doc.CreateElement("Category");
category.SetAttribute("id", Id);
XmlElement title = doc.CreateElement("Name");
title.InnerText = Label;
category.AppendChild(title);
XmlElement backgroundImages = doc.CreateElement("BackgroundImage");
foreach (Thumbnail t in BackgroundImage ?? Array.Empty<Thumbnail>())
{
XmlElement thumbnail = doc.CreateElement("Thumbnail");
thumbnail.SetAttribute("width", t.Width.ToString());
thumbnail.SetAttribute("height", t.Height.ToString());
thumbnail.InnerText = t.Url;
backgroundImages.AppendChild(thumbnail);
}
category.AppendChild(backgroundImages);
XmlElement icons = doc.CreateElement("Icon");
foreach (Thumbnail t in Icon ?? Array.Empty<Thumbnail>())
{
XmlElement thumbnail = doc.CreateElement("Thumbnail");
thumbnail.SetAttribute("width", t.Width.ToString());
thumbnail.SetAttribute("height", t.Height.ToString());
thumbnail.InnerText = t.Url;
icons.AppendChild(thumbnail);
}
category.AppendChild(icons);
return category;
}
}
}

View file

@ -0,0 +1,45 @@
using System;
using System.Xml;
namespace InnerTube.Models
{
public class YoutubeVideo
{
public string Id;
public string Title;
public string Description;
public Channel Channel;
public string UploadDate;
public DynamicItem[] Recommended;
public string Views;
public string GetHtmlDescription() => InnerTube.Utils.GetHtmlDescription(Description);
public XmlDocument GetXmlDocument()
{
XmlDocument doc = new();
XmlElement item = doc.CreateElement("Video");
item.SetAttribute("id", Id);
item.SetAttribute("views", Views);
item.SetAttribute("uploadDate", UploadDate);
XmlElement title = doc.CreateElement("Title");
title.InnerText = Title;
item.AppendChild(title);
XmlElement description = doc.CreateElement("Description");
description.InnerText = Description;
item.AppendChild(description);
item.AppendChild(Channel.GetXmlElement(doc));
XmlElement recommendations = doc.CreateElement("Recommendations");
foreach (DynamicItem f in Recommended ?? Array.Empty<DynamicItem>()) recommendations.AppendChild(f.GetXmlElement(doc));
item.AppendChild(recommendations);
doc.AppendChild(item);
return doc;
}
}
}