aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2023-11-15 19:01:41 +0100
committerdec05eba <dec05eba@protonmail.com>2023-11-15 19:01:41 +0100
commite90a00764642f79ad61cef8659ce6147299a26d8 (patch)
tree2d999642a88efc3a119eab79d11b43663f76c3dc
parent913e40f114fb6e18f495ca65e5f332ef37a320f9 (diff)
Add < and > to navigate playlist
-rw-r--r--README.md4
-rw-r--r--TODO1
-rw-r--r--src/QuickMedia.cpp163
-rw-r--r--src/plugins/Youtube.cpp39
4 files changed, 122 insertions, 85 deletions
diff --git a/README.md b/README.md
index 4994f83..bb4484d 100644
--- a/README.md
+++ b/README.md
@@ -80,7 +80,9 @@ Type text and then wait and QuickMedia will automatically search.\
`Ctrl+S`: Save the video/music (with dialog).\
`Ctrl+Shift+S`: Save the video/music (without dialog).\
`Ctrl+C`: Copy the url of the currently playing video to the clipboard (with timestamp, if supported).\
-`F5`: Reload the video/music.
+`F5`: Reload the video/music.\
+`<`: Go to the previous video.\
+`>`: Go to the next video.
### Youtube channel controls
`Ctrl+T`: Subscribe/Unsubscribe from the channel.
### Manga search/history/chapters page controls
diff --git a/TODO b/TODO
index e66526c..472a221 100644
--- a/TODO
+++ b/TODO
@@ -293,3 +293,4 @@ Fix youtube age restricted videos.
Direct link to youtube playlist should open the playlist page and select the playlist item.
Support youtube mix. Doesn't work that nicely because the mix playlist doesn't show all items unless you click on the last item and then it will show more items.
Youtube community tab.
+v0.m3u8 doesn't work for some lbry videos (such as https://odysee.com/@MoneroMagazine:9/Privacy-101-w-Luke-Smith:2). Fallback to v1.m3u8 (next track in the master.m3u8 file) in such cases. \ No newline at end of file
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index d145dda..4e0367a 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -3558,6 +3558,72 @@ namespace QuickMedia {
}
};
+ auto play_video = [&](const std::string &new_video_url) {
+ TaskResult get_playable_url_result = run_task_with_loading_screen([video_page, &new_video_url]() {
+ video_page->set_url(video_page->url_get_playable_url(new_video_url));
+ return true;
+ });
+
+ if(get_playable_url_result == TaskResult::CANCEL) {
+ current_page = previous_page;
+ go_to_previous_page = true;
+ return;
+ } else if(get_playable_url_result == TaskResult::FALSE) {
+ show_notification("QuickMedia", "Failed to get playable url", Urgency::CRITICAL);
+ current_page = previous_page;
+ go_to_previous_page = true;
+ return;
+ }
+
+ load_video_error_check("0");
+ };
+
+ auto load_next_page = [&]() -> size_t {
+ if(!parent_body_page)
+ return 0;
+
+ BodyItems new_body_items;
+ const int fetch_page = (*parent_body_page) + 1;
+ TaskResult load_next_page_result = run_task_with_loading_screen([parent_page, parent_page_search, fetch_page, &new_body_items] {
+ if(parent_page->get_page(parent_page_search, fetch_page, new_body_items) != PluginResult::OK) {
+ fprintf(stderr, "Failed to get next page (page %d)\n", fetch_page);
+ return false;
+ }
+ return true;
+ });
+
+ fprintf(stderr, "Finished fetching page %d, num new items: %zu\n", fetch_page, new_body_items.size());
+ size_t num_new_messages = new_body_items.size();
+ if(num_new_messages > 0) {
+ if(parent_body)
+ parent_body->append_items(new_body_items);
+ (*parent_body_page)++;
+ related_videos = std::move(new_body_items);
+ }
+
+ if(load_next_page_result == TaskResult::CANCEL) {
+ current_page = previous_page;
+ go_to_previous_page = true;
+ }
+
+ return num_new_messages;
+ };
+
+ auto play_next_video = [&]() -> bool {
+ if(parent_body->select_next_item(false, true)) {
+ play_video(parent_body->get_selected()->url);
+ return true;
+ } else {
+ if(load_next_page() == 0) {
+ return false;
+ } else {
+ parent_body->select_next_item(false, true);
+ play_video(parent_body->get_selected()->url);
+ return true;
+ }
+ }
+ };
+
idle_active_handler();
while (current_page == PageType::VIDEO_CONTENT && window.is_open() && !go_to_previous_page) {
@@ -3640,6 +3706,20 @@ namespace QuickMedia {
double resume_start_time = 0.0;
video_player->get_time_in_file(&resume_start_time);
load_video_error_check(std::to_string((int)resume_start_time));
+ } else if(pressed_keysym == XK_less) {
+ const bool forward = pressing_shift;
+ if(parent_body && video_page->autoplay_next_item() && video_page->should_autoplay()) {
+ if(forward) {
+ if(!play_next_video())
+ show_notification("QuickMedia", "You have reached the last video in the playlist", Urgency::LOW);
+ } else {
+ if(parent_body->select_previous_item(false, true)) {
+ play_video(parent_body->get_selected()->url);
+ } else {
+ show_notification("QuickMedia", "You have reached the first video in the playlist", Urgency::LOW);
+ }
+ }
+ }
} else if(pressed_keysym == XK_r && pressing_ctrl && !video_page->is_local()) {
cursor_hide_timer.restart();
if(!cursor_visible)
@@ -3778,62 +3858,55 @@ namespace QuickMedia {
}
}
};
- find_next_video();
-
- if(new_video_url.empty() && parent_page && parent_body_page && video_page->autoplay_next_item()) {
- BodyItems new_body_items;
- const int fetch_page = (*parent_body_page) + 1;
- TaskResult load_next_page_result = run_task_with_loading_screen([parent_page, parent_page_search, fetch_page, &new_body_items] {
- if(parent_page->get_page(parent_page_search, fetch_page, new_body_items) != PluginResult::OK) {
- fprintf(stderr, "Failed to get next page (page %d)\n", fetch_page);
- return false;
- }
- return true;
- });
- fprintf(stderr, "Finished fetching page %d, num new items: %zu\n", fetch_page, new_body_items.size());
- size_t num_new_messages = new_body_items.size();
- if(num_new_messages > 0) {
- if(parent_body)
- parent_body->append_items(new_body_items);
- (*parent_body_page)++;
- related_videos = std::move(new_body_items);
- find_next_video();
+ if(parent_body && video_page->autoplay_next_item() && video_page->should_autoplay()) {
+ if(!play_next_video()) {
+ if(!video_page->is_local())
+ show_notification("QuickMedia", "No more related videos to play");
+ current_page = previous_page;
+ go_to_previous_page = true;
+ break;
}
+ } else {
+ find_next_video();
- if(load_next_page_result == TaskResult::CANCEL) {
+ if(new_video_url.empty() && parent_page && parent_body_page && video_page->autoplay_next_item()) {
+ if(load_next_page() > 0) {
+ find_next_video();
+ } else {
+ current_page = previous_page;
+ go_to_previous_page = true;
+ break;
+ }
+ }
+
+ // If there are no videos to play, then dont play any...
+ if(new_video_url.empty()) {
+ if(!video_page->is_local())
+ show_notification("QuickMedia", "No more related videos to play");
current_page = previous_page;
go_to_previous_page = true;
break;
}
- }
- // If there are no videos to play, then dont play any...
- if(new_video_url.empty()) {
- if(!video_page->is_local())
- show_notification("QuickMedia", "No more related videos to play");
- current_page = previous_page;
- go_to_previous_page = true;
- break;
- }
+ TaskResult get_playable_url_result = run_task_with_loading_screen([video_page, &new_video_url]() {
+ video_page->set_url(video_page->url_get_playable_url(new_video_url));
+ return true;
+ });
- TaskResult get_playable_url_result = run_task_with_loading_screen([video_page, &new_video_url]() {
- video_page->set_url(video_page->url_get_playable_url(new_video_url));
- return true;
- });
+ if(get_playable_url_result == TaskResult::CANCEL) {
+ current_page = previous_page;
+ go_to_previous_page = true;
+ break;
+ } else if(get_playable_url_result == TaskResult::FALSE) {
+ show_notification("QuickMedia", "Failed to get playable url", Urgency::CRITICAL);
+ current_page = previous_page;
+ go_to_previous_page = true;
+ break;
+ }
- if(get_playable_url_result == TaskResult::CANCEL) {
- current_page = previous_page;
- go_to_previous_page = true;
- break;
- } else if(get_playable_url_result == TaskResult::FALSE) {
- show_notification("QuickMedia", "Failed to get playable url", Urgency::CRITICAL);
- current_page = previous_page;
- go_to_previous_page = true;
- break;
+ load_video_error_check();
}
-
- load_video_error_check();
} else if(update_err != VideoPlayer::Error::OK) {
show_notification("QuickMedia", "Failed to play the video (error code " + std::to_string((int)update_err) + ")", Urgency::CRITICAL);
current_page = previous_page;
diff --git a/src/plugins/Youtube.cpp b/src/plugins/Youtube.cpp
index d4211b3..2e3a238 100644
--- a/src/plugins/Youtube.cpp
+++ b/src/plugins/Youtube.cpp
@@ -2312,45 +2312,6 @@ namespace QuickMedia {
return PluginResult::OK;
}
- static void playlist_get_items(const Json::Value &json_root, std::unordered_set<std::string> &added_videos, BodyItems &result_items) {
- if(!json_root.isObject())
- return;
-
- const Json::Value *response_json = &json_root["response"];
- if(!response_json->isObject())
- response_json = &json_root;
-
- const Json::Value &contents_json = (*response_json)["contents"];
- if(!contents_json.isObject())
- return;
-
- const Json::Value &tcwnr_json = contents_json["twoColumnWatchNextResults"];
- if(!tcwnr_json.isObject())
- return;
-
- const Json::Value &playlist_json = tcwnr_json["playlist"];
- if(!playlist_json.isObject())
- return;
-
- const Json::Value &playlist_inner_json = playlist_json["playlist"];
- if(!playlist_inner_json.isObject())
- return;
-
- //const Json::Value &title_json = playlist_inner_json["title"];
- const Json::Value &playlist_contents_json = playlist_inner_json["contents"];
- if(!playlist_contents_json.isArray())
- return;
-
- for(const Json::Value &content_json : playlist_contents_json) {
- if(!content_json.isObject())
- continue;
-
- auto body_item = parse_common_video_item(content_json["playlistPanelVideoRenderer"], added_videos);
- if(body_item)
- result_items.push_back(std::move(body_item));
- }
- }
-
YoutubePlaylistPage::YoutubePlaylistPage(Program *program, const std::string &url, std::string title) :
LazyFetchPage(program), title(std::move(title))
{