aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/Youtube.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/Youtube.cpp')
-rw-r--r--src/plugins/Youtube.cpp54
1 files changed, 44 insertions, 10 deletions
diff --git a/src/plugins/Youtube.cpp b/src/plugins/Youtube.cpp
index d80d86c..2d92cd8 100644
--- a/src/plugins/Youtube.cpp
+++ b/src/plugins/Youtube.cpp
@@ -7,6 +7,7 @@
#include "../../include/VideoPlayer.hpp"
#include "../../include/Utils.hpp"
#include "../../include/Theme.hpp"
+#include "../../plugins/WatchProgress.hpp"
#include <optional>
#include <json/reader.h>
extern "C" {
@@ -1858,6 +1859,30 @@ namespace QuickMedia {
VideoPage::set_url(std::move(new_url));
}
+ std::string YoutubeVideoPage::get_url_timestamp() {
+ if(!timestamp.empty())
+ return timestamp;
+
+ std::string video_id;
+ if(!youtube_url_extract_id(url, video_id)) {
+ fprintf(stderr, "Failed to extract youtube id from %s\n", url.c_str());
+ return "";
+ }
+
+ std::unordered_map<std::string, WatchProgress> watch_progress = get_watch_progress_for_plugin("youtube");
+ auto it = watch_progress.find(video_id);
+ if(it == watch_progress.end())
+ return "";
+
+ // If we are very close to the end then start from the beginning.
+ // This is the same behavior as mpv.
+ // This is better because we dont want the video player to stop immediately after we start playing and we dont get any chance to seek.
+ if(it->second.time_pos_sec + 10.0 >= it->second.duration_sec)
+ return "";
+ else
+ return std::to_string(it->second.time_pos_sec);
+ }
+
BodyItems YoutubeVideoPage::get_related_media(const std::string &url) {
comments_continuation_token.clear();
BodyItems result_items;
@@ -2213,6 +2238,7 @@ namespace QuickMedia {
video_details.author.clear();
video_details.views.clear();
video_details.description.clear();
+ video_details.duration = 0.0;
}
PluginResult YoutubeVideoPage::parse_video_response(const Json::Value &json_root, std::string &title, std::string &channel_url, std::vector<MediaChapter> &chapters, std::string &err_str) {
@@ -2274,11 +2300,18 @@ namespace QuickMedia {
const Json::Value &author_json = video_details_json["author"];
const Json::Value &view_count_json = video_details_json["viewCount"];
const Json::Value &short_description_json = video_details_json["shortDescription"];
+ const Json::Value &length_seconds_json = video_details_json["lengthSeconds"];
if(title_json.isString()) video_details.title = title_json.asString();
if(author_json.isString()) video_details.author = author_json.asString();
if(view_count_json.isString()) video_details.views = view_count_json.asString();
if(short_description_json.isString()) video_details.description = short_description_json.asString();
+ if(length_seconds_json.isString()) {
+ const char *length_seconds_str = length_seconds_json.asCString();
+ int duration = 0;
+ to_num(length_seconds_str, strlen(length_seconds_str), duration);
+ video_details.duration = duration;
+ }
title = video_details.title;
if(!video_details.description.empty())
@@ -2333,7 +2366,7 @@ namespace QuickMedia {
return PluginResult::OK;
}
- PluginResult YoutubeVideoPage::load(std::string &title, std::string &channel_url, std::vector<MediaChapter> &chapters, std::string &err_str) {
+ PluginResult YoutubeVideoPage::load(std::string &title, std::string &channel_url, double &duration, std::vector<MediaChapter> &chapters, std::string &err_str) {
std::string video_id;
if(!youtube_url_extract_id(url, video_id)) {
fprintf(stderr, "Failed to extract youtube id from %s\n", url.c_str());
@@ -2408,6 +2441,7 @@ R"END(
PluginResult result = parse_video_response(json_root, title, channel_url, chapters, err_str);
if(result == PluginResult::OK) {
err_str.clear();
+ duration = video_details.duration;
return PluginResult::OK;
}
}
@@ -2483,15 +2517,6 @@ R"END(
if(!format.isObject())
continue;
- if(is_adaptive) {
- // TODO: Fix. Some streams use &sq=num instead of index
- const Json::Value &index_range_json = format["indexRange"];
- if(index_range_json.isNull()) {
- fprintf(stderr, "Ignoring adaptive stream without indexRange\n");
- continue;
- }
- }
-
// TODO: Support HDR?
const Json::Value &quality_label_json = format["qualityLabel"];
if(quality_label_json.isString() && strstr(quality_label_json.asCString(), "HDR")) continue;
@@ -2574,4 +2599,13 @@ R"END(
const Json::Value &adaptive_formats_json = streaming_data_json["adaptiveFormats"];
parse_format(adaptive_formats_json, true);
}
+
+ void YoutubeVideoPage::set_watch_progress(int64_t time_pos_sec, int64_t duration_sec) {
+ std::string video_id;
+ if(!youtube_url_extract_id(url, video_id)) {
+ show_notification("QuickMedia", "Failed to extract youtube id from " + url);
+ return;
+ }
+ set_watch_progress_for_plugin("youtube", video_id, time_pos_sec, duration_sec, video_id);
+ }
}