mirror of
https://onedev.site.tesses.net/tytd2025
synced 2026-06-01 09:55:34 +00:00
Make the downloader more resiliant
This commit is contained in:
@@ -14,6 +14,6 @@
|
||||
"project_dependencies": [
|
||||
"..\/Tesses.YouTubeDownloader"
|
||||
],
|
||||
"version": "1.0.0.2-prod",
|
||||
"version": "1.0.0.3-prod",
|
||||
"compTime": "secure"
|
||||
}
|
||||
@@ -623,6 +623,17 @@ class TYTDApp {
|
||||
|
||||
}
|
||||
}
|
||||
else if(ctx.Path == "/api/v1/manifest.json")
|
||||
{
|
||||
const v = ctx.QueryParams.TryGetFirst("v");
|
||||
if(TypeIsString(v))
|
||||
{
|
||||
const resp=this.TYTD.ManifestRequest(v);
|
||||
Console.WriteLine(resp);
|
||||
ctx.WithMimeType("application/json").SendJson(resp);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if(ctx.Path == "/api/v1/personal")
|
||||
{
|
||||
/*
|
||||
|
||||
@@ -14,6 +14,6 @@
|
||||
}
|
||||
],
|
||||
"name": "Tesses.YouTubeDownloader",
|
||||
"version": "1.0.0.2-prod",
|
||||
"version": "1.0.0.3-prod",
|
||||
"icon": "icon.png"
|
||||
}
|
||||
@@ -1341,11 +1341,51 @@ class TYTD.Downloader {
|
||||
if(e == null)
|
||||
{
|
||||
var req = this.ManifestRequest(id);
|
||||
this.DownloadCaptions(req);
|
||||
this.PutVideoInfo(req.playerResponse.videoDetails);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
private DownloadCaptions(req)
|
||||
{
|
||||
const tracks = req.playerResponse.playerCaptionsTracklistRenderer.captionTracks;
|
||||
if(TypeIsList(tracks))
|
||||
{
|
||||
each(var item : tracks)
|
||||
{
|
||||
if(!TypeIsString(item.languageCode)) continue;
|
||||
if(!TypeIsString(item.baseUrl)) continue;
|
||||
try {
|
||||
var path = /"Streams"/id.Substring(0,4) / id.Substring(4) / item.languageCode;
|
||||
var resp = Net.Http.MakeRequest(url,{FollowRedirects=true});
|
||||
if(resp.StatusCode >= 200 && resp.StatusCode <= 299)
|
||||
{
|
||||
const strm=this.Storage.OpenFile(path+".xml","wb");
|
||||
resp.CopyToStream(strm);
|
||||
strm.Close();
|
||||
}
|
||||
resp = Net.Http.MakeRequest(url.Replace("fmt=srv3","fmt=vtt"),{FollowRedirects=true});
|
||||
if(resp.StatusCode >= 200 && resp.StatusCode <= 299)
|
||||
{
|
||||
const strm=this.Storage.OpenFile(path+".vtt","wb");
|
||||
resp.CopyToStream(strm);
|
||||
strm.Close();
|
||||
}
|
||||
resp = Net.Http.MakeRequest(url.Replace("fmt=srv3","fmt=srt"),{FollowRedirects=true});
|
||||
if(resp.StatusCode >= 200 && resp.StatusCode <= 299)
|
||||
{
|
||||
const strm=this.Storage.OpenFile(path+".srt","wb");
|
||||
resp.CopyToStream(strm);
|
||||
strm.Close();
|
||||
}
|
||||
|
||||
} catch(ex) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/^
|
||||
Put video info from info into database
|
||||
^/
|
||||
@@ -1608,6 +1648,7 @@ class TYTD.Downloader {
|
||||
^/
|
||||
public ManifestRequest(vid)
|
||||
{
|
||||
while(true) {
|
||||
var id = TYTD.GetVideoId(vid);
|
||||
if(id == null) return null;
|
||||
TryDownloadVideoThumbnail(id,"0");
|
||||
@@ -1651,9 +1692,35 @@ class TYTD.Downloader {
|
||||
};
|
||||
this.RateLimit();
|
||||
var response = Net.Http.MakeRequest(url,requestData);
|
||||
if(response.StatusCode < 200 || response.StatusCode > 299) return null;
|
||||
return Json.Decode(response.ReadAsString());
|
||||
Console.WriteLine(response.StatusCode);
|
||||
|
||||
if(response.StatusCode < 200 || response.StatusCode > 299) continue;
|
||||
const respText = response.ReadAsString();
|
||||
const jsonResp = Json.Decode(respText);
|
||||
if(!TypeIsDictionary(jsonResp.playerResponse)) continue;
|
||||
|
||||
if(TypeIsDictionary(jsonResp.playerResponse.playabilityStatus))
|
||||
{
|
||||
if(jsonResp.playerResponse.playabilityStatus.status == "ERROR")
|
||||
{
|
||||
throw new VideoDownloadError(id, jsonResp.playerResponse.playabilityStatus.reason);
|
||||
}
|
||||
} else {
|
||||
throw new VideoDownloadError(id, "playabilityStatus is missing");
|
||||
}
|
||||
|
||||
if(!TypeIsDictionary(jsonResp.playerResponse.videoDetails))
|
||||
{
|
||||
throw new VideoDownloadError(id, "videoDetails is missing");
|
||||
}
|
||||
|
||||
if(!TypeIsList(jsonResp.playerResponse.streamingData.adaptiveFormats))
|
||||
{
|
||||
throw new VideoDownloadError(id, "adaptiveFormats is missing");
|
||||
}
|
||||
|
||||
return jsonResp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
16
Tesses.YouTubeDownloader/src/error.tcross
Normal file
16
Tesses.YouTubeDownloader/src/error.tcross
Normal file
@@ -0,0 +1,16 @@
|
||||
class VideoDownloadError {
|
||||
public VideoDownloadError(id, error)
|
||||
{
|
||||
Id = id;
|
||||
Error = error;
|
||||
}
|
||||
|
||||
public Id;
|
||||
|
||||
public Error;
|
||||
|
||||
public ToString()
|
||||
{
|
||||
return $"Download error {Error} with Id: {Id}";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user