aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/Page.hpp4
-rw-r--r--plugins/Youtube.hpp5
-rw-r--r--src/QuickMedia.cpp18
-rw-r--r--src/plugins/Youtube.cpp37
4 files changed, 46 insertions, 18 deletions
diff --git a/plugins/Page.hpp b/plugins/Page.hpp
index 0ed4933..39222b1 100644
--- a/plugins/Page.hpp
+++ b/plugins/Page.hpp
@@ -112,8 +112,10 @@ namespace QuickMedia {
virtual std::unique_ptr<RelatedVideosPage> create_related_videos_page(Program *program) = 0;
// Return nullptr if the service doesn't support channels page
virtual std::unique_ptr<Page> create_channels_page(Program *program, const std::string &channel_url) = 0;
- void set_url(std::string new_url) { url = std::move(new_url); }
+ virtual void set_url(std::string new_url) { url = std::move(new_url); }
std::string get_url() { return url; }
+ // Returns empty string for no timestamp or if the video doesn't support timestamps
+ virtual std::string get_url_timestamp() { return ""; }
// Falls back to |get_url| if this and |get_audio_url| returns empty strings
virtual std::string get_video_url(int max_height, bool &has_embedded_audio) {
(void)max_height;
diff --git a/plugins/Youtube.hpp b/plugins/Youtube.hpp
index 28b50bb..d8c4cc2 100644
--- a/plugins/Youtube.hpp
+++ b/plugins/Youtube.hpp
@@ -132,13 +132,15 @@ namespace QuickMedia {
class YoutubeVideoPage : public VideoPage {
public:
- YoutubeVideoPage(Program *program, std::string url) : VideoPage(program, std::move(url)) {}
+ YoutubeVideoPage(Program *program, std::string url);
const char* get_title() const override { return ""; }
BodyItems get_related_media(const std::string &url) override;
std::unique_ptr<Page> create_search_page(Program *program, int &search_delay) override;
std::unique_ptr<Page> create_comments_page(Program *program) override;
std::unique_ptr<RelatedVideosPage> create_related_videos_page(Program *program) override;
std::unique_ptr<Page> create_channels_page(Program *program, const std::string &channel_url) override;
+ void set_url(std::string new_url) override;
+ std::string get_url_timestamp() override { return timestamp; }
std::string get_video_url(int max_height, bool &has_embedded_audio) override;
std::string get_audio_url() override;
PluginResult load(std::string &title, std::string &channel_url) override;
@@ -147,6 +149,7 @@ namespace QuickMedia {
void parse_format(const Json::Value &format_json, bool is_adaptive);
void parse_formats(const Json::Value &streaming_data_json);
private:
+ std::string timestamp;
std::string xsrf_token;
std::string comments_continuation_token;
std::string hls_manifest_url;
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index 77098a3..5316d3f 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -2383,19 +2383,6 @@ namespace QuickMedia {
download_async_gui(url, file_manager_start_dir.string(), true, audio_only);
}
- static std::string youtube_url_extract_timestamp(const std::string &url) {
- size_t timestamp_start = url.find("t=");
- if(timestamp_start == std::string::npos)
- return "";
-
- timestamp_start += 2;
- size_t timestamp_end = url.find('&');
- if(timestamp_end == std::string::npos)
- timestamp_end = url.size();
-
- return url.substr(timestamp_start, timestamp_end - timestamp_start);
- }
-
bool Program::video_download_if_non_streamable(std::string &video_url, std::string &audio_url, bool &is_audio_only, bool &has_embedded_audio, PageType previous_page) {
Path video_cache_dir = get_cache_dir().join("media");
Path video_path = video_cache_dir;
@@ -2562,8 +2549,8 @@ namespace QuickMedia {
}
const bool is_resume_go_back = !start_time.empty();
- if(is_youtube && start_time.empty())
- start_time = youtube_url_extract_timestamp(video_page->get_url());
+ if(start_time.empty())
+ start_time = video_page->get_url_timestamp();
prev_start_time = start_time;
watched_videos.insert(video_page->get_url());
@@ -2665,7 +2652,6 @@ namespace QuickMedia {
auto save_video_url_to_clipboard = [this, video_page]() {
std::string url = video_page->get_url();
if(video_url_supports_timestamp(url)) {
- // TODO: Remove timestamp (&t= or ?t=) from video_url
double time_in_file = 0.0;
if(video_player && (video_player->get_time_in_file(&time_in_file) != VideoPlayer::Error::OK))
time_in_file = 0.0;
diff --git a/src/plugins/Youtube.cpp b/src/plugins/Youtube.cpp
index d9d9239..924bf14 100644
--- a/src/plugins/Youtube.cpp
+++ b/src/plugins/Youtube.cpp
@@ -1783,6 +1783,43 @@ R"END(
return "";
}
+ static int youtube_url_timestamp_to_seconds(const std::string &timestamp) {
+ int hours = 0;
+ int minutes = 0;
+ int seconds = 0;
+ if(sscanf(timestamp.c_str(), "%dh%dm%d", &hours, &minutes, &seconds) == 3)
+ return (hours * 60 * 60) + (minutes * 60) + seconds;
+ if(sscanf(timestamp.c_str(), "%dm%d", &minutes, &seconds) == 2)
+ return (minutes * 60) + seconds;
+ if(sscanf(timestamp.c_str(), "%d", &seconds) == 1)
+ return seconds;
+ return 0;
+ }
+
+ static void youtube_url_remove_timestamp(std::string &url, std::string &timestamp) {
+ size_t timestamp_start = url.find("&t=");
+ if(timestamp_start == std::string::npos)
+ return;
+
+ size_t timestamp_end = url.find("&", timestamp_start + 3);
+ if(timestamp_end == std::string::npos)
+ timestamp_end = url.size();
+
+ int timestamp_seconds = youtube_url_timestamp_to_seconds(url.substr(timestamp_start + 3, timestamp_end - (timestamp_start + 3)));
+ timestamp = std::to_string(timestamp_seconds);
+ url.erase(timestamp_start, timestamp_end - timestamp_start);
+ return;
+ }
+
+ YoutubeVideoPage::YoutubeVideoPage(Program *program, std::string url) : VideoPage(program, "") {
+ set_url(std::move(url));
+ }
+
+ void YoutubeVideoPage::set_url(std::string new_url) {
+ youtube_url_remove_timestamp(new_url, timestamp);
+ VideoPage::set_url(std::move(new_url));
+ }
+
BodyItems YoutubeVideoPage::get_related_media(const std::string &url) {
BodyItems result_items;