Repository rearrangement
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
using Google.Apis.Services;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using YouTube.Models;
|
||||
using YoutubeExplode;
|
||||
|
||||
namespace YouTube.Resources
|
||||
{
|
||||
public class CaptionsResource : Google.Apis.YouTube.v3.CaptionsResource
|
||||
{
|
||||
IClientService Service { get; }
|
||||
public CaptionsResource(IClientService service) : base(service) =>
|
||||
Service = service;
|
||||
|
||||
public LoadRequest Load(ClosedCaptionInfo captionInfo) =>
|
||||
new LoadRequest(Service, captionInfo);
|
||||
|
||||
public class LoadRequest
|
||||
{
|
||||
public ClosedCaptionInfo CaptionInfo { get; set; }
|
||||
IClientService Service { get; set; }
|
||||
|
||||
public LoadRequest(IClientService service, ClosedCaptionInfo captionInfo)
|
||||
{
|
||||
CaptionInfo = captionInfo;
|
||||
Service = service;
|
||||
}
|
||||
|
||||
public async Task<ClosedCaptionTrack> ExecuteAsync()
|
||||
{
|
||||
YoutubeClient client = new YoutubeClient(Service.HttpClient);
|
||||
var response = await client.GetClosedCaptionTrackAsync(CaptionInfo.TrackInfo);
|
||||
List<ClosedCaptionTrack.ClosedCaption> captions = new List<ClosedCaptionTrack.ClosedCaption>();
|
||||
foreach (var i in response.Captions)
|
||||
captions.Add(new ClosedCaptionTrack.ClosedCaption
|
||||
{
|
||||
Offset = i.Offset,
|
||||
Duration = i.Duration,
|
||||
Content = i.Text
|
||||
});
|
||||
|
||||
return new ClosedCaptionTrack
|
||||
{
|
||||
Info = CaptionInfo,
|
||||
Captions = captions.AsReadOnly()
|
||||
};
|
||||
}
|
||||
|
||||
public ClosedCaptionTrack Execute()
|
||||
{
|
||||
Task<ClosedCaptionTrack> task = ExecuteAsync();
|
||||
task.Wait();
|
||||
return task.Result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using Google.Apis.Services;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using YouTube.Generators;
|
||||
using YouTube.Models;
|
||||
|
||||
namespace YouTube.Resources
|
||||
{
|
||||
public class DashManifestsResource
|
||||
{
|
||||
IClientService Service { get; }
|
||||
public DashManifestsResource(IClientService service) =>
|
||||
Service = service;
|
||||
|
||||
public ListRequest List(string videoId) =>
|
||||
new ListRequest(Service, videoId);
|
||||
|
||||
public class ListRequest
|
||||
{
|
||||
public string Id { get; set; }
|
||||
IClientService Service { get; set; }
|
||||
|
||||
public ListRequest(IClientService service, string id)
|
||||
{
|
||||
Id = id;
|
||||
Service = service;
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyList<DashManifest>> ExecuteAsync()
|
||||
{
|
||||
ManifestGenerator generator = new ManifestGenerator(Service, Id);
|
||||
|
||||
return await generator.GenerateManifestsAsync();
|
||||
}
|
||||
|
||||
public IReadOnlyList<DashManifest> Execute()
|
||||
{
|
||||
Task<IReadOnlyList<DashManifest>> task = ExecuteAsync();
|
||||
task.Wait();
|
||||
return task.Result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Google.Apis.YouTube.v3;
|
||||
using Google.Apis.YouTube.v3.Data;
|
||||
|
||||
namespace YouTube.Resources
|
||||
{
|
||||
public class HistoryResource
|
||||
{
|
||||
public class ListRequest { }
|
||||
public class InsertRequest { }
|
||||
public class DeleteRequest { }
|
||||
public class ClearRequest { }
|
||||
|
||||
public ListRequest List()
|
||||
{
|
||||
return new ListRequest();
|
||||
}
|
||||
|
||||
public InsertRequest Insert(string videoId, TimeSpan? leftOn)
|
||||
{
|
||||
return new InsertRequest();
|
||||
}
|
||||
|
||||
public DeleteRequest Delete(string videoId)
|
||||
{
|
||||
return new DeleteRequest();
|
||||
}
|
||||
|
||||
public ClearRequest Clear()
|
||||
{
|
||||
return new ClearRequest();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
using Google.Apis.Services;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Threading.Tasks;
|
||||
using YouTube.Models;
|
||||
using YoutubeExplode;
|
||||
using YoutubeExplode.Models.ClosedCaptions;
|
||||
using YoutubeExplode.Models.MediaStreams;
|
||||
|
||||
namespace YouTube.Resources
|
||||
{
|
||||
public class VideoPlaybackResource
|
||||
{
|
||||
IClientService ClientService { get; }
|
||||
public VideoPlaybackResource(IClientService clientService) =>
|
||||
ClientService = clientService;
|
||||
|
||||
public ListRequest List(string videoId) =>
|
||||
new ListRequest(ClientService, videoId);
|
||||
|
||||
public class ListRequest
|
||||
{
|
||||
IClientService Service { get; }
|
||||
|
||||
public string Id { get; set; }
|
||||
|
||||
public async Task<VideoPlayback> ExecuteAsync()
|
||||
{
|
||||
VideoPlayback item = new VideoPlayback();
|
||||
YoutubeClient client = new YoutubeClient(Service.HttpClient);
|
||||
MediaStreamInfoSet streamSet = await client.GetVideoMediaStreamInfosAsync(Id);
|
||||
item.Id = Id;
|
||||
item.PlaybackUrls.ValidUntil = streamSet.ValidUntil.DateTime;
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(streamSet.HlsLiveStreamUrl))
|
||||
{
|
||||
item.PlaybackUrls.LiveStreamUrl = streamSet.HlsLiveStreamUrl;
|
||||
return item;
|
||||
}
|
||||
|
||||
List<AudioPlaybackUrl> audio = new List<AudioPlaybackUrl>();
|
||||
foreach (AudioStreamInfo i in streamSet.Audio)
|
||||
audio.Add(new AudioPlaybackUrl
|
||||
{
|
||||
Url = i.Url,
|
||||
Bitrate = (int)i.Bitrate,
|
||||
Format = (AudioFormat)i.AudioEncoding,
|
||||
Quality = Extensions.RangeOffset((int)i.Bitrate / 1024, 128, 255) switch
|
||||
{
|
||||
-1 => AudioQuality.Low,
|
||||
1 => AudioQuality.High,
|
||||
_ => AudioQuality.Medium
|
||||
}
|
||||
});
|
||||
item.PlaybackUrls.Audio = audio.AsReadOnly();
|
||||
|
||||
List<VideoPlaybackUrl> video = new List<VideoPlaybackUrl>();
|
||||
foreach (VideoStreamInfo i in streamSet.Video)
|
||||
video.Add(new VideoPlaybackUrl
|
||||
{
|
||||
Format = (VideoFormat)i.VideoEncoding,
|
||||
HasAudio = false,
|
||||
Quality = i.VideoQualityLabel,
|
||||
Url = i.Url,
|
||||
Resolution = new Size(i.Resolution.Width, i.Resolution.Height),
|
||||
Bitrate = (int)i.Bitrate
|
||||
});
|
||||
|
||||
foreach (MuxedStreamInfo i in streamSet.Muxed)
|
||||
video.Add(new VideoPlaybackUrl
|
||||
{
|
||||
Format = (VideoFormat)i.VideoEncoding,
|
||||
HasAudio = true,
|
||||
Quality = i.VideoQualityLabel,
|
||||
Url = i.Url,
|
||||
Resolution = new Size(i.Resolution.Width, i.Resolution.Height),
|
||||
Bitrate = 0
|
||||
});
|
||||
item.PlaybackUrls.Video = video.AsReadOnly();
|
||||
|
||||
var ccSet = await client.GetVideoClosedCaptionTrackInfosAsync(Id);
|
||||
|
||||
List<ClosedCaptionInfo> captions = new List<ClosedCaptionInfo>();
|
||||
foreach (ClosedCaptionTrackInfo i in ccSet)
|
||||
captions.Add(new ClosedCaptionInfo
|
||||
{
|
||||
AutoGenerated = i.IsAutoGenerated,
|
||||
Url = i.Url,
|
||||
Language = new CultureInfo(i.Language.Code),
|
||||
TrackInfo = i
|
||||
});
|
||||
item.ClosedCaptions = captions.AsReadOnly();
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public VideoPlayback Execute()
|
||||
{
|
||||
Task<VideoPlayback> task = ExecuteAsync();
|
||||
task.Wait();
|
||||
return task.Result;
|
||||
}
|
||||
public ListRequest(IClientService service, string id)
|
||||
{
|
||||
Id = id;
|
||||
Service = service;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
using AngleSharp.Html.Dom;
|
||||
using AngleSharp.Html.Parser;
|
||||
using Google.Apis.Http;
|
||||
using Google.Apis.Services;
|
||||
using Google.Apis.YouTube.v3;
|
||||
using Google.Apis.YouTube.v3.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace YouTube.Resources
|
||||
{
|
||||
public class WatchLaterResource
|
||||
{
|
||||
IClientService Service { get; }
|
||||
|
||||
public WatchLaterResource(IClientService service) =>
|
||||
Service = service;
|
||||
|
||||
public ListRequest List()
|
||||
{
|
||||
return new ListRequest();
|
||||
}
|
||||
|
||||
public InsertRequest Insert(string videoId, string part) =>
|
||||
new InsertRequest(Service, videoId, part);
|
||||
|
||||
public DeleteRequest Delete(string videoId) =>
|
||||
new DeleteRequest(Service, videoId);
|
||||
|
||||
public class ListRequest { }
|
||||
public class InsertRequest
|
||||
{
|
||||
IClientService Service { get; set; }
|
||||
public string Id { get; set; }
|
||||
public string Part { get; set; }
|
||||
|
||||
public InsertRequest(IClientService service, string videoId, string part)
|
||||
{
|
||||
Service = service;
|
||||
Id = videoId;
|
||||
Part = part;
|
||||
}
|
||||
|
||||
public async Task<PlaylistItem> ExecuteAsync()
|
||||
{
|
||||
PlaylistItem playlist = new PlaylistItem
|
||||
{
|
||||
Snippet = new PlaylistItemSnippet
|
||||
{
|
||||
PlaylistId = "WL",
|
||||
ResourceId = new ResourceId
|
||||
{
|
||||
VideoId = Id,
|
||||
Kind = "youtube#video"
|
||||
}
|
||||
}
|
||||
};
|
||||
PlaylistItemsResource.InsertRequest request = (Service as YouTubeService).PlaylistItems.Insert(playlist, Part);
|
||||
|
||||
return await request.ExecuteAsync();
|
||||
}
|
||||
|
||||
public PlaylistItem Execute()
|
||||
{
|
||||
Task<PlaylistItem> task = ExecuteAsync();
|
||||
task.Wait();
|
||||
return task.Result;
|
||||
}
|
||||
}
|
||||
public class DeleteRequest
|
||||
{
|
||||
IClientService Service { get; set; }
|
||||
public string Id { get; set; }
|
||||
|
||||
public DeleteRequest(IClientService service, string videoId)
|
||||
{
|
||||
Service = service;
|
||||
Id = videoId;
|
||||
}
|
||||
|
||||
public async Task ExecuteAsync()
|
||||
{
|
||||
ConfigurableHttpClient client = Service.HttpClient;
|
||||
string data = await client.GetStringAsync($"https://youtube.com/watch?v={Id}&disable_polymer=true&bpctr=9999999999&hl=en");
|
||||
string plid = Regex.Match(data, @"(?<=plid=).?\w+").Value;
|
||||
IHtmlDocument html = await new HtmlParser().ParseDocumentAsync(data);
|
||||
string sessionToken = html.GetElementsByTagName("input").FirstOrDefault(i => i.GetAttribute("name") == "session_token")?.GetAttribute("value");
|
||||
Dictionary<string, string> body = new Dictionary<string, string>
|
||||
{
|
||||
{ "video_ids", Id },
|
||||
{ "full_list_id", "WL" },
|
||||
{ "plid", plid },
|
||||
{ "session_token", sessionToken }
|
||||
};
|
||||
HttpResponseMessage response = await client.PostAsync("https://www.youtube.com/playlist_video_ajax?action_delete_from_playlist=1", new FormUrlEncodedContent(body));
|
||||
string responseStr = await response.Content.ReadAsStringAsync();
|
||||
if (!responseStr.Contains("SUCCESS"))
|
||||
throw new Exception(responseStr);
|
||||
}
|
||||
|
||||
public void Execute() =>
|
||||
ExecuteAsync().Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user