Added example
This commit is contained in:
parent
229443fb86
commit
e60820a763
|
@ -142,4 +142,5 @@ Tesses.YouTubeDownloader.Net6/PreMuxed/
|
|||
Tesses.YouTubeDownloader.Net6/config/
|
||||
Tesses.YouTubeDownloader.Net6/Playlist/
|
||||
Tesses.YouTubeDownloader.Net6/Channel/
|
||||
Tesses.YouTubeDownloader.Net6/Subscriptions/
|
||||
push
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
# Tesses.YouTubeDownloader (2022)
|
||||
|
||||
Tesses.YouTubeDownloader.ExampleExtension uses [Return YouTube Dislikes](https://returnyoutubedislike.com/)
|
||||
|
||||
[How To Find Videos (When Downloaded)](docs/HowToFindVideos.md)
|
||||
<br>
|
||||
[Server Endpoints](docs/Server.md)
|
||||
<br>
|
||||
[Classes and Enums](docs/JsonAndEnum.md)
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
using System;
|
||||
using Tesses.YouTubeDownloader.ExtensionLoader;
|
||||
using Tesses.WebServer;
|
||||
using Newtonsoft.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Tesses.YouTubeDownloader.ExampleExtension
|
||||
{
|
||||
public class ExampleExtensionClass : Extension
|
||||
{
|
||||
string efn;
|
||||
public bool Enabled {get {return Storage.FileExists(efn);} set{
|
||||
if(value)
|
||||
{
|
||||
if(!Storage.FileExists(efn))
|
||||
{
|
||||
Storage.WriteAllTextAsync(efn,"enabled").Wait();
|
||||
}
|
||||
}else{
|
||||
if(Storage.FileExists(efn))
|
||||
{
|
||||
Storage.DeleteFile(efn);
|
||||
}
|
||||
}
|
||||
}}
|
||||
public bool FirstLoad()
|
||||
{
|
||||
string init=this.ExtensionStorage("init");
|
||||
bool first = !this.Storage.FileExists(init);
|
||||
if(first)
|
||||
{
|
||||
this.Storage.WriteAllTextAsync(init,"loaded").Wait();
|
||||
}
|
||||
return first;
|
||||
}
|
||||
public override void OnStart()
|
||||
{
|
||||
if(FirstLoad())
|
||||
{
|
||||
Enabled=true;
|
||||
}
|
||||
this.Storage.BeforeSaveInfo += BeforeSaveInfo;
|
||||
efn=this.ExtensionStorage("enabled");
|
||||
RouteServer svr=new RouteServer();
|
||||
svr.Add("/",Index);
|
||||
svr.Add("/setting.cgi",Setting);
|
||||
}
|
||||
public async Task Index(ServerContext ctx)
|
||||
{
|
||||
string enabledStr = Enabled ? " checked" : "";
|
||||
string index=$"<!DOCTYPE html><html lang=\"en\"><head> <meta charset=\"UTF-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>Return YouTube Dislikes Addon for TYTD</title></head><body><h1>Return YouTube Dislikes Addon for TYTD</h1><form action=\"./setting.cgi\" method=\"GET\"><label for=\"enabled\">Enabled: </label><input type=\"checkbox\" name=\"enabled\" id=\"enabled\" {enabledStr}><br><input type=\"submit\" value=\"Save\"></form>This extension uses <a href=\"//returnyoutubedislike.com\">Return YouTube Dislikes</a></body></html>";
|
||||
await ctx.SendTextAsync(index);
|
||||
}
|
||||
public async Task Setting(ServerContext ctx)
|
||||
{
|
||||
Enabled=ctx.QueryParams.ContainsKey("enabled");
|
||||
|
||||
await ctx.SendTextAsync(
|
||||
$"<html><head><titleYou Will Be Redirected in 5 Sec</title><meta http-equiv=\"Refresh\" content=\"5; url='./'\" /></head><body><h1>You Will Be Redirected in 5 Sec</h1></body></html>\n"
|
||||
);
|
||||
}
|
||||
public override string Name => "returnyoutubedislike.com";
|
||||
private async void BeforeSaveInfo(object sender, BeforeSaveInfoEventArgs e)
|
||||
{
|
||||
if(Enabled)
|
||||
e.VideoInfo.Dislikes=JsonConvert.DeserializeObject<Dislike>(await this.Storage.HttpClient.GetStringAsync($"https://returnyoutubedislikeapi.com/votes?videoId={e.VideoInfo.Id}")).dislikes;
|
||||
}
|
||||
}
|
||||
|
||||
public class Dislike
|
||||
{
|
||||
public long dislikes {get;set;}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Tesses.YouTubeDownloader.ExtensionLoader\Tesses.YouTubeDownloader.ExtensionLoader.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
|
@ -10,11 +10,13 @@ namespace Tesses.YouTubeDownloader.Net6
|
|||
TYTDCurrentDirectory currentDirectory=new TYTDCurrentDirectory(new HttpClient());
|
||||
TYTDServer server=new TYTDServer(currentDirectory);
|
||||
server.RootServer.Server=new StaticServer("WebSite");
|
||||
HttpServerListener listener=new HttpServerListener(new System.Net.IPEndPoint(System.Net.IPAddress.Any,42440),server.InnerServer);
|
||||
currentDirectory.CanDownload=false;
|
||||
HttpServerListener listener=new HttpServerListener(new System.Net.IPEndPoint(System.Net.IPAddress.Any,3252),server.InnerServer);
|
||||
currentDirectory.StartLoop();
|
||||
TYTDStorage.FFmpeg ="/usr/bin/ffmpeg";
|
||||
Console.WriteLine("Almost Ready to Listen");
|
||||
await listener.ListenAsync(CancellationToken.None);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -30,17 +30,17 @@ namespace Tesses.YouTubeDownloader
|
|||
}
|
||||
Resolution Resolution;
|
||||
UserName name1;
|
||||
ChannelId Id;
|
||||
ChannelId? Id; //made me nullable
|
||||
|
||||
public async Task<SavedChannel> GetChannel(TYTDStorage storage)
|
||||
{
|
||||
SavedChannel channel;
|
||||
if(Id !=null)
|
||||
if(Id.HasValue) //dont check for if(Id != null) hince I was looking for several minutes for the bug
|
||||
{
|
||||
string path=$"Channel/{Id}.json";
|
||||
string path=$"Channel/{Id.Value}.json";
|
||||
if(await storage.Continue(path))
|
||||
{
|
||||
channel=await DownloadThumbnails(storage,await storage.YoutubeClient.Channels.GetAsync(Id));
|
||||
channel=await DownloadThumbnails(storage,await storage.YoutubeClient.Channels.GetAsync(Id.Value));
|
||||
//channel=new SavedChannel(i);
|
||||
await storage.WriteAllTextAsync(path,JsonConvert.SerializeObject(channel));
|
||||
return channel;
|
||||
|
@ -49,8 +49,9 @@ namespace Tesses.YouTubeDownloader
|
|||
return j;
|
||||
}
|
||||
}else{
|
||||
channel=await DownloadThumbnails(storage, await storage.YoutubeClient.Channels.GetByUserAsync(name1));
|
||||
string path=$"Channel/{Id}.json";
|
||||
var c=await storage.YoutubeClient.Channels.GetByUserAsync(name1);
|
||||
channel=await DownloadThumbnails(storage,c);
|
||||
string path=$"Channel/{c.Id.Value}.json";
|
||||
if(await storage.Continue(path))
|
||||
{
|
||||
await storage.WriteAllTextAsync(path,JsonConvert.SerializeObject(channel));
|
||||
|
|
|
@ -130,7 +130,7 @@ namespace Tesses.YouTubeDownloader
|
|||
}
|
||||
public async Task SaveSubscription(Subscription sub)
|
||||
{
|
||||
await WriteAllTextAsync($"Subscriptions/{sub.Id}",JsonConvert.SerializeObject(sub));
|
||||
await WriteAllTextAsync($"Subscriptions/{sub.Id}.json",JsonConvert.SerializeObject(sub));
|
||||
}
|
||||
public async Task SubscribeAsync(UserName name,ChannelBellInfo bellInfo=ChannelBellInfo.NotifyAndDownload)
|
||||
{
|
||||
|
|
|
@ -115,6 +115,8 @@ namespace Tesses.YouTubeDownloader
|
|||
}
|
||||
public void CreateDirectories()
|
||||
{
|
||||
CreateDirectoryIfNotExist("Channel");
|
||||
CreateDirectoryIfNotExist("Playlist");
|
||||
CreateDirectoryIfNotExist("Subscriptions");
|
||||
CreateDirectoryIfNotExist("VideoOnly");
|
||||
CreateDirectoryIfNotExist("AudioOnly");
|
||||
|
@ -122,6 +124,8 @@ namespace Tesses.YouTubeDownloader
|
|||
CreateDirectoryIfNotExist("PreMuxed");
|
||||
CreateDirectoryIfNotExist("Info");
|
||||
CreateDirectoryIfNotExist("Thumbnails");
|
||||
CreateDirectoryIfNotExist("config");
|
||||
CreateDirectoryIfNotExist("config/logs");
|
||||
}
|
||||
public void StartLoop(CancellationToken token = default(CancellationToken))
|
||||
{
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
<PackageId>Tesses.YouTubeDownloader</PackageId>
|
||||
<Author>Mike Nolan</Author>
|
||||
<Company>Tesses</Company>
|
||||
<Version>1.0.3.1</Version>
|
||||
<AssemblyVersion>1.0.3.1</AssemblyVersion>
|
||||
<FileVersion>1.0.3.1</FileVersion>
|
||||
<Version>1.0.3.3</Version>
|
||||
<AssemblyVersion>1.0.3.3</AssemblyVersion>
|
||||
<FileVersion>1.0.3.3</FileVersion>
|
||||
<Description>A YouTube Downloader</Description>
|
||||
<PackageLicenseExpression>LGPL-3.0-only</PackageLicenseExpression>
|
||||
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Configuration
|
||||
This is Json Object (With these Key/Value Pairs)
|
||||
This is Json Object (With these Key/Value Pairs)<br>
|
||||
File path is config/tytdprop.json
|
||||
| Name | Description | Type |
|
||||
| ------- | ----------------- | ----- |
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
# How to find videos
|
||||
|
||||
| Name | Url | Url with filename in content-disposition | Path |
|
||||
| ------- | ------- | ---------- | ----- |
|
||||
| Mux | http://localhost:3252/api/Storage/File/Mux/{Id}.mkv | http://localhost:3252/api/Storage/VideoRes/0/{Id} | Mux/{Id}.mkv |
|
||||
| PreMuxed | http://localhost:3252/api/Storage/File/PreMuxed/{Id}.{Container} | http://localhost:3252/api/Storage/VideoRes/1/{Id} | PreMuxed/{Id}.{Container} |
|
||||
| AudioOnly | http://localhost:3252/api/Storage/File/AudioOnly/{Id}.{Container} | http://localhost:3252/api/Storage/VideoRes/2/{Id} | AudioOnly/{Id}.{Container} |
|
||||
|
|
||||
| VideoOnly | http://localhost:3252/api/Storage/File/VideoOnly/{Id}.{Container} | http://localhost:3252/api/Storage/VideoRes/3/{Id} | VideoOnly/{Id}.{Container} |
|
||||
|
|
||||
|
||||
# What you should see before this
|
||||
[StreamInfo](StreamInfo.md) (this is required to get {Container})<br>
|
||||
[Resolution](Resolution.md) (this is recomended so you know what the resolution numbers mean)
|
|
@ -9,4 +9,5 @@
|
|||
| Configure | App Configuration | Class | [View](Configure.md) |
|
||||
| QueueList | Video Queue | List of Class | [View](QueueList.md) |
|
||||
| Bell | Bell Setting (simular to on YouTube) | Enum | [View](Bell.md) |
|
||||
| Resolution | Video Resolution | Enum | [View](Resolution.md) |
|
||||
| Resolution | Video Resolution | Enum | [View](Resolution.md) |
|
||||
| StreamInfo | Video Stream Info | Class | [View](StreamInfo.md) |
|
|
@ -4,6 +4,7 @@ This is an Enum
|
|||
|
||||
| Name | Number| Used to be |
|
||||
| ---- | ---- | -----|
|
||||
| NoDownload | -1 | N/A (Endpoints with Only in them) |
|
||||
| Mux | 0 | Converted |
|
||||
| PreMuxed | 1 | NotConverted |
|
||||
| AudioOnly | 2 | Audio |
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Saved Channel
|
||||
This is Json Object (With these Key/Value Pairs)
|
||||
This is Json Object (With these Key/Value Pairs)<br>
|
||||
File Path is Channel/{Id}.json
|
||||
| Name | Description | Type |
|
||||
|--------|-------|------|
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Saved Playlist
|
||||
This is Json Object (With these Key/Value Pairs)
|
||||
This is Json Object (With these Key/Value Pairs)<br>
|
||||
File Path is Playlist/{Id}.json
|
||||
| Name | Description | Type |
|
||||
|--------|-------|------|
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Saved Video
|
||||
This is Json Object (With these Key/Value Pairs)
|
||||
This is Json Object (With these Key/Value Pairs)<br>
|
||||
File Path is Info/{Id}.json
|
||||
| Name | Description | Type |
|
||||
|--------|-------|------|
|
||||
|
|
|
@ -17,4 +17,9 @@ Get Requests
|
|||
| http://localhost:3252/api/v2/subscribe?id={UserName}&conf=NotifyAndDownload | Subscribe to YouTuber (UserName), See [Bell](Bell.md) for conf queryparm |
|
||||
| http://localhost:3252/api/v2/resubscribe?id={ChannelId}&conf=Download | Change Bell for YouTuber, See [Bell](Bell.md) for conf queryparm |
|
||||
| http://localhost:3252/api/v2/unsubscribe?id={ChannelId} | Unsubscribe from YouTuber |
|
||||
| http://localhost:3252/api/v2/subscriptions | Get Subscriptions, Is a json array of [Subscription](Subscription.md) |
|
||||
| http://localhost:3252/api/v2/subscriptions | Get Subscriptions, Is a json array of [Subscription](Subscription.md) |
|
||||
| http://localhost:3252/api/Storage/File/{File_Path} | Get File from TYTDStorage |
|
||||
| http://localhost:3252/api/Storage/FileExists/{File_Path} | Does file exist, returns "true" or "false" as response (Not Json just that text) |
|
||||
| http://localhost:3252/api/Storage/DirectoryExists/{Directory_Path} | Does directory exist, returns "true" or "false" as response (Not Json just that text) |
|
||||
| http://localhost:3252/api/Storage/GetFiles/{File_Path} | Get list of files json array of filenames, not full path |
|
||||
| http://localhost:3252/api/Storage/GetDirectories/{Directory_Path} | Get list of directorys json array of directory names, not full path |
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
# Video Streams Info
|
||||
This is Json Object (With these Key/Value Pairs)<br>
|
||||
File Path is StreamInfo/{Id}.json<br>
|
||||
This is required to get extension for all resolutions except "Mux" which uses mkv<br>
|
||||
these extensions are not prepended with .<br>
|
||||
hince all of the resolutions use the same class use [this](StreamInfo2.md) for json structure for all three with type "Object"
|
||||
| Name | Description | Type |
|
||||
|--------|-------|------|
|
||||
| Expires | When the url's expire (6 hours after adding video) ex 2022-05-07T01:48:23.982827-05:00 | DateTime(String) |
|
||||
| VideoOnly | This stream go into "VideoOnly" folder, no audio | Object |
|
||||
| Audio | This stream go into "AudioOnly" folder, no video | Object |
|
||||
| Muxed | This stream go into "PreMuxed" folder, both video and audio (no conversion required) | Object |
|
|
@ -0,0 +1,10 @@
|
|||
# Video Streams Info
|
||||
This is Json Object (With these Key/Value Pairs)<br>
|
||||
See [this](StreamInfo.md) if you havent already
|
||||
|
||||
| Name | Description | Type |
|
||||
|--------|-------|------|
|
||||
| | When the url's expire (6 hours after adding video) ex 2022-05-07T01:48:23.982827-05:00 | DateTime(String) |
|
||||
| VideoOnly | This stream go into "VideoOnly" folder, no audio | Object |
|
||||
| Audio | This stream go into "AudioOnly" folder, no video | Object |
|
||||
| Muxed | This stream go into "PreMuxed" folder, both video and audio (no conversion required) | Object |
|
Loading…
Reference in New Issue