aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md3
-rw-r--r--TODO3
-rw-r--r--include/VideoPlayer.hpp5
-rw-r--r--input.conf1
-rw-r--r--src/QuickMedia.cpp42
-rw-r--r--src/VideoPlayer.cpp18
6 files changed, 53 insertions, 19 deletions
diff --git a/README.md b/README.md
index f029f03..eb53b29 100644
--- a/README.md
+++ b/README.md
@@ -43,7 +43,8 @@ Press `Middle mouse button` to "autoscroll" in scrolling image view mode.\
Press `Tab` to autocomplete a search when autocomplete is available (currently only available for youtube).\
Press `Tab` to switch between username/password field in login panel.\
Press `Ctrl + V` to paste the content of your clipboard into the search bar.\
-Press `Ctrl + P` to view image/video attached to matrix message.
+Press `Ctrl + P` to view image/video attached to matrix message.\
+Press `Ctrl + S` to copy the url of the currently playing video to the clipboard (with timestamp).
## Video controls
Press `space` to pause/unpause video. `Double-click` video to fullscreen or leave fullscreen.
# Mangadex
diff --git a/TODO b/TODO
index 4cbaef1..03e574e 100644
--- a/TODO
+++ b/TODO
@@ -35,4 +35,5 @@ Support emoji (mainly for matrix), by readding Text code from dchat. Also do the
Also take code from dchat to support gifs (inline in text).
Fix page jumping up/down in image continuous mode when scrolling past images that fail to load / scrolling fast.
Use pixel buffer object for asynchronous texture transfer to gpu? is this necessary?
-When pressing backspace to delete text, auto search will kick in because the key repeat delay is longer on the first key. SearchBar should instead check of key press/key release state. \ No newline at end of file
+When pressing backspace to delete text, auto search will kick in because the key repeat delay is longer on the first key. SearchBar should instead check of key press/key release state.
+Set the thumbnail fallback image dimensions to the image dimensions we get from matrix. That means we can know the dimensions of images in matrix before they have finished downloading. This is good for removing popouts in the body. \ No newline at end of file
diff --git a/include/VideoPlayer.hpp b/include/VideoPlayer.hpp
index 3f3a18c..e4a5610 100644
--- a/include/VideoPlayer.hpp
+++ b/include/VideoPlayer.hpp
@@ -36,7 +36,7 @@ namespace QuickMedia {
};
// @event_callback is called from another thread
- VideoPlayer(bool use_tor, bool use_system_mpv_config, EventCallbackFunc event_callback, VideoPlayerWindowCreateCallback window_create_callback);
+ VideoPlayer(bool use_tor, bool use_system_mpv_config, EventCallbackFunc event_callback, VideoPlayerWindowCreateCallback window_create_callback, const std::string &resource_root);
~VideoPlayer();
VideoPlayer(const VideoPlayer&) = delete;
VideoPlayer& operator=(const VideoPlayer&) = delete;
@@ -50,6 +50,8 @@ namespace QuickMedia {
// Progress is in range [0..1]
Error get_progress(double *result);
+ // Returns time in seconds
+ Error get_time_in_file(double *result);
Error get_time_remaining(double *result);
Error set_paused(bool paused);
@@ -93,5 +95,6 @@ namespace QuickMedia {
ERROR
};
ResponseDataStatus response_data_status;
+ std::string resource_root;
};
}
diff --git a/input.conf b/input.conf
new file mode 100644
index 0000000..768d21a
--- /dev/null
+++ b/input.conf
@@ -0,0 +1 @@
+Ctrl+s ignore \ No newline at end of file
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index cec7531..7c718e5 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -20,6 +20,7 @@
#include "../include/base64_url.hpp"
#include <SFML/Graphics/RectangleShape.hpp>
+#include <SFML/Window/Clipboard.hpp>
#include <SFML/Graphics/Sprite.hpp>
#include <SFML/Graphics/Text.hpp>
#include <SFML/Window/Event.hpp>
@@ -1564,7 +1565,7 @@ namespace QuickMedia {
}
};
- video_player = std::make_unique<VideoPlayer>(current_plugin->use_tor, use_system_mpv_config, video_event_callback, on_window_create);
+ video_player = std::make_unique<VideoPlayer>(current_plugin->use_tor, use_system_mpv_config, video_event_callback, on_window_create, resources_root);
load_video_error_check();
sf::Event event;
@@ -1581,6 +1582,22 @@ namespace QuickMedia {
sf::Clock cursor_hide_timer;
bool is_youtube = current_plugin->name == "youtube";
+ bool is_pornhub = current_plugin->name == "pornhub";
+ bool supports_url_timestamp = is_youtube || is_pornhub;
+
+ auto save_video_url_to_clipboard = [this, &video_player_window, &video_player, &supports_url_timestamp]() {
+ if(!video_player_window)
+ return;
+
+ if(supports_url_timestamp) {
+ double time_in_file;
+ if(video_player->get_time_in_file(&time_in_file) != VideoPlayer::Error::OK)
+ time_in_file = 0.0;
+ sf::Clipboard::setString(content_url + "&t=" + std::to_string((int)time_in_file));
+ } else {
+ sf::Clipboard::setString(content_url);
+ }
+ };
while (current_page == Page::VIDEO_CONTENT) {
while (window.pollEvent(event)) {
@@ -1617,26 +1634,20 @@ namespace QuickMedia {
if(!selected_item)
continue;
- // Make window black while the next video is loading, otherwise it will be stuck at the last view
- related_media_window->clear();
- related_media_window->display();
-
- related_media_window.reset();
related_media_window_visible = false;
-
- video_player_window = None;
- has_video_started = true;
- video_player.reset();
- video_player = std::make_unique<VideoPlayer>(current_plugin->use_tor, use_system_mpv_config, video_event_callback, on_window_create);
+ related_media_window->setVisible(false);
+ has_video_started = false;
content_url = selected_item->url;
content_title = selected_item->get_title();
load_video_error_check();
+ } else if(event.key.code == sf::Keyboard::S && event.key.control) {
+ save_video_url_to_clipboard();
}
}
}
- if(video_player_window && XCheckTypedWindowEvent(disp, video_player_window, KeyPress, &xev)/* && xev.xkey.subwindow == video_player_window*/) {
+ if(video_player_window && XCheckTypedWindowEvent(disp, video_player_window, KeyPress, &xev)/* && xev.xkey.subwindow == video_player_window*/ && !related_media_window_visible) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
KeySym pressed_keysym = XKeycodeToKeysym(disp, xev.xkey.keycode, 0);
@@ -1646,12 +1657,14 @@ namespace QuickMedia {
current_page = previous_page;
} else if(pressed_keysym == XK_f && pressing_ctrl) {
window_set_fullscreen(disp, window.getSystemHandle(), WindowFullscreenState::TOGGLE);
- } else if(pressed_keysym == XK_r && pressing_ctrl && related_media_window && !related_media_window_visible) {
+ } else if(pressed_keysym == XK_r && pressing_ctrl && related_media_window) {
related_media_window_visible = true;
related_media_window->setVisible(related_media_window_visible);
if(!cursor_visible)
window.setMouseCursorVisible(true);
cursor_visible = true;
+ } else if(pressed_keysym == XK_s && pressing_ctrl) {
+ save_video_url_to_clipboard();
}
}
@@ -1668,7 +1681,8 @@ namespace QuickMedia {
show_notification("Video player", "Failed to connect to mpv ipc after 10 seconds", Urgency::CRITICAL);
current_page = previous_page;
break;
- } else if(update_err == VideoPlayer::Error::EXITED && video_player->exit_status == 0) {
+ } else if(update_err == VideoPlayer::Error::EXITED && (video_player->exit_status == 0 || video_player->exit_status == 4)) {
+ // The exit status is 0 when 'q' is used and the exist status is 4 when ctrl+c is used.
fprintf(stderr, "mpv exited with status 0, the user most likely closed mpv with 'q'\n");
current_page = previous_page;
break;
diff --git a/src/VideoPlayer.cpp b/src/VideoPlayer.cpp
index 0811c74..0ad4152 100644
--- a/src/VideoPlayer.cpp
+++ b/src/VideoPlayer.cpp
@@ -18,7 +18,7 @@ const int MAX_RETRIES_CONNECT = 20;
const int READ_TIMEOUT_MS = 200;
namespace QuickMedia {
- VideoPlayer::VideoPlayer(bool use_tor, bool use_system_mpv_config, EventCallbackFunc _event_callback, VideoPlayerWindowCreateCallback _window_create_callback) :
+ VideoPlayer::VideoPlayer(bool use_tor, bool use_system_mpv_config, EventCallbackFunc _event_callback, VideoPlayerWindowCreateCallback _window_create_callback, const std::string &resource_root) :
exit_status(0),
use_tor(use_tor),
use_system_mpv_config(use_system_mpv_config),
@@ -35,7 +35,8 @@ namespace QuickMedia {
request_id(1),
expected_request_id(0),
request_response_data(Json::nullValue),
- response_data_status(ResponseDataStatus::NONE)
+ response_data_status(ResponseDataStatus::NONE),
+ resource_root(resource_root)
{
display = XOpenDisplay(NULL);
if (!display)
@@ -76,6 +77,8 @@ namespace QuickMedia {
std::string wid_arg = "--wid=";
wid_arg += parent_window_str;
+ std::string input_conf = "--input-conf=" + resource_root + "input.conf";
+
// TODO: Resume playback if the last video played matches the first video played next time QuickMedia is launched
args.insert(args.end(), {
"mpv", "--keep-open=yes", input_ipc_server_arg.c_str(),
@@ -83,6 +86,7 @@ namespace QuickMedia {
"--cursor-autohide=no", /* "--no-input-default-bindings", "--input-vo-keyboard=no", "--no-input-cursor", */
"--no-terminal",
"--ytdl-raw-options=sub-lang=\"en,eng,enUS,en-US\",write-sub=",
+ input_conf.c_str(),
wid_arg.c_str()
});
@@ -290,6 +294,16 @@ namespace QuickMedia {
return err;
}
+ VideoPlayer::Error VideoPlayer::get_time_in_file(double *result) {
+ Json::Value time_pos_json;
+ Error err = get_property("time-pos", &time_pos_json, Json::realValue);
+ if(err != Error::OK)
+ return err;
+
+ *result = time_pos_json.asDouble();
+ return err;
+ }
+
VideoPlayer::Error VideoPlayer::get_time_remaining(double *result) {
Json::Value time_remaining_json;
Error err = get_property("time-remaining", &time_remaining_json, Json::realValue);