From c9c2621accb68634685a14703491cacdd7ed2bb1 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Thu, 8 Aug 2019 07:26:04 +0200 Subject: Retain fullscreen video when changing to next video --- src/Body.cpp | 22 ++++++----- src/Program.c | 3 +- src/QuickMedia.cpp | 105 +++++++++++++++++++++++++++++++++++----------------- src/VideoPlayer.cpp | 31 ++-------------- 4 files changed, 89 insertions(+), 72 deletions(-) (limited to 'src') diff --git a/src/Body.cpp b/src/Body.cpp index c9fbc89..6051e02 100644 --- a/src/Body.cpp +++ b/src/Body.cpp @@ -54,7 +54,7 @@ namespace QuickMedia { void Body::clear_items() { items.clear(); - item_thumbnail_textures.clear(); + //item_thumbnail_textures.clear(); } BodyItem* Body::get_selected() const { @@ -137,11 +137,8 @@ namespace QuickMedia { if(num_items == 0) return; - if((int)item_thumbnail_textures.size() != num_items) { - // First unload all textures, then prepare to load new textures - item_thumbnail_textures.resize(0); + if((int)item_thumbnail_textures.size() != num_items) item_thumbnail_textures.resize(num_items); - } float row_height = font_height; if(draw_thumbnails) @@ -173,8 +170,15 @@ namespace QuickMedia { float row_height = font_height; if(draw_thumbnails) { row_height = image_height; - if(!item->thumbnail_url.empty() && !item_thumbnail && !loading_thumbnail) - item_thumbnail = load_thumbnail_from_url(item->thumbnail_url); + // TODO: Should this be optimized by instead of checking if url changes based on index, + // put thumbnails in hash map based on url? + if(item->thumbnail_url.empty() && item_thumbnail.texture) { + item_thumbnail.texture = nullptr; + item_thumbnail.url = ""; + } else if(!item->thumbnail_url.empty() && !loading_thumbnail && (!item_thumbnail.texture || item_thumbnail.url != item->url)) { + item_thumbnail.url = item->url; + item_thumbnail.texture = load_thumbnail_from_url(item->thumbnail_url); + } } sf::Vector2f item_pos = pos; @@ -198,8 +202,8 @@ namespace QuickMedia { if(draw_thumbnails) { // TODO: Verify if this is safe. The thumbnail is being modified in another thread // and it might not be fully finished before the native handle is set? - if(item_thumbnail && item_thumbnail->getNativeHandle() != 0) { - image.setTexture(*item_thumbnail, true); + if(item_thumbnail.texture && item_thumbnail.texture->getNativeHandle() != 0) { + image.setTexture(*item_thumbnail.texture, true); auto image_size = image.getTexture()->getSize(); auto height_ratio = image_height / image_size.y; auto scale = image.getScale(); diff --git a/src/Program.c b/src/Program.c index 480f403..731a20e 100644 --- a/src/Program.c +++ b/src/Program.c @@ -39,7 +39,7 @@ int exec_program(const char **args, ProgramOutputCallback output_callback, void char buffer[2048]; for(;;) { - ssize_t bytes_read = read(fd[READ_END], buffer, sizeof(buffer)); + ssize_t bytes_read = read(fd[READ_END], buffer, sizeof(buffer) - 1); if(bytes_read == 0) { break; } else if(bytes_read == -1) { @@ -49,6 +49,7 @@ int exec_program(const char **args, ProgramOutputCallback output_callback, void goto cleanup; } + buffer[bytes_read] = '\0'; if(output_callback && output_callback(buffer, bytes_read, userdata) != 0) break; } diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 4fa5f35..0a34508 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -17,6 +17,7 @@ const sf::Color front_color(43, 45, 47); const sf::Color back_color(33, 35, 37); +const int DOUBLE_CLICK_TIME = 500; namespace QuickMedia { Program::Program() : @@ -319,49 +320,80 @@ namespace QuickMedia { search_bar->onTextUpdateCallback = nullptr; search_bar->onTextSubmitCallback = nullptr; - watched_videos.insert(content_url); - std::unique_ptr video_player = nullptr; - try { - printf("Play video: %s\n", content_url.c_str()); - video_player.reset(new VideoPlayer(&window, window_size.x, window_size.y, content_url.c_str())); - } catch(VideoInitializationException &e) { - show_notification("Video player", "Failed to create video player", Urgency::CRITICAL); - video_player = nullptr; - } + // This variable is needed because calling play_video is not possible in onPlaybackEndedCallback + bool play_next_video = false; - std::vector> related_media = current_plugin->get_related_media(content_url); - bool reload = false; - - if(video_player) { - video_player->onPlaybackEndedCallback = [this, &related_media, &video_player, &reload]() { - std::string new_video_url; - // Find video that hasn't been played before in this video session - for(auto it = related_media.begin(), end = related_media.end(); it != end; ++it) { - if(watched_videos.find((*it)->url) == watched_videos.end()) { - new_video_url = (*it)->url; - related_media.erase(it); - break; - } + auto onPlaybackEndedCallback = [this, &play_next_video]() { + std::string new_video_url; + std::vector> related_media = current_plugin->get_related_media(content_url); + // Find video that hasn't been played before in this video session + for(auto it = related_media.begin(), end = related_media.end(); it != end; ++it) { + if(watched_videos.find((*it)->url) == watched_videos.end()) { + new_video_url = (*it)->url; + break; } + } - // If there are no videos to play, then dont play any... - if(new_video_url.empty()) - return; + // If there are no videos to play, then dont play any... + if(new_video_url.empty()) { + show_notification("Video player", "No more related videos to play"); + return; + } - content_url = std::move(new_video_url); - related_media = current_plugin->get_related_media(content_url); - // TODO: This doesn't seem to work correctly right now, it causes video to become black when changing video (context reset bug). - //video_player->load_file(video_url); - reload = true; - }; - } + content_url = std::move(new_video_url); + play_next_video = true; + // TODO: This doesn't seem to work correctly right now, it causes video to become black when changing video (context reset bug). + //video_player->load_file(video_url); + }; + + std::unique_ptr video_player = nullptr; + auto play_video = [this, &video_player, &onPlaybackEndedCallback]() { + watched_videos.insert(content_url); + try { + printf("Play video: %s\n", content_url.c_str()); + video_player.reset(new VideoPlayer(&window, window_size.x, window_size.y, content_url.c_str())); + video_player->onPlaybackEndedCallback = onPlaybackEndedCallback; + } catch(VideoInitializationException &e) { + show_notification("Video player", "Failed to create video player", Urgency::CRITICAL); + video_player = nullptr; + } + }; + play_video(); - sf::Clock resize_timer; + sf::Clock time_since_last_left_click; + int left_click_counter; + bool video_is_fullscreen = false; sf::Event event; - while (current_page == Page::VIDEO_CONTENT && !reload) { + auto on_doubleclick = [this, &video_is_fullscreen]() { + if(video_is_fullscreen) { + window.create(sf::VideoMode::getDesktopMode(), "QuickMedia", sf::Style::Default); + } else { + window.create(sf::VideoMode::getDesktopMode(), "QuickMedia", sf::Style::Fullscreen); + } + window.setVerticalSyncEnabled(true); + video_is_fullscreen = !video_is_fullscreen; + }; + + while (current_page == Page::VIDEO_CONTENT) { + if(play_next_video) { + play_next_video = false; + play_video(); + } + while (window.pollEvent(event)) { base_event_handler(event, Page::SEARCH_SUGGESTION); + if(event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left) { + if(time_since_last_left_click.restart().asMilliseconds() <= DOUBLE_CLICK_TIME) { + if(++left_click_counter == 2) { + on_doubleclick(); + left_click_counter = 0; + } + } else { + left_click_counter = 1; + } + } + if(video_player) { if(event.type == sf::Event::Resized) video_player->resize(window_size); @@ -374,6 +406,11 @@ namespace QuickMedia { video_player->draw(window); window.display(); } + + if(video_is_fullscreen) { + window.create(sf::VideoMode::getDesktopMode(), "QuickMedia", sf::Style::Default); + window.setVerticalSyncEnabled(true); + } } enum class TrackMediaType { diff --git a/src/VideoPlayer.cpp b/src/VideoPlayer.cpp index 62fc7d2..4c19c61 100644 --- a/src/VideoPlayer.cpp +++ b/src/VideoPlayer.cpp @@ -8,7 +8,6 @@ #include const int UI_VISIBLE_TIMEOUT_MS = 2500; -const int DOUBLE_CLICK_TIME = 500; const auto pause_key = sf::Keyboard::Space; namespace QuickMedia { @@ -61,10 +60,7 @@ namespace QuickMedia { mpvGl(nullptr), context(nullptr), textureBuffer(nullptr), - desired_size(width, height), - left_click_counter(0), - window(_window), - video_is_fullscreen(false) + desired_size(width, height) { //ContextScope context_scope(context.get()); texture.setSmooth(true); @@ -135,12 +131,9 @@ namespace QuickMedia { if(mpv) { //mpv_set_wakeup_callback(mpv, nullptr, nullptr); - //mpv_detach_destroy(mpv); - mpv_terminate_destroy(mpv); + mpv_destroy(mpv); + //mpv_terminate_destroy(mpv); } - - if(video_is_fullscreen) - window->create(sf::VideoMode::getDesktopMode(), "QuickMedia", sf::Style::Default); } void VideoPlayer::handle_event(sf::Event &event) { @@ -150,25 +143,7 @@ namespace QuickMedia { if(event.key.code == pause_key) { mpv_command_string(mpv, "cycle pause"); } - } else if(event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left) { - if(time_since_last_left_click.restart().asMilliseconds() <= DOUBLE_CLICK_TIME) { - if(++left_click_counter == 2) { - on_doubleclick(); - left_click_counter = 0; - } - } else { - left_click_counter = 1; - } - } - } - - void VideoPlayer::on_doubleclick() { - if(video_is_fullscreen) { - window->create(sf::VideoMode::getDesktopMode(), "QuickMedia", sf::Style::Default); - } else { - window->create(sf::VideoMode::getDesktopMode(), "QuickMedia", sf::Style::Fullscreen); } - video_is_fullscreen = !video_is_fullscreen; } void VideoPlayer::setPosition(float x, float y) { -- cgit v1.2.3