From d37b3a7aac87e5f60c49202c824d985e53b7b544 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Mon, 14 Jun 2021 07:22:05 +0200 Subject: Rework around mpv issue: reload video if frozen after seek. Add f5 to reload video, readd video cache --- README.md | 3 +- TODO | 6 +- include/QuickMedia.hpp | 1 + include/VideoPlayer.hpp | 10 +- src/QuickMedia.cpp | 289 +++++++++++++++++++++++++++--------------------- src/VideoPlayer.cpp | 49 ++------ 6 files changed, 181 insertions(+), 177 deletions(-) diff --git a/README.md b/README.md index 0a356ad..ca9ca43 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,8 @@ Type text and then wait and QuickMedia will automatically search.\ `Ctrl+F`: Toggle between fullscreen mode and window mode. `Esc` can also be used to switch from fullscreen mode to window mode.\ `Ctrl+R`: Show pages related to the video, such as comments, related videos or channel videos (if supported).\ `Ctrl+S`: Save the video/music.\ -`Ctrl+C`: Copy the url of the currently playing video to the clipboard (with timestamp, if supported). +`Ctrl+C`: Copy the url of the currently playing video to the clipboard (with timestamp, if supported).\ +`F5`: Reload the video/music. ### Youtube channel controls `Ctrl+T`: Subscribe/Unsubscribe from the channel. ### Manga page view controls diff --git a/TODO b/TODO index f97cbd1..ee42725 100644 --- a/TODO +++ b/TODO @@ -164,8 +164,6 @@ Reload youtube video url if the video is idle for too long. The video url is onl Improve live stream startup time by downloading the video formats in parts instead of the hls manifest? Add youtube chapters. Disable drop shadow on pinephone. ---resume-playback doesn't seem to work with the new youtube code. Or maybe --save-position-on-quit fails? Load the next page in chapter list when reaching the bottom (when going to previous chapters in image view). -Seeking too much breaks mpv when playing youtube. It takes 30 seconds or something to resume! -Re-enable video cache which was disabled because youtube seeking freezes for up to 20 seconds when its used! -Loading image background should be rounded. \ No newline at end of file +Loading image background should be rounded. +Workaround mpv issue where video is frozen after seeking (with and without cache enabled, but more often with cache enabled). \ No newline at end of file diff --git a/include/QuickMedia.hpp b/include/QuickMedia.hpp index 8be6fa5..70d3637 100644 --- a/include/QuickMedia.hpp +++ b/include/QuickMedia.hpp @@ -115,6 +115,7 @@ namespace QuickMedia { // Returns false if the page loop was escaped by user navigation (pressing escape) or if there was an error at startup bool page_loop(std::vector &tabs, int start_tab_index = 0, PageLoopSubmitHandler after_submit_handler = nullptr); void video_page_download_video(const std::string &url, bool use_youtube_dl, sf::WindowHandle video_player_window = None); + bool video_download_if_non_streamable(std::string &video_url, std::string &audio_url, bool &is_audio_only, bool &has_embedded_audio, PageType previous_page); void video_content_page(Page *parent_page, VideoPage *video_page, std::string video_title, bool download_if_streaming_fails, BodyItems &next_play_items, int play_index, int *parent_body_page = nullptr, const std::string &parent_page_search = ""); // 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); diff --git a/include/VideoPlayer.hpp b/include/VideoPlayer.hpp index 1e40de1..a7906a2 100644 --- a/include/VideoPlayer.hpp +++ b/include/VideoPlayer.hpp @@ -35,34 +35,30 @@ namespace QuickMedia { }; // @event_callback is called from another thread - VideoPlayer(bool no_video, bool use_system_mpv_config, bool resume_playback, bool keep_open, EventCallbackFunc event_callback, VideoPlayerWindowCreateCallback window_create_callback, const std::string &resource_root, int monitor_height); + VideoPlayer(bool no_video, bool use_system_mpv_config, bool keep_open, EventCallbackFunc event_callback, VideoPlayerWindowCreateCallback window_create_callback, const std::string &resource_root, int monitor_height); ~VideoPlayer(); VideoPlayer(const VideoPlayer&) = delete; VideoPlayer& operator=(const VideoPlayer&) = delete; // |audio_path| is only set when video and audio are separate files/urls. - // |start_time| is ignored if |resume_playback| is true. - Error load_video(const char *path, const char *audio_path, sf::WindowHandle parent_window, const std::string &plugin_name, const std::string &title, const std::string &start_time = ""); + Error load_video(const char *path, const char *audio_path, sf::WindowHandle parent_window, bool is_youtube, const std::string &title, const std::string &start_time = ""); // Should be called every update frame Error update(); // Returns time in seconds Error get_time_in_file(double *result); - Error quit_and_save_watch_later(); - Error set_property(const std::string &property_name, const Json::Value &value); Error get_property(const std::string &property_name, Json::Value *result, Json::ValueType result_type); int exit_status; private: Error send_command(const char *cmd, size_t size); - Error launch_video_process(const char *path, const char *audio_path, sf::WindowHandle parent_window, const std::string &plugin_name, const std::string &title, const std::string &start_time); + Error launch_video_process(const char *path, const char *audio_path, sf::WindowHandle parent_window, bool is_youtube, const std::string &title, const std::string &start_time); VideoPlayer::Error read_ipc_func(); private: bool no_video; bool use_system_mpv_config; - bool resume_playback; bool keep_open; pid_t video_process_id; bool connected_to_ipc; diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index c81d59d..c6a1d2f 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -2376,6 +2376,76 @@ namespace QuickMedia { 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; + SHA256 sha256; + sha256.add(video_url.data(), video_url.size()); + video_path.join(sha256.getHash()); + + if(get_file_type(video_path) == FileType::REGULAR) { + fprintf(stderr, "%s is found in cache. Playing from cache...\n", video_url.c_str()); + video_url = std::move(video_path.data); + audio_url.clear(); + if(no_video) { + is_audio_only = true; + has_embedded_audio = false; + } else { + is_audio_only = false; + has_embedded_audio = true; + } + } else { + TaskResult video_is_not_streamble_result = run_task_with_loading_screen([video_url]() { + return video_url_is_non_streamable_mp4(video_url.c_str()); + }); + + if(video_is_not_streamble_result == TaskResult::TRUE) { + fprintf(stderr, "%s is detected to be a non-streamable mp4 file, downloading it before playing it...\n", video_url.c_str()); + if(create_directory_recursive(video_cache_dir) != 0) { + show_notification("QuickMedia", "Failed to create video cache directory", Urgency::CRITICAL); + current_page = previous_page; + go_to_previous_page = true; + return false; + } + + TaskResult download_file_result = run_task_with_loading_screen([&video_path, video_url]() { + return download_to_file(video_url, video_path.data, {}, true) == DownloadResult::OK; + }); + switch(download_file_result) { + case TaskResult::TRUE: { + video_url = std::move(video_path.data); + audio_url.clear(); + if(no_video) { + is_audio_only = true; + has_embedded_audio = false; + } else { + is_audio_only = false; + has_embedded_audio = true; + } + break; + } + case TaskResult::FALSE: { + show_notification("QuickMedia", "Failed to download " + video_url, Urgency::CRITICAL); + current_page = previous_page; + go_to_previous_page = true; + return false; + } + case TaskResult::CANCEL: { + current_page = previous_page; + go_to_previous_page = true; + return false; + } + } + } else if(video_is_not_streamble_result == TaskResult::CANCEL) { + current_page = previous_page; + go_to_previous_page = true; + return false; + } + } + + return true; + } + #define CLEANMASK(mask) ((mask) & (ShiftMask|ControlMask|Mod1Mask|Mod4Mask|Mod5Mask)) void Program::video_content_page(Page *parent_page, VideoPage *video_page, std::string video_title, bool download_if_streaming_fails, BodyItems &next_play_items, int play_index, int *parent_body_page, const std::string &parent_page_search) { @@ -2406,127 +2476,77 @@ namespace QuickMedia { std::function video_event_callback; bool go_to_previous_page = false; - auto load_video_error_check = [this, &video_title, &video_tasks, &channel_url, previous_page, &go_to_previous_page, &time_watched_timer, &video_loaded, video_page, &video_event_callback, &on_window_create, &video_player_window, is_youtube, is_matrix, download_if_streaming_fails](bool resume_video) mutable { + std::string video_url; + std::string audio_url; + + bool in_seeking = false; + sf::Clock seeking_start_timer; + const float seeking_restart_timeout_sec = 4.0f; // TODO: Test if this timeout is good on slow hardware such as pinephone and slow internet + + auto load_video_error_check = [this, &in_seeking, &video_url, &audio_url, &video_title, &video_tasks, &channel_url, previous_page, &go_to_previous_page, &time_watched_timer, &video_loaded, video_page, &video_event_callback, &on_window_create, &video_player_window, is_youtube, is_matrix, download_if_streaming_fails](std::string start_time = "", bool reuse_media_source = false) mutable { video_player.reset(); channel_url.clear(); video_loaded = false; + in_seeking = false; video_player_window = None; - - std::string new_title; - TaskResult load_result = run_task_with_loading_screen([video_page, &new_title, &channel_url]() { - return video_page->load(new_title, channel_url) == PluginResult::OK; - }); - - if(!new_title.empty()) - video_title = std::move(new_title); - - if(load_result == TaskResult::CANCEL) { - current_page = previous_page; - go_to_previous_page = true; - return; - } else if(load_result == TaskResult::FALSE) { - show_notification("QuickMedia", "Failed to load media", Urgency::CRITICAL); - current_page = previous_page; - go_to_previous_page = true; - return; - } bool is_audio_only = no_video; bool has_embedded_audio = true; const int largest_monitor_height = get_largest_monitor_height(disp); - std::string video_url = video_page->get_video_url(largest_monitor_height, has_embedded_audio); - std::string audio_url; - if(video_url.empty() || no_video) { - video_url = video_page->get_audio_url(); - if(video_url.empty()) { - video_url = video_page->get_url(); - has_embedded_audio = true; - } else { - is_audio_only = true; - has_embedded_audio = false; - } - } else if(!has_embedded_audio) { - audio_url = video_page->get_audio_url(); - } - - bool video_url_is_local = false; - if(!is_youtube && download_if_streaming_fails) { - Path video_cache_dir = get_cache_dir().join("media"); - Path video_path = video_cache_dir; - SHA256 sha256; - sha256.add(video_url.data(), video_url.size()); - video_path.join(sha256.getHash()); - if(get_file_type(video_path) == FileType::REGULAR) { - fprintf(stderr, "%s is found in cache. Playing from cache...\n", video_url.c_str()); - video_url = std::move(video_path.data); - video_url_is_local = true; - audio_url.clear(); - if(no_video) { + + if(!reuse_media_source) { + std::string new_title; + TaskResult load_result = run_task_with_loading_screen([video_page, &new_title, &channel_url]() { + return video_page->load(new_title, channel_url) == PluginResult::OK; + }); + + if(!new_title.empty()) + video_title = std::move(new_title); + + if(load_result == TaskResult::CANCEL) { + current_page = previous_page; + go_to_previous_page = true; + return; + } else if(load_result == TaskResult::FALSE) { + show_notification("QuickMedia", "Failed to load media", Urgency::CRITICAL); + current_page = previous_page; + go_to_previous_page = true; + return; + } + + video_url.clear(); + audio_url.clear(); + if(!no_video) + video_url = video_page->get_video_url(largest_monitor_height, has_embedded_audio); + + if(video_url.empty() || no_video) { + video_url = video_page->get_audio_url(); + if(video_url.empty()) { + video_url = video_page->get_url(); + has_embedded_audio = true; + } else { is_audio_only = true; has_embedded_audio = false; - } else { - is_audio_only = false; - has_embedded_audio = true; } - } else { - TaskResult video_is_not_streamble_result = run_task_with_loading_screen([video_url]() { - return video_url_is_non_streamable_mp4(video_url.c_str()); - }); - if(video_is_not_streamble_result == TaskResult::TRUE) { - fprintf(stderr, "%s is detected to be a non-streamable mp4 file, downloading it before playing it...\n", video_url.c_str()); - if(create_directory_recursive(video_cache_dir) != 0) { - show_notification("QuickMedia", "Failed to create video cache directory", Urgency::CRITICAL); - current_page = previous_page; - go_to_previous_page = true; - return; - } + } else if(!has_embedded_audio) { + audio_url = video_page->get_audio_url(); + } - TaskResult download_file_result = run_task_with_loading_screen([&video_path, video_url]() { - return download_to_file(video_url, video_path.data, {}, true) == DownloadResult::OK; - }); - switch(download_file_result) { - case TaskResult::TRUE: { - video_url = std::move(video_path.data); - video_url_is_local = true; - audio_url.clear(); - if(no_video) { - is_audio_only = true; - has_embedded_audio = false; - } else { - is_audio_only = false; - has_embedded_audio = true; - } - break; - } - case TaskResult::FALSE: { - show_notification("QuickMedia", "Failed to download " + video_url, Urgency::CRITICAL); - current_page = previous_page; - go_to_previous_page = true; - return; - } - case TaskResult::CANCEL: { - current_page = previous_page; - go_to_previous_page = true; - return; - } - } - } else if(video_is_not_streamble_result == TaskResult::CANCEL) { - current_page = previous_page; - go_to_previous_page = true; + if(!is_youtube && download_if_streaming_fails) { + if(!video_download_if_non_streamable(video_url, audio_url, is_audio_only, has_embedded_audio, previous_page)) return; - } } } - std::string start_time; - if(is_youtube) + 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()); time_watched_timer.restart(); watched_videos.insert(video_page->get_url()); - video_player = std::make_unique(is_audio_only, use_system_mpv_config, resume_video, is_matrix && !is_youtube, video_event_callback, on_window_create, resources_root, largest_monitor_height); - VideoPlayer::Error err = video_player->load_video(video_url.c_str(), audio_url.c_str(), window.getSystemHandle(), plugin_name, video_title, start_time); + video_player = std::make_unique(is_audio_only, use_system_mpv_config, is_matrix && !is_youtube, video_event_callback, on_window_create, resources_root, largest_monitor_height); + VideoPlayer::Error err = video_player->load_video(video_url.c_str(), audio_url.c_str(), window.getSystemHandle(), is_youtube, video_title, start_time); if(err != VideoPlayer::Error::OK) { std::string err_msg = "Failed to play url: "; err_msg += video_page->get_url(); @@ -2537,15 +2557,17 @@ namespace QuickMedia { if(video_page->autoplay_next_item()) return; - std::string url = video_page->get_url(); - video_tasks = AsyncTask([video_page, url]() { - BodyItems related_videos = video_page->get_related_media(url); - video_page->mark_watched(); - return related_videos; - }); + if(!is_resume_go_back) { + std::string url = video_page->get_url(); + video_tasks = AsyncTask([video_page, url]() { + BodyItems related_videos = video_page->get_related_media(url); + video_page->mark_watched(); + return related_videos; + }); + } // TODO: Make this also work for other video plugins - if(strcmp(plugin_name, "youtube") != 0 || resume_video) + if(strcmp(plugin_name, "youtube") != 0 || is_resume_go_back) return; std::string video_id; @@ -2580,29 +2602,35 @@ namespace QuickMedia { } }; - video_event_callback = [this, &time_watched_timer, &video_loaded](const char *event_name) mutable { + video_event_callback = [&time_watched_timer, &video_loaded, &in_seeking, &seeking_start_timer](const char *event_name) mutable { + if(strcmp(event_name, "seek") == 0) { + in_seeking = true; + seeking_start_timer.restart(); + } + if(strcmp(event_name, "pause") == 0) { //double time_remaining = 9999.0; //if(video_player->get_time_remaining(&time_remaining) == VideoPlayer::Error::OK && time_remaining <= 1.0) // end_of_file = true; } else if(strcmp(event_name, "playback-restart") == 0) { //video_player->set_paused(false); + in_seeking = false; } else if(strcmp(event_name, "file-loaded") == 0) { time_watched_timer.restart(); - if(!video_loaded) - video_player->set_property("no-resume-playback", true); video_loaded = true; + in_seeking = false; } else if(strcmp(event_name, "video-reconfig") == 0 || strcmp(event_name, "audio-reconfig") == 0) { if(!video_loaded) { video_loaded = true; time_watched_timer.restart(); } + in_seeking = false; } //fprintf(stderr, "event name: %s\n", event_name); }; - load_video_error_check(false); + load_video_error_check(); sf::Event event; @@ -2647,11 +2675,13 @@ namespace QuickMedia { window_set_fullscreen(disp, window.getSystemHandle(), WindowFullscreenState::TOGGLE); } else if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::C && event.key.control) { save_video_url_to_clipboard(); + } else if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::F5) { + load_video_error_check(); } } handle_window_close(); - if(video_player_window && XCheckTypedWindowEvent(disp, video_player_window, KeyPress, &xev)/* && xev.xkey.subwindow == video_player_window*/) { + if(video_player && video_player_window && XCheckTypedWindowEvent(disp, video_player_window, KeyPress, &xev)/* && xev.xkey.subwindow == video_player_window*/) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" KeySym pressed_keysym = XKeycodeToKeysym(disp, xev.xkey.keycode, 0); @@ -2669,6 +2699,11 @@ namespace QuickMedia { window_set_fullscreen(disp, window.getSystemHandle(), WindowFullscreenState::TOGGLE); } else if(pressed_keysym == XK_s && pressing_ctrl) { video_page_download_video(video_page->get_url(), !is_matrix || is_youtube, video_player_window); + } else if(pressed_keysym == XK_F5) { + in_seeking = false; + 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_r && pressing_ctrl) { bool cancelled = false; if(video_tasks.valid()) { @@ -2726,19 +2761,11 @@ namespace QuickMedia { } bool page_changed = false; - page_loop(tabs, 1, [this, &page_changed](const std::vector &new_tabs) { + double resume_start_time = 0.0; + page_loop(tabs, 1, [this, &page_changed, &resume_start_time](const std::vector &new_tabs) { if(!page_changed && new_tabs.size() == 1 && new_tabs[0].page->get_type() == PageTypez::VIDEO) { - window.setMouseCursorVisible(true); - if(video_player) { - video_player->quit_and_save_watch_later(); - while(true) { - VideoPlayer::Error update_err = video_player->update(); - if(update_err != VideoPlayer::Error::OK || !window.isOpen() || current_page == PageType::EXIT) - break; - std::this_thread::sleep_for(std::chrono::milliseconds(20)); - } - video_player.reset(); - } + video_player->get_time_in_file(&resume_start_time); + video_player.reset(); page_changed = true; } }); @@ -2750,7 +2777,7 @@ namespace QuickMedia { if(!video_player) { current_page = PageType::VIDEO_CONTENT; - load_video_error_check(true); + load_video_error_check(resume_start_time > 0.1 ? std::to_string((int)resume_start_time) : ""); } else { XMapWindow(disp, video_player_window); XSync(disp, False); @@ -2770,6 +2797,16 @@ namespace QuickMedia { cursor_visible = true; } + // TODO: Remove the need for this. This is needed right now because mpv sometimes gets stuck when playing youtube videos after seeking too much + if(is_youtube && video_player && in_seeking && seeking_start_timer.getElapsedTime().asSeconds() >= seeking_restart_timeout_sec) { + in_seeking = false; + double resume_start_time = 0.0; + if(video_player->get_time_in_file(&resume_start_time) == VideoPlayer::Error::OK) { + // TODO: Set the second argument to false if the video url is no longer valid (or always?) + load_video_error_check(std::to_string((int)resume_start_time), true); + } + } + VideoPlayer::Error update_err = video_player ? video_player->update() : VideoPlayer::Error::OK; if(update_err == VideoPlayer::Error::FAIL_TO_CONNECT_TIMEOUT) { show_notification("QuickMedia", "Failed to connect to mpv ipc after 10 seconds", Urgency::CRITICAL); @@ -2863,7 +2900,7 @@ namespace QuickMedia { break; } - load_video_error_check(false); + 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/VideoPlayer.cpp b/src/VideoPlayer.cpp index 0df4108..fe4643e 100644 --- a/src/VideoPlayer.cpp +++ b/src/VideoPlayer.cpp @@ -20,11 +20,10 @@ const int MAX_RETRIES_CONNECT = 1000; const int READ_TIMEOUT_MS = 200; namespace QuickMedia { - VideoPlayer::VideoPlayer(bool no_video, bool use_system_mpv_config, bool resume_playback, bool keep_open, EventCallbackFunc _event_callback, VideoPlayerWindowCreateCallback _window_create_callback, const std::string &resource_root, int monitor_height) : + VideoPlayer::VideoPlayer(bool no_video, bool use_system_mpv_config, bool keep_open, EventCallbackFunc _event_callback, VideoPlayerWindowCreateCallback _window_create_callback, const std::string &resource_root, int monitor_height) : exit_status(0), no_video(no_video), use_system_mpv_config(use_system_mpv_config), - resume_playback(resume_playback), keep_open(keep_open), video_process_id(-1), connected_to_ipc(false), @@ -67,7 +66,7 @@ namespace QuickMedia { XCloseDisplay(display); } - VideoPlayer::Error VideoPlayer::launch_video_process(const char *path, const char *audio_path, sf::WindowHandle _parent_window, const std::string &plugin_name, const std::string &title, const std::string &start_time) { + VideoPlayer::Error VideoPlayer::launch_video_process(const char *path, const char *audio_path, sf::WindowHandle _parent_window, bool is_youtube, const std::string &title, const std::string &start_time) { parent_window = _parent_window; if(socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == -1) { @@ -77,10 +76,6 @@ namespace QuickMedia { return Error::FAIL_TO_CREATE_SOCKET; } - Path cookies_filepath; - if(get_cookies_filepath(cookies_filepath, plugin_name) != 0) - fprintf(stderr, "Failed to create %s cookies filepath\n", plugin_name.c_str()); - const std::string parent_window_str = std::to_string(parent_window); std::vector args; @@ -91,19 +86,12 @@ namespace QuickMedia { std::string input_conf = "--input-conf=" + resource_root + "input.conf"; - Path mpv_watch_later_dir = get_storage_dir().join("mpv").join("watch_later"); - if(create_directory_recursive(mpv_watch_later_dir) != 0) - fprintf(stderr, "Failed to create %s watch later directory\n", mpv_watch_later_dir.data.c_str()); - std::string watch_later_dir = "--watch-later-directory=" + mpv_watch_later_dir.data; - std::string ytdl_format; if(no_video) ytdl_format = "--ytdl-format=bestaudio/best"; else ytdl_format = "--ytdl-format=bestvideo[height<=?" + std::to_string(monitor_height) + "]+bestaudio/best"; - std::string cookies_file_arg = "--cookies-file=" + cookies_filepath.data; - // TODO: Resume playback if the last video played matches the first video played next time QuickMedia is launched args.insert(args.end(), { "mpv", @@ -112,13 +100,11 @@ namespace QuickMedia { "--no-terminal", "--save-position-on-quit=yes", "--profile=pseudo-gui", // For gui when playing audio, requires a version of mpv that isn't ancient - watch_later_dir.c_str(), ytdl_format.c_str(), + "--no-resume-playback", // TODO: Disable hr seek on low power devices? "--hr-seek=yes", - "--cache=no", - "--cookies", - cookies_file_arg.c_str(), + //"--cache=no", input_conf.c_str(), wid_arg.c_str() }); @@ -131,10 +117,8 @@ namespace QuickMedia { if(keep_open) args.push_back("--keep-open=yes"); - if(resume_playback) - args.push_back("--resume-playback"); - else - args.push_back("--no-resume-playback"); + if(is_youtube) + args.push_back("--no-ytdl"); if(!use_system_mpv_config) { args.insert(args.end(), { @@ -161,7 +145,7 @@ namespace QuickMedia { } std::string start_time_arg; - if(!resume_playback && !start_time.empty()) { + if(!start_time.empty()) { start_time_arg = "--start=" + start_time; args.push_back(start_time_arg.c_str()); } @@ -184,16 +168,16 @@ namespace QuickMedia { return Error::OK; } - VideoPlayer::Error VideoPlayer::load_video(const char *path, const char *audio_path, sf::WindowHandle _parent_window, const std::string &plugin_name, const std::string &title, const std::string &start_time) { + VideoPlayer::Error VideoPlayer::load_video(const char *path, const char *audio_path, sf::WindowHandle _parent_window, bool is_youtube, const std::string &title, const std::string &start_time) { // This check is to make sure we dont change window that the video belongs to. This is not a usecase we will have so // no need to support it for now at least. assert(parent_window == 0 || parent_window == _parent_window); assert(path); fprintf(stderr, "Playing video: %s, audio: %s\n", path ? path : "", audio_path ? audio_path : ""); if(video_process_id == -1) - return launch_video_process(path, audio_path, _parent_window, plugin_name, title, start_time); + return launch_video_process(path, audio_path, _parent_window, is_youtube, title, start_time); - // TODO: When these are used, add audio_path, title and start_time. Also handle plugin_name + // TODO: When these are used, add audio_path, title and start_time. Also handle is_youtube Json::Value command_data(Json::arrayValue); command_data.append("loadfile"); command_data.append(path); @@ -399,19 +383,6 @@ namespace QuickMedia { return err; } - VideoPlayer::Error VideoPlayer::quit_and_save_watch_later() { - Json::Value command_data(Json::arrayValue); - command_data.append("quit-watch-later"); - Json::Value command(Json::objectValue); - command["command"] = command_data; - - Json::StreamWriterBuilder builder; - builder["commentStyle"] = "None"; - builder["indentation"] = ""; - const std::string cmd_str = Json::writeString(builder, command) + "\n"; - return send_command(cmd_str.c_str(), cmd_str.size()); - } - VideoPlayer::Error VideoPlayer::send_command(const char *cmd, size_t size) { if(!connected_to_ipc) return Error::FAIL_NOT_CONNECTED; -- cgit v1.2.3