diff options
-rw-r--r-- | include/QuickMedia.hpp | 2 | ||||
-rw-r--r-- | plugins/Page.hpp | 3 | ||||
-rw-r--r-- | plugins/Soundcloud.hpp | 3 | ||||
-rw-r--r-- | src/QuickMedia.cpp | 24 | ||||
-rw-r--r-- | src/plugins/Soundcloud.cpp | 17 |
5 files changed, 41 insertions, 8 deletions
diff --git a/include/QuickMedia.hpp b/include/QuickMedia.hpp index 51a97b4..8c6b02e 100644 --- a/include/QuickMedia.hpp +++ b/include/QuickMedia.hpp @@ -101,7 +101,7 @@ namespace QuickMedia { void page_loop_render(sf::RenderWindow &window, std::vector<Tab> &tabs, int selected_tab, TabAssociatedData &tab_associated_data, const Json::Value *json_chapters); using PageLoopSubmitHandler = std::function<void(const std::vector<Tab> &new_tabs)>; void page_loop(std::vector<Tab> &tabs, int start_tab_index = 0, PageLoopSubmitHandler after_submit_handler = nullptr); - void video_content_page(VideoPage *video_page, std::string video_title, bool download_if_streaming_fails); + void video_content_page(VideoPage *video_page, std::string video_title, bool download_if_streaming_fails, BodyItems &next_play_items, int play_index); // Returns -1 to go to previous chapter, 0 to stay on same chapter and 1 to go to next chapter int image_page(MangaImagesPage *images_page, Body *chapters_body); void image_continuous_page(MangaImagesPage *images_page); diff --git a/plugins/Page.hpp b/plugins/Page.hpp index f1ef893..803b9e6 100644 --- a/plugins/Page.hpp +++ b/plugins/Page.hpp @@ -100,6 +100,7 @@ namespace QuickMedia { public: VideoPage(Program *program) : Page(program) {} virtual PageTypez get_type() const override { return PageTypez::VIDEO; } + virtual bool autoplay_next_item() { return false; } virtual BodyItems get_related_media(const std::string &url, std::string &channel_url) { (void)url; (void)channel_url; return {}; } virtual std::unique_ptr<Page> create_search_page(Program *program, int &search_delay) { (void)program; (void)search_delay; return nullptr; } virtual std::unique_ptr<Page> create_comments_page(Program *program) { (void)program; return nullptr; } @@ -108,5 +109,7 @@ namespace QuickMedia { // Return nullptr if the service doesn't support channels page virtual std::unique_ptr<LazyFetchPage> create_channels_page(Program *program, const std::string &channel_url) = 0; virtual std::string get_url() = 0; + virtual std::string url_get_playable_url(const std::string &url) { return url; } + virtual bool video_should_be_skipped(const std::string &url) { return false; } }; }
\ No newline at end of file diff --git a/plugins/Soundcloud.hpp b/plugins/Soundcloud.hpp index 4962c04..0d73d36 100644 --- a/plugins/Soundcloud.hpp +++ b/plugins/Soundcloud.hpp @@ -47,9 +47,12 @@ namespace QuickMedia { public: SoundcloudAudioPage(Program *program, const std::string &url) : VideoPage(program), url(url) {} const char* get_title() const override { return ""; } + bool autoplay_next_item() override { return true; } std::unique_ptr<RelatedVideosPage> create_related_videos_page(Program *, const std::string &, const std::string &) override { return nullptr; } std::unique_ptr<LazyFetchPage> create_channels_page(Program *, const std::string &) override { return nullptr; } std::string get_url() override { return url; } + std::string url_get_playable_url(const std::string &url) override; + bool video_should_be_skipped(const std::string &url) override { return url == "track"; } private: std::string url; }; diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index ff78735..cc89146 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -1200,7 +1200,8 @@ namespace QuickMedia { image_board_thread_page(static_cast<ImageBoardThreadPage*>(new_tabs[0].page.get()), new_tabs[0].body.get()); } else if(new_tabs.size() == 1 && new_tabs[0].page->get_type() == PageTypez::VIDEO) { current_page = PageType::VIDEO_CONTENT; - video_content_page(static_cast<VideoPage*>(new_tabs[0].page.get()), selected_item->get_title(), false); + int selected_index = tabs[selected_tab].body->get_selected_item(); + video_content_page(static_cast<VideoPage*>(new_tabs[0].page.get()), selected_item->get_title(), false, tabs[selected_tab].body->items, selected_index); } else if(new_tabs.size() == 1 && new_tabs[0].page->get_type() == PageTypez::CHAT) { body_set_selected_item(tabs[selected_tab].body.get(), selected_item.get()); current_page = PageType::CHAT; @@ -1740,7 +1741,7 @@ namespace QuickMedia { #define CLEANMASK(mask) ((mask) & (ShiftMask|ControlMask|Mod1Mask|Mod4Mask|Mod5Mask)) - void Program::video_content_page(VideoPage *video_page, std::string video_title, bool download_if_streaming_fails) { + void Program::video_content_page(VideoPage *video_page, std::string video_title, bool download_if_streaming_fails, BodyItems &next_play_items, int play_index) { sf::Clock time_watched_timer; bool added_recommendations = false; bool video_loaded = false; @@ -1806,6 +1807,9 @@ namespace QuickMedia { std::unique_ptr<VideoPlayer> video_player; BodyItems related_videos; + if(video_page->autoplay_next_item()) + related_videos.insert(related_videos.end(), next_play_items.begin() + play_index + 1, next_play_items.end()); + std::string channel_url; sf::WindowHandle video_player_window = None; @@ -1839,6 +1843,9 @@ namespace QuickMedia { show_notification("QuickMedia", err_msg.c_str(), Urgency::CRITICAL); current_page = previous_page; } else { + if(video_page->autoplay_next_item()) + return; + channel_url.clear(); // TODO: Remove this and use lazy_fetch instead related_videos = video_page->get_related_media(video_url, channel_url); @@ -2037,7 +2044,7 @@ namespace QuickMedia { // Find video that hasn't been played before in this video session // TODO: Remove duplicates for(auto it = related_videos.begin(), end = related_videos.end(); it != end; ++it) { - if(watched_videos.find((*it)->url) == watched_videos.end()) { + if(watched_videos.find((*it)->url) == watched_videos.end() && !video_page->video_should_be_skipped((*it)->url)) { new_video_url = (*it)->url; new_video_title = (*it)->get_title(); break; @@ -2051,7 +2058,7 @@ namespace QuickMedia { break; } - video_url = std::move(new_video_url); + video_url = video_page->url_get_playable_url(new_video_url); video_title = std::move(new_video_title); load_video_error_check(false); } else if(update_err != VideoPlayer::Error::OK) { @@ -2839,7 +2846,8 @@ namespace QuickMedia { watched_videos.clear(); // TODO: Use real title thread_page->video_url = selected_item->attached_content_url; - video_content_page(thread_page, "No title.webm", true); + BodyItems next_items; + video_content_page(thread_page, "No title.webm", true, next_items, 0); redraw = true; } else { if(downloading_image && load_image_future.valid()) @@ -4133,7 +4141,8 @@ namespace QuickMedia { current_page = PageType::VIDEO_CONTENT; // TODO: Add title video_page->url = url; - video_content_page(video_page.get(), "No title", false); + BodyItems next_items; + video_content_page(video_page.get(), "No title", false, next_items, 0); redraw = true; } else { const char *launch_program = "xdg-open"; @@ -4212,7 +4221,8 @@ namespace QuickMedia { no_video = is_audio; // TODO: Add title video_page->url = selected->url; - video_content_page(video_page.get(), "No title", message_type == MessageType::VIDEO || message_type == MessageType::AUDIO); + BodyItems next_items; + video_content_page(video_page.get(), "No title", message_type == MessageType::VIDEO || message_type == MessageType::AUDIO, next_items, 0); no_video = prev_no_video; redraw = true; return true; diff --git a/src/plugins/Soundcloud.cpp b/src/plugins/Soundcloud.cpp index cfb6011..37538ed 100644 --- a/src/plugins/Soundcloud.cpp +++ b/src/plugins/Soundcloud.cpp @@ -284,4 +284,21 @@ namespace QuickMedia { if(result != DownloadResult::OK) return download_result_to_plugin_result(result); return parse_user_page(json_root, result_items, next_href); } + + std::string SoundcloudAudioPage::url_get_playable_url(const std::string &url) { + std::string query_url = url + "?client_id=" + client_id; + + Json::Value json_root; + DownloadResult result = download_json(json_root, query_url, {}, true); + if(result != DownloadResult::OK) return url; + + if(!json_root.isObject()) + return url; + + const Json::Value &url_json = json_root["url"]; + if(!url_json.isString()) + return url; + + return url_json.asString(); + } }
\ No newline at end of file |