Episode: Added Downloading Captions With "--captions"
This commit is contained in:
parent
2ade05b175
commit
3a8e904ebb
|
@ -249,6 +249,22 @@ namespace dropout_dl {
|
||||||
return qualities;
|
return qualities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string episode::get_captions_url() {
|
||||||
|
std::string start = "\"lang\":\"en\",\"url\":\"";
|
||||||
|
std::string end = "\",\"kind\":\"captions\"";
|
||||||
|
|
||||||
|
if (this->config_data.find(end) == std::string::npos) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string captions_url = dropout_dl::get_substring_in(this->config_data, start, end);
|
||||||
|
if (this->verbose) {
|
||||||
|
std::cout << "captions url: " << captions_url << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return captions_url;
|
||||||
|
}
|
||||||
|
|
||||||
std::string episode::get_video_url(const std::string& quality) {
|
std::string episode::get_video_url(const std::string& quality) {
|
||||||
for (int i = 0; i < qualities.size(); i++) {
|
for (int i = 0; i < qualities.size(); i++) {
|
||||||
if (qualities[i] == quality) {
|
if (qualities[i] == quality) {
|
||||||
|
@ -300,11 +316,19 @@ namespace dropout_dl {
|
||||||
std::cout << YELLOW << "File already exists: " << filepath << RESET << '\n';
|
std::cout << YELLOW << "File already exists: " << filepath << RESET << '\n';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::fstream out(filepath,
|
std::fstream out(filepath + ".mp4",
|
||||||
std::ios_base::in | std::ios_base::out | std::ios_base::trunc);
|
std::ios_base::in | std::ios_base::out | std::ios_base::trunc);
|
||||||
|
|
||||||
out << this->get_video_data(quality, filepath) << std::endl;
|
out << this->get_video_data(quality, filepath) << std::endl;
|
||||||
|
|
||||||
|
if (!this->captions_url.empty()) {
|
||||||
|
std::fstream captions_file(filepath + ".vtt",
|
||||||
|
std::ios_base::in | std::ios_base::out | std::ios_base::trunc);
|
||||||
|
|
||||||
|
captions_file << get_generic_page(this->captions_url);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
std::cout << GREEN << filepath << RESET;
|
std::cout << GREEN << filepath << RESET;
|
||||||
|
|
||||||
std::cout << '\n';
|
std::cout << '\n';
|
||||||
|
@ -315,14 +339,14 @@ namespace dropout_dl {
|
||||||
if (filename.empty()) {
|
if (filename.empty()) {
|
||||||
if (this->episode_number != 0) {
|
if (this->episode_number != 0) {
|
||||||
if (this->season_number != 0) {
|
if (this->season_number != 0) {
|
||||||
filename = this->series + " - S" + ((this->season_number < 10) ? "0" : "") + std::to_string(this->season_number) + "E" + ((this->episode_number < 10) ? "0" : "") + std::to_string(this->episode_number) + " - " + this->name + ".mp4";
|
filename = this->series + " - S" + ((this->season_number < 10) ? "0" : "") + std::to_string(this->season_number) + "E" + ((this->episode_number < 10) ? "0" : "") + std::to_string(this->episode_number) + " - " + this->name;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
filename = this->series + " - " + this->season + " Episode " + std::to_string(this->episode_number) + " - " + this->name + ".mp4";
|
filename = this->series + " - " + this->season + " Episode " + std::to_string(this->episode_number) + " - " + this->name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
filename = this->series + " - " + this->season + " - " + this->name + ".mp4";
|
filename = this->series + " - " + this->season + " - " + this->name;
|
||||||
}
|
}
|
||||||
filename = format_filename(filename);
|
filename = format_filename(filename);
|
||||||
}
|
}
|
||||||
|
@ -335,6 +359,5 @@ namespace dropout_dl {
|
||||||
} else {
|
} else {
|
||||||
this->download_quality(quality, series_directory, filename);
|
this->download_quality(quality, series_directory, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} // dropout_dl
|
} // dropout_dl
|
||||||
|
|
|
@ -47,6 +47,8 @@ namespace dropout_dl {
|
||||||
std::string embedded_page_data;
|
std::string embedded_page_data;
|
||||||
/// The url for the main config page. This contains page the link to the mp4 video of the episode
|
/// The url for the main config page. This contains page the link to the mp4 video of the episode
|
||||||
std::string config_url;
|
std::string config_url;
|
||||||
|
/// The url for the captions of the episode.
|
||||||
|
std::string captions_url;
|
||||||
/// The data of the main config page. This contains the link to the mp4 video of the episode
|
/// The data of the main config page. This contains the link to the mp4 video of the episode
|
||||||
std::string config_data;
|
std::string config_data;
|
||||||
/// The list of the qualities available for the episode. This is a parallel array with the quality_urls vector
|
/// The list of the qualities available for the episode. This is a parallel array with the quality_urls vector
|
||||||
|
@ -134,6 +136,15 @@ namespace dropout_dl {
|
||||||
*/
|
*/
|
||||||
std::vector<std::string> get_qualities();
|
std::vector<std::string> get_qualities();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return the url for the captions of the episode
|
||||||
|
*
|
||||||
|
* Gets the url for the captions of the episode if possible. If not returns "".
|
||||||
|
*/
|
||||||
|
std::string get_captions_url();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param quality - The quality of the video
|
* @param quality - The quality of the video
|
||||||
|
@ -191,7 +202,7 @@ namespace dropout_dl {
|
||||||
* Create an episode object from the link using to cookies to get all the necessary information.
|
* Create an episode object from the link using to cookies to get all the necessary information.
|
||||||
* This constructor initializes all the object data.
|
* This constructor initializes all the object data.
|
||||||
*/
|
*/
|
||||||
episode(const std::string& episode_url, std::vector<cookie> cookies, const std::string& series, const std::string& season, int episode_number, int season_number, bool verbose = false) {
|
episode(const std::string& episode_url, std::vector<cookie> cookies, const std::string& series, const std::string& season, int episode_number, int season_number, bool verbose = false, bool download_captions = false) {
|
||||||
this->episode_url = episode_url;
|
this->episode_url = episode_url;
|
||||||
this->verbose = verbose;
|
this->verbose = verbose;
|
||||||
|
|
||||||
|
@ -254,6 +265,16 @@ namespace dropout_dl {
|
||||||
|
|
||||||
this->config_data = get_generic_page(this->config_url);
|
this->config_data = get_generic_page(this->config_url);
|
||||||
|
|
||||||
|
if (download_captions) {
|
||||||
|
this->captions_url = get_captions_url();
|
||||||
|
if (verbose) {
|
||||||
|
std::cout << "Got caption url: " << this->captions_url << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this->captions_url = "";
|
||||||
|
}
|
||||||
|
|
||||||
this->get_qualities();
|
this->get_qualities();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,11 +287,10 @@ namespace dropout_dl {
|
||||||
* Create an episode object from the link using to cookies to get all the necessary information.
|
* Create an episode object from the link using to cookies to get all the necessary information.
|
||||||
* This constructor initializes all the object data.
|
* This constructor initializes all the object data.
|
||||||
*/
|
*/
|
||||||
episode(const std::string& episode_url, std::vector<cookie> cookies, bool verbose = false) {
|
episode(const std::string& episode_url, std::vector<cookie> cookies, bool verbose = false, bool download_captions = false) {
|
||||||
|
|
||||||
this->episode_url = episode_url;
|
this->episode_url = episode_url;
|
||||||
this->verbose = verbose;
|
this->verbose = verbose;
|
||||||
|
|
||||||
episode_data = get_episode_page(episode_url, cookies[0].value, cookies[1].value);
|
episode_data = get_episode_page(episode_url, cookies[0].value, cookies[1].value);
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
|
@ -337,6 +357,13 @@ namespace dropout_dl {
|
||||||
|
|
||||||
this->config_data = get_generic_page(this->config_url);
|
this->config_data = get_generic_page(this->config_url);
|
||||||
|
|
||||||
|
if (download_captions) {
|
||||||
|
this->captions_url = get_captions_url();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this->captions_url = "";
|
||||||
|
}
|
||||||
|
|
||||||
this->get_qualities();
|
this->get_qualities();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
src/main.cpp
11
src/main.cpp
|
@ -23,6 +23,7 @@ namespace dropout_dl {
|
||||||
bool is_series = false;
|
bool is_series = false;
|
||||||
bool is_season = false;
|
bool is_season = false;
|
||||||
bool is_episode = false;
|
bool is_episode = false;
|
||||||
|
bool download_captions = false;
|
||||||
std::string quality;
|
std::string quality;
|
||||||
std::string filename;
|
std::string filename;
|
||||||
std::string output_directory;
|
std::string output_directory;
|
||||||
|
@ -107,6 +108,9 @@ namespace dropout_dl {
|
||||||
else if (arg == "episode") {
|
else if (arg == "episode") {
|
||||||
is_episode = true;
|
is_episode = true;
|
||||||
}
|
}
|
||||||
|
else if (arg == "captions") {
|
||||||
|
download_captions = true;
|
||||||
|
}
|
||||||
else if (arg == "help") {
|
else if (arg == "help") {
|
||||||
std::cout << "Usage: dropout-dl [OPTIONS] <url> [OPTIONS]\n"
|
std::cout << "Usage: dropout-dl [OPTIONS] <url> [OPTIONS]\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -121,6 +125,7 @@ namespace dropout_dl {
|
||||||
"\t--force-cookies Interpret the next to arguments as authentication cookie and session cookie\n"
|
"\t--force-cookies Interpret the next to arguments as authentication cookie and session cookie\n"
|
||||||
"\t--series Interpret the url as a link to a series and download all episodes from all seasons\n"
|
"\t--series Interpret the url as a link to a series and download all episodes from all seasons\n"
|
||||||
"\t--season Interpret the url as a link to a season and download all episodes from all seasons\n"
|
"\t--season Interpret the url as a link to a season and download all episodes from all seasons\n"
|
||||||
|
"\t--captions Download the captions along with the episode\n"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
|
@ -385,7 +390,7 @@ int main(int argc, char** argv) {
|
||||||
if (options.verbose) {
|
if (options.verbose) {
|
||||||
std::cout << "Getting series\n";
|
std::cout << "Getting series\n";
|
||||||
}
|
}
|
||||||
dropout_dl::series series(options.url, options.cookies);
|
dropout_dl::series series(options.url, options.cookies, options.download_captions);
|
||||||
|
|
||||||
series.download(options.quality, options.output_directory);
|
series.download(options.quality, options.output_directory);
|
||||||
}
|
}
|
||||||
|
@ -393,7 +398,7 @@ int main(int argc, char** argv) {
|
||||||
if (options.verbose) {
|
if (options.verbose) {
|
||||||
std::cout << "Getting season\n";
|
std::cout << "Getting season\n";
|
||||||
}
|
}
|
||||||
dropout_dl::season season = dropout_dl::series::get_season(options.url, options.cookies);
|
dropout_dl::season season = dropout_dl::series::get_season(options.url, options.cookies, options.download_captions);
|
||||||
|
|
||||||
season.download(options.quality, options.output_directory + "/" + season.series_name);
|
season.download(options.quality, options.output_directory + "/" + season.series_name);
|
||||||
}
|
}
|
||||||
|
@ -401,7 +406,7 @@ int main(int argc, char** argv) {
|
||||||
if (options.verbose) {
|
if (options.verbose) {
|
||||||
std::cout << "Getting episode\n";
|
std::cout << "Getting episode\n";
|
||||||
}
|
}
|
||||||
dropout_dl::episode ep(options.url, options.cookies, options.verbose);
|
dropout_dl::episode ep(options.url, options.cookies, options.verbose, options.download_captions);
|
||||||
|
|
||||||
if (options.verbose) {
|
if (options.verbose) {
|
||||||
std::cout << "filename: " << options.filename << '\n';
|
std::cout << "filename: " << options.filename << '\n';
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace dropout_dl {
|
||||||
for (int j = 0; j + i < html_data.size(); j++) {
|
for (int j = 0; j + i < html_data.size(); j++) {
|
||||||
if (html_data[i + j] == '"') {
|
if (html_data[i + j] == '"') {
|
||||||
start_point += 15;
|
start_point += 15;
|
||||||
return {html_data.substr(i, j), cookies, this->series_name, this->name, episode_number, this->season_number};
|
return episode(html_data.substr(i, j), cookies, this->series_name, this->name, episode_number, this->season_number, false, this->download_captions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@ namespace dropout_dl {
|
||||||
std::string page_data;
|
std::string page_data;
|
||||||
/// The list of all the episodes in the season
|
/// The list of all the episodes in the season
|
||||||
std::vector<episode> episodes;
|
std::vector<episode> episodes;
|
||||||
|
/// Whether or not to download captions
|
||||||
|
bool download_captions;
|
||||||
|
|
||||||
episode get_episode(const std::string& html_data, int& start_point, const std::vector<cookie>& cookies, int episode_number = 0);
|
episode get_episode(const std::string& html_data, int& start_point, const std::vector<cookie>& cookies, int episode_number = 0);
|
||||||
|
|
||||||
|
@ -64,8 +66,9 @@ namespace dropout_dl {
|
||||||
*
|
*
|
||||||
* Creates a season object and populates the needed information.
|
* Creates a season object and populates the needed information.
|
||||||
*/
|
*/
|
||||||
season(const std::string& url, const std::string& name, const std::vector<cookie>& cookies, const std::string& series_name = "") {
|
season(const std::string& url, const std::string& name, const std::vector<cookie>& cookies, const std::string& series_name = "", bool download_captions = false) {
|
||||||
this->url = url;
|
this->url = url;
|
||||||
|
this->download_captions = download_captions;
|
||||||
this->season_number = get_season_number(this->url);
|
this->season_number = get_season_number(this->url);
|
||||||
this->name = name;
|
this->name = name;
|
||||||
this->series_name = series_name;
|
this->series_name = series_name;
|
||||||
|
|
|
@ -115,7 +115,7 @@ namespace dropout_dl {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
season series::get_season(const std::string &url, const std::vector<cookie>& cookies) {
|
season series::get_season(const std::string &url, const std::vector<cookie>& cookies, bool download_captions) {
|
||||||
std::string html_data = get_generic_page(url);
|
std::string html_data = get_generic_page(url);
|
||||||
|
|
||||||
std::string search_class("js-switch-season");
|
std::string search_class("js-switch-season");
|
||||||
|
@ -184,7 +184,7 @@ namespace dropout_dl {
|
||||||
season_name = season_name.substr(name_start,
|
season_name = season_name.substr(name_start,
|
||||||
season_name.size() - name_start - name_end);
|
season_name.size() - name_start - name_end);
|
||||||
|
|
||||||
return {season_url, season_name, cookies, get_series_name(html_data)};
|
return {season_url, season_name, cookies, get_series_name(html_data), download_captions};
|
||||||
}
|
}
|
||||||
|
|
||||||
season_url.clear();
|
season_url.clear();
|
||||||
|
|
|
@ -56,7 +56,7 @@ namespace dropout_dl {
|
||||||
*
|
*
|
||||||
* Gets the season page, which is really just a series page, and creates a season object with all the episodes of the season
|
* Gets the season page, which is really just a series page, and creates a season object with all the episodes of the season
|
||||||
*/
|
*/
|
||||||
static season get_season(const std::string& url, const std::vector<cookie>& cookies);
|
static season get_season(const std::string& url, const std::vector<cookie>& cookies, bool download_captions);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue