tytd_proxy/TYTDProxy/Program.cs

183 lines
7.1 KiB
C#

using System.Net;
using Tesses.WebServer;
using YoutubeExplode;
using YoutubeExplode.Search;
using YoutubeExplode.Videos;
using YoutubeExplode.Videos.Streams;
public class TYTDProxy
{
static YoutubeClient Youtube = new YoutubeClient();
public static async Task Main(string[] args)
{
using (var token = new CancellationTokenSource())
{
Console.CancelKeyPress += (sender,e)=>{
token.Cancel();
};
StaticServer static_server=new StaticServer("WebSite");
RouteServer api_server=new RouteServer();
RouteApi(api_server);
MountableServer mountable_server=new MountableServer(static_server);
mountable_server.Mount("/api/",api_server);
HttpServerListener listener=new HttpServerListener(new System.Net.IPEndPoint(System.Net.IPAddress.Any,3253),mountable_server);
await listener.ListenAsync(token.Token);
}
}
public static void RouteApi(RouteServer api)
{
api.Add("/Video.json",Video);
api.Add("/Video.json",Video,"POST");
api.Add("/PreMuxed",PreMuxed);
api.Add("/VideoOnly",VideoOnly);
api.Add("/AudioOnly",AudioOnly);
api.Add("/PreMuxed",PreMuxed,"POST");
api.Add("/VideoOnly",VideoOnly,"POST");
api.Add("/AudioOnly",AudioOnly,"POST");
api.Add("/DownloadYTStream",DownloadYTStream,"POST");
api.Add("/Search.json",Search,"POST");
api.Add("/Search.json",Search);
}
public class StreamResult
{
public StreamResult(IStreamInfo info)
{
url = info.Url;
ext=info.Container.Name;
size = info.Size.Bytes;
}
public string url {get;set;}
public string ext {get;set;}
public long size {get;set;}
}
public class VideoResult
{
public VideoResult(StreamResult muxed,StreamResult video_only,StreamResult audio_only,SavedVideo video)
{
this.muxed=muxed;
this.video_only=video_only;
this.audio_only = audio_only;
this.video_info=video;
}
public StreamResult muxed {get;set;}
public StreamResult video_only {get;set;}
public StreamResult audio_only {get;set;}
public SavedVideo video_info {get;set;}
}
public static async Task Search(ServerContext ctx)
{
string q;
if(ctx.QueryParams.TryGetFirst("q",out q)){
if(ctx.Method == "POST") ctx.ParseBody();
if(ctx.Method != "POST") q=WebUtility.UrlDecode(q);
{
List<VideoSearchResult> searchResults=new List<VideoSearchResult>();
await foreach(var item in Youtube.Search.GetVideosAsync(q))
{
searchResults.Add(item);
}
await ctx.SendJsonAsync(searchResults);
}
}
}
public static async Task PreMuxed(ServerContext ctx)
{
string v;
if(ctx.QueryParams.TryGetFirst("v",out v)){
if(ctx.Method == "POST") ctx.ParseBody();
if(ctx.Method != "POST") v=WebUtility.UrlDecode(v);
var vid=await Youtube.Videos.GetAsync(v);
var res= await Youtube.Videos.Streams.GetManifestAsync(v);
var bestMuxed=res.GetMuxedStreams().GetWithHighestVideoQuality();
System.Net.Mime.ContentDisposition contentDisposition=new System.Net.Mime.ContentDisposition();
contentDisposition.FileName = vid.Title;
await ctx.SendStreamAsync(await Youtube.Videos.Streams.GetAsync(bestMuxed),$"file.{bestMuxed.Container.Name}");
}
}
public static async Task VideoOnly(ServerContext ctx)
{
string v;
if(ctx.QueryParams.TryGetFirst("v",out v)){
if(ctx.Method == "POST") ctx.ParseBody();
if(ctx.Method != "POST") v=WebUtility.UrlDecode(v);
var vid=await Youtube.Videos.GetAsync(v);
var res= await Youtube.Videos.Streams.GetManifestAsync(v);
var bestVideoOnly=res.GetVideoOnlyStreams().GetWithHighestVideoQuality();
System.Net.Mime.ContentDisposition contentDisposition=new System.Net.Mime.ContentDisposition();
contentDisposition.FileName = vid.Title;
await ctx.SendStreamAsync(await Youtube.Videos.Streams.GetAsync(bestVideoOnly),$"file.{bestVideoOnly.Container.Name}");
}
}
public static async Task AudioOnly(ServerContext ctx)
{
string v;
if(ctx.QueryParams.TryGetFirst("v",out v)){
if(ctx.Method == "POST") ctx.ParseBody();
if(ctx.Method != "POST") v=WebUtility.UrlDecode(v);
var vid=await Youtube.Videos.GetAsync(v);
var res= await Youtube.Videos.Streams.GetManifestAsync(v);
var bestAudioOnly=res.GetAudioOnlyStreams().GetWithHighestBitrate();
System.Net.Mime.ContentDisposition contentDisposition=new System.Net.Mime.ContentDisposition();
contentDisposition.FileName = vid.Title;
await ctx.SendStreamAsync(await Youtube.Videos.Streams.GetAsync(bestAudioOnly),$"file.{bestAudioOnly.Container.Name}");
}
}
public class DummyStr : IStreamInfo
{
public DummyStr(string url,long len)
{
this.url = url;
this.len=len;
}
long len;
string url;
public string Url => url;
public Container Container => Container.Mp4;
public FileSize Size => new FileSize(len);
public Bitrate Bitrate => new Bitrate(420000);
}
public static async Task DownloadYTStream(ServerContext ctx)
{
string v;
string lenTxt;
if(ctx.QueryParams.TryGetFirst("url",out v)){
if(ctx.QueryParams.TryGetFirst("flen",out lenTxt)){
if(ctx.Method == "POST") ctx.ParseBody();
if(ctx.Method != "POST") v=WebUtility.UrlDecode(v);
long len;
if(long.TryParse(lenTxt,out len)){
await ctx.SendStreamAsync(await Youtube.Videos.Streams.GetAsync(new DummyStr(v,len)),HeyRed.Mime.MimeTypesMap.GetMimeType("file.bin"));
}
}
}
}
public static async Task Video(ServerContext ctx)
{
string v;
if(ctx.QueryParams.TryGetFirst("v",out v)){
if(ctx.Method == "POST") ctx.ParseBody();
if(ctx.Method != "POST") v=WebUtility.UrlDecode(v);
var res= await Youtube.Videos.Streams.GetManifestAsync(v);
var bestMuxed=new StreamResult(res.GetMuxedStreams().GetWithHighestVideoQuality());
var bestVideoOnly=new StreamResult(res.GetVideoOnlyStreams().GetWithHighestVideoQuality());
var bestAudioOnly=new StreamResult(res.GetAudioOnlyStreams().GetWithHighestBitrate());
SavedVideo video = new SavedVideo(await Youtube.Videos.GetAsync(v));
VideoResult result = new VideoResult(bestMuxed,bestVideoOnly,bestAudioOnly,video);
await ctx.SendJsonAsync(result);
}
}
}