mirror of
https://codeberg.org/ashley/poke.git
synced 2025-06-24 04:47:02 -04:00
owo
This commit is contained in:
parent
f431111611
commit
72143fede3
100 changed files with 12438 additions and 0 deletions
380
core/InnerTube/Models/DynamicItem.cs
Normal file
380
core/InnerTube/Models/DynamicItem.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
67
core/InnerTube/Models/RequestContext.cs
Normal file
67
core/InnerTube/Models/RequestContext.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
71
core/InnerTube/Models/YoutubeChannel.cs
Normal file
71
core/InnerTube/Models/YoutubeChannel.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
40
core/InnerTube/Models/YoutubeLocals.cs
Normal file
40
core/InnerTube/Models/YoutubeLocals.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
230
core/InnerTube/Models/YoutubePlayer.cs
Normal file
230
core/InnerTube/Models/YoutubePlayer.cs
Normal 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; }
|
||||
}
|
||||
}
|
68
core/InnerTube/Models/YoutubePlaylist.cs
Normal file
68
core/InnerTube/Models/YoutubePlaylist.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
39
core/InnerTube/Models/YoutubeSearchResults.cs
Normal file
39
core/InnerTube/Models/YoutubeSearchResults.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
38
core/InnerTube/Models/YoutubeStoryboardSpec.cs
Normal file
38
core/InnerTube/Models/YoutubeStoryboardSpec.cs
Normal 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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
70
core/InnerTube/Models/YoutubeTrends.cs
Normal file
70
core/InnerTube/Models/YoutubeTrends.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
45
core/InnerTube/Models/YoutubeVideo.cs
Normal file
45
core/InnerTube/Models/YoutubeVideo.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue