Added backend capability to select specific download qualities
This commit is contained in:
parent
818213da50
commit
c66883efd6
@ -17,22 +17,28 @@ void DownloadManager::PreInit()
|
||||
return;
|
||||
}
|
||||
|
||||
std::string DownloadManager::QueueDownload(std::string url, DOWNLOAD_MODE mode)
|
||||
std::string DownloadManager::QueueDownload(std::string url, DOWNLOAD_MODE mode, DOWNLOAD_QUALITY quality)
|
||||
{
|
||||
// Create uniquie tubio id
|
||||
std::string tubioId = CreateNewTubioID();
|
||||
FetchInformation(url, tubioId);
|
||||
|
||||
// Fetch metadata
|
||||
FetchInformation(url, tubioId);
|
||||
std::string jsString = FileSystem::ReadFile(XGConfig::downloader.cachedir + "/metadata/" + tubioId + ".json");
|
||||
|
||||
// Create download entry structure
|
||||
DownloadEntry newDownload;
|
||||
newDownload.tubio_id = tubioId;
|
||||
newDownload.mode = mode;
|
||||
newDownload.quality = quality;
|
||||
newDownload.download_progress = 0;
|
||||
newDownload.queued_timestamp = time(0);
|
||||
newDownload.download_url = "/download/" + newDownload.tubio_id;
|
||||
newDownload.download_url = "download/" + newDownload.tubio_id;
|
||||
|
||||
// Check for missing dependencies
|
||||
WarnIfMissingDependenciesWIN();
|
||||
|
||||
// Interpret metadata
|
||||
if (!IsJsonValid(jsString))
|
||||
{
|
||||
newDownload.status = DOWNLOAD_STATUS::FAILED;
|
||||
@ -92,6 +98,7 @@ std::string DownloadManager::QueueDownload(std::string url, DOWNLOAD_MODE mode)
|
||||
}
|
||||
}
|
||||
|
||||
// Add to list of unfinished downloads
|
||||
unfinishedCache.push_back(newDownload);
|
||||
|
||||
return tubioId;
|
||||
@ -146,16 +153,19 @@ void DownloadManager::DownloadNext()
|
||||
|
||||
std::thread* downloadThread = new std::thread([=]() {
|
||||
DownloadEntry* entry = next;
|
||||
std::string tubioId = entry->tubio_id;
|
||||
|
||||
std::stringstream ss;
|
||||
if (entry->mode == DOWNLOAD_MODE::VIDEO)
|
||||
{
|
||||
std::string ytdl_call_video_base =
|
||||
// Call template
|
||||
std::string ytdl_call_video_base =
|
||||
"youtube-dl --newline --no-call-home --no-playlist --no-part --no-warnings --socket-timeout 5 --limit-rate $$DL_RATE"
|
||||
" --no-mtime --no-cache-dir --recode-video mp4 --prefer-ffmpeg"
|
||||
" --no-mtime --no-cache-dir -f $$QUALITY --recode-video mp4 --prefer-ffmpeg"
|
||||
" -o \"$$DL_FILE\" \"$$DL_URL\" > \"$$DL_PROG_BUF_FILE\"";
|
||||
|
||||
|
||||
// Fill template
|
||||
ytdl_call_video_base = Internal::StringHelpers::Replace(ytdl_call_video_base, "$$QUALITY", DownloadQualityToStringParams(entry->quality));
|
||||
ytdl_call_video_base = Internal::StringHelpers::Replace(ytdl_call_video_base, "$$DL_RATE", XGConfig::downloader.max_dlrate_per_thread);
|
||||
ytdl_call_video_base = Internal::StringHelpers::Replace(ytdl_call_video_base, "$$DL_FILE", XGConfig::downloader.cachedir + "/download/" + entry->tubio_id + ".%(ext)s");
|
||||
ytdl_call_video_base = Internal::StringHelpers::Replace(ytdl_call_video_base, "$$DL_URL", entry->webpage_url);
|
||||
@ -167,11 +177,15 @@ void DownloadManager::DownloadNext()
|
||||
}
|
||||
else // DOWNLOAD_MODE::AUDIO
|
||||
{
|
||||
// Call template
|
||||
std::string ytdl_call_audio_base =
|
||||
"youtube-dl --newline --no-call-home --no-playlist --no-part --no-warnings --socket-timeout 5 --limit-rate $$DL_RATE"
|
||||
" --no-mtime --no-cache-dir --audio-format mp3 --audio-quality 0 --extract-audio -o \"$$DL_FILE\""
|
||||
" --no-mtime --no-cache-dir -f $$QUALITY --audio-format mp3 --audio-quality 0 --extract-audio -o \"$$DL_FILE\""
|
||||
" \"$$DL_URL\" > \"$$DL_PROG_BUF_FILE\"";
|
||||
|
||||
|
||||
// Fill template
|
||||
ytdl_call_audio_base = Internal::StringHelpers::Replace(ytdl_call_audio_base, "$$QUALITY", DownloadQualityToStringParams(entry->quality));
|
||||
ytdl_call_audio_base = Internal::StringHelpers::Replace(ytdl_call_audio_base, "$$DL_RATE", XGConfig::downloader.max_dlrate_per_thread);
|
||||
ytdl_call_audio_base = Internal::StringHelpers::Replace(ytdl_call_audio_base, "$$DL_FILE", XGConfig::downloader.cachedir + "/download/" + entry->tubio_id + ".%(ext)s");
|
||||
ytdl_call_audio_base = Internal::StringHelpers::Replace(ytdl_call_audio_base, "$$DL_URL", entry->webpage_url);
|
||||
@ -182,13 +196,21 @@ void DownloadManager::DownloadNext()
|
||||
ss << ytdl_call_audio_base;
|
||||
}
|
||||
|
||||
// This call takes a good while and is run in a seperate thread (look a few lines above. The lambda function)
|
||||
int returnCode = system(ss.str().c_str());
|
||||
|
||||
// Fetch new instance
|
||||
// Don't ask me why the old one isn't valid anymore -.-
|
||||
for (std::size_t i = 0; i < unfinishedCache.size(); i++)
|
||||
if (unfinishedCache[i].tubio_id == tubioId)
|
||||
entry = &unfinishedCache[i];
|
||||
|
||||
if (returnCode == 0)
|
||||
{
|
||||
// Download succeeded
|
||||
entry->status = DOWNLOAD_STATUS::FINISHED;
|
||||
entry->download_progress = 100;
|
||||
|
||||
shouldSave = true;
|
||||
}
|
||||
else
|
||||
@ -569,6 +591,25 @@ std::vector<DownloadEntry> DownloadManager::ParseJsonArrayToEntries(const JasonP
|
||||
return entries;
|
||||
}
|
||||
|
||||
std::string DownloadManager::DownloadQualityToStringParams(DOWNLOAD_QUALITY quality)
|
||||
{
|
||||
switch (quality)
|
||||
{
|
||||
case DOWNLOAD_QUALITY::_BEST:
|
||||
return "bestvideo[ext=mp4]+bestaudio";
|
||||
case DOWNLOAD_QUALITY::_1080p:
|
||||
return "bestvideo[ext=mp4][height^<=1080]+bestaudio";
|
||||
case DOWNLOAD_QUALITY::_720p:
|
||||
return "bestvideo[ext=mp4][height^<=720]+bestaudio";
|
||||
case DOWNLOAD_QUALITY::_360p:
|
||||
return "bestvideo[ext=mp4][height^<=360]+bestaudio";
|
||||
case DOWNLOAD_QUALITY::_144p:
|
||||
return "bestvideo[ext=mp4][height^<=144]+bestaudio";
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
void DownloadManager::FetchInformation(std::string url, std::string tubId)
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
@ -23,6 +23,14 @@ namespace Downloader
|
||||
FINISHED,
|
||||
FAILED
|
||||
};
|
||||
enum class DOWNLOAD_QUALITY
|
||||
{
|
||||
_BEST, // best quality
|
||||
_1080p, // 1080p
|
||||
_720p, // 720p
|
||||
_360p, // 360p
|
||||
_144p // 144p
|
||||
};
|
||||
|
||||
class DownloadEntry
|
||||
{
|
||||
@ -41,6 +49,7 @@ namespace Downloader
|
||||
std::string download_url;
|
||||
DOWNLOAD_STATUS status;
|
||||
DOWNLOAD_MODE mode;
|
||||
DOWNLOAD_QUALITY quality;
|
||||
int download_progress;
|
||||
time_t queued_timestamp;
|
||||
|
||||
@ -61,7 +70,7 @@ namespace Downloader
|
||||
/// <param name="url"></param>
|
||||
/// <param name="mode">If video or audio</param>
|
||||
/// <returns>Tubio download id</returns>
|
||||
static std::string QueueDownload(std::string url, DOWNLOAD_MODE mode);
|
||||
static std::string QueueDownload(std::string url, DOWNLOAD_MODE mode, DOWNLOAD_QUALITY quality = DOWNLOAD_QUALITY::_BEST);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the number of videos queued
|
||||
@ -107,7 +116,24 @@ namespace Downloader
|
||||
static void Load();
|
||||
static std::vector<DownloadEntry> ParseJsonArrayToEntries(const JasonPP::JsonArray& arr);
|
||||
|
||||
/// <summary>
|
||||
/// Will return a youtube-dl quality string based on 'quality'
|
||||
/// </summary>
|
||||
/// <param name="quality"></param>
|
||||
/// <returns></returns>
|
||||
static std::string DownloadQualityToStringParams(DOWNLOAD_QUALITY quality);
|
||||
|
||||
/// <summary>
|
||||
/// Will fetch metadata of an url
|
||||
/// </summary>
|
||||
/// <param name="url">Url to fetch from</param>
|
||||
/// <param name="tubId">Tubio id to save data to</param>
|
||||
static void FetchInformation(std::string url, std::string tubId);
|
||||
|
||||
/// <summary>
|
||||
/// Will create an unique tubio id (based on time())
|
||||
/// </summary>
|
||||
/// <returns>Unique tubio id</returns>
|
||||
static std::string CreateNewTubioID();
|
||||
|
||||
/// <summary>
|
||||
|
@ -73,6 +73,7 @@ bool RestQueryHandler::Example_Foo(const JsonBlock& request, JsonBlock& response
|
||||
|
||||
bool RestQueryHandler::QueueDownload(const JsonBlock& request, JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode)
|
||||
{
|
||||
// Fetch parameters
|
||||
if ((!ValidateField("video_url", JDType::STRING, request, responseBody)) ||
|
||||
(!ValidateField("mode", JDType::STRING, request, responseBody)))
|
||||
{
|
||||
@ -80,8 +81,21 @@ bool RestQueryHandler::QueueDownload(const JsonBlock& request, JsonBlock& respon
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string modeParam = request.Get("mode").AsString;
|
||||
std::string videoUrl = request.Get("video_url").AsString;
|
||||
std::string modeParam = request.Get("mode").AsString;
|
||||
std::string qualityParam;
|
||||
|
||||
// 'quality' is an optional parameter. Default value is 'best'
|
||||
if ((ValidateField("quality", JDType::STRING, request, responseBody)))
|
||||
{
|
||||
qualityParam = request.Get("quality").AsString;
|
||||
}
|
||||
else
|
||||
{
|
||||
qualityParam = "best";
|
||||
}
|
||||
|
||||
// Process parameters
|
||||
DOWNLOAD_MODE mode;
|
||||
if (modeParam == "video") mode = DOWNLOAD_MODE::VIDEO;
|
||||
else if (modeParam == "audio") mode = DOWNLOAD_MODE::AUDIO;
|
||||
@ -92,10 +106,27 @@ bool RestQueryHandler::QueueDownload(const JsonBlock& request, JsonBlock& respon
|
||||
return false;
|
||||
}
|
||||
|
||||
DOWNLOAD_QUALITY quality;
|
||||
if (qualityParam == "best")
|
||||
quality = DOWNLOAD_QUALITY::_BEST;
|
||||
else if (qualityParam == "1080p")
|
||||
quality = DOWNLOAD_QUALITY::_1080p;
|
||||
else if (qualityParam == "720p")
|
||||
quality = DOWNLOAD_QUALITY::_720p;
|
||||
else if (qualityParam == "360p")
|
||||
quality = DOWNLOAD_QUALITY::_360p;
|
||||
else if (qualityParam == "144p")
|
||||
quality = DOWNLOAD_QUALITY::_144p;
|
||||
else {
|
||||
responseCode = HTTP_STATUS_CODE::BAD_REQUEST;
|
||||
responseBody.CloneFrom(RestResponseTemplates::GetByCode(HTTP_STATUS_CODE::BAD_REQUEST, "Parameter 'quality' is of wrong value. Choose either 'best', '1080p', '720p', '360p', or '144p'."));
|
||||
return false;
|
||||
}
|
||||
|
||||
log->cout << "Queued video \"" << videoUrl << "\"...";
|
||||
log->Flush();
|
||||
|
||||
std::string tubId = DownloadManager::QueueDownload(videoUrl, mode);
|
||||
std::string tubId = DownloadManager::QueueDownload(videoUrl, mode, quality);
|
||||
|
||||
responseCode = HTTP_STATUS_CODE::OK;
|
||||
responseBody.CloneFrom(RestResponseTemplates::GetByCode(HTTP_STATUS_CODE::OK));
|
||||
|
@ -1,2 +1,2 @@
|
||||
#pragma once
|
||||
#define TUBIO_SERVER_VERSION (0.537)
|
||||
#define TUBIO_SERVER_VERSION (0.538)
|
||||
|
Loading…
x
Reference in New Issue
Block a user