aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/Program.h3
-rw-r--r--include/VideoPlayer.hpp3
-rw-r--r--src/Program.c22
-rw-r--r--src/QuickMedia.cpp61
-rw-r--r--src/VideoPlayer.cpp12
5 files changed, 72 insertions, 29 deletions
diff --git a/include/Program.h b/include/Program.h
index 6a6d038..bc3e91e 100644
--- a/include/Program.h
+++ b/include/Program.h
@@ -2,6 +2,7 @@
#define QUICKMEDIA_PROGRAM_H
#include <sys/types.h>
+#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
@@ -25,6 +26,8 @@ int exec_program(const char **args, ProgramOutputCallback output_callback, void
// Return the exit status, or a negative value if waiting failed
int wait_program(pid_t process_id);
+bool wait_program_non_blocking(pid_t process_id, int *status);
+
/*
@args need to have at least 2 arguments. The first which is the program name
and the last which is NULL, which indicates end of args
diff --git a/include/VideoPlayer.hpp b/include/VideoPlayer.hpp
index 4dc7b53..c5d9cfe 100644
--- a/include/VideoPlayer.hpp
+++ b/include/VideoPlayer.hpp
@@ -31,7 +31,8 @@ namespace QuickMedia {
READ_TIMEOUT,
READ_RESPONSE_ERROR,
READ_INCORRECT_TYPE,
- INIT_FAILED
+ INIT_FAILED,
+ EXITED
};
// @event_callback is called from another thread
diff --git a/src/Program.c b/src/Program.c
index 2c6759e..65164c4 100644
--- a/src/Program.c
+++ b/src/Program.c
@@ -114,6 +114,28 @@ int wait_program(pid_t process_id) {
return WEXITSTATUS(status);
}
+bool wait_program_non_blocking(pid_t process_id, int *status) {
+ int s;
+ int wait_result = waitpid(process_id, &s, WNOHANG);
+ if(wait_result == -1) {
+ perror("waitpid failed");
+ *status = -errno;
+ return false;
+ } else if(wait_result == 0) {
+ /* the child process is still running */
+ *status = 0;
+ return false;
+ }
+
+ if(!WIFEXITED(s)) {
+ *status = -4;
+ return false;
+ }
+
+ *status = WEXITSTATUS(s);
+ return true;
+}
+
int exec_program_async(const char **args, pid_t *result_process_id) {
/* 1 arguments */
if(args[0] == NULL)
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index 2ccb9d6..df5a1e8 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -692,54 +692,34 @@ namespace QuickMedia {
return false;
}
- static bool youtube_dl_can_download_video(const std::string &video_url) {
- const char *args[] = { "youtube-dl", "--skip-download", "--", video_url.c_str(), nullptr };
- return exec_program(args, nullptr, nullptr) == 0;
- }
-
void Program::video_content_page() {
search_bar->onTextUpdateCallback = nullptr;
search_bar->onTextSubmitCallback = nullptr;
Page previous_page = pop_page_stack();
- bool seekable = false;
-
std::unique_ptr<VideoPlayer> video_player;
sf::WindowHandle video_player_window = None;
- auto on_window_create = [this, &video_player, &seekable, &video_player_window](sf::WindowHandle _video_player_window) mutable {
+ auto on_window_create = [this, &video_player_window](sf::WindowHandle _video_player_window) mutable {
video_player_window = _video_player_window;
XSelectInput(disp, video_player_window, KeyPressMask);
XSync(disp, False);
- video_player->is_seekable(&seekable);
};
auto load_video_error_check = [this, &video_player, previous_page]() mutable {
watched_videos.insert(content_url);
- std::string video_url = content_url;
-
- std::string youtube_video_id;
- if(youtube_url_extract_id(video_url, youtube_video_id)) {
- // This can fail for example if the video requires age vertification...
- // TODO: Remove this when youtube-dl is modified to work with videos that require age verification.
- if(!youtube_dl_can_download_video(video_url)) {
- // Im sorry invidio.us server... this will be removed later and it only happens when youtube-dl fails!
- video_url = "https://www.invidio.us/latest_version?id=" + youtube_video_id + "&itag=22";
- }
- }
-
- VideoPlayer::Error err = video_player->load_video(video_url.c_str(), window.getSystemHandle());
+ VideoPlayer::Error err = video_player->load_video(content_url.c_str(), window.getSystemHandle());
if(err != VideoPlayer::Error::OK) {
std::string err_msg = "Failed to play url: ";
- err_msg += video_url;
+ err_msg += content_url;
show_notification("Video player", err_msg.c_str(), Urgency::CRITICAL);
current_page = previous_page;
}
};
bool has_video_started = true;
- video_player = std::make_unique<VideoPlayer>(current_plugin->use_tor, use_system_mpv_config, [this, &video_player, &seekable, &load_video_error_check, previous_page, &has_video_started](const char *event_name) mutable {
+ auto video_event_callback = [this, &video_player, &load_video_error_check, previous_page, &has_video_started](const char *event_name) mutable {
bool end_of_file = false;
if(strcmp(event_name, "pause") == 0) {
double time_remaining = 9999.0;
@@ -747,7 +727,6 @@ namespace QuickMedia {
end_of_file = true;
} else if(strcmp(event_name, "playback-restart") == 0) {
video_player->set_paused(false);
- video_player->is_seekable(&seekable);
} else if(strcmp(event_name, "start-file") == 0) {
has_video_started = true;
}
@@ -774,9 +753,10 @@ namespace QuickMedia {
content_url = std::move(new_video_url);
load_video_error_check();
}
- }, on_window_create);
- load_video_error_check();
+ };
+ video_player = std::make_unique<VideoPlayer>(current_plugin->use_tor, use_system_mpv_config, video_event_callback, on_window_create);
+ load_video_error_check();
sf::Event event;
@@ -806,8 +786,33 @@ namespace QuickMedia {
show_notification("Video player", "Failed to connect to mpv ipc after 5 seconds", Urgency::CRITICAL);
current_page = previous_page;
return;
+ } else if(update_err == VideoPlayer::Error::EXITED) {
+ std::string youtube_video_id;
+ if(youtube_url_extract_id(content_url, youtube_video_id)) {
+ fprintf(stderr, "Failed to play youtube video (maybe because of age verification?), trying with invidio.us...\n");
+ // This can fail for example if the video requires age vertification...
+ // Im sorry invidio.us server... this will be removed later and it only happens when youtube-dl fails!
+ // TODO: Remove this when youtube-dl is modified to work with videos that require age verification.
+ 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);
+
+ std::string new_video_url = "https://www.invidio.us/latest_version?id=" + youtube_video_id + "&itag=22";
+ VideoPlayer::Error err = video_player->load_video(new_video_url.c_str(), window.getSystemHandle());
+ if(err != VideoPlayer::Error::OK) {
+ std::string err_msg = "Failed to play url: ";
+ err_msg += content_url;
+ show_notification("Video player", err_msg.c_str(), Urgency::CRITICAL);
+ current_page = previous_page;
+ }
+ } else {
+ show_notification("Video player", "The video player failed to play the video", Urgency::CRITICAL);
+ current_page = previous_page;
+ return;
+ }
} else if(update_err != VideoPlayer::Error::OK) {
- show_notification("Video player", "Unexpected error while updating", Urgency::CRITICAL);
+ show_notification("Video player", "The video player failed to play the video", Urgency::CRITICAL);
current_page = previous_page;
return;
}
diff --git a/src/VideoPlayer.cpp b/src/VideoPlayer.cpp
index 138f269..6024ca8 100644
--- a/src/VideoPlayer.cpp
+++ b/src/VideoPlayer.cpp
@@ -191,6 +191,18 @@ namespace QuickMedia {
}
}
+ if(video_process_id != -1) {
+ int status;
+ if(wait_program_non_blocking(video_process_id, &status)) {
+ fprintf(stderr, "The video player exited!, status: %d\n", status);
+ close(ipc_socket);
+ remove(ipc_server_path);
+ video_process_id = -1;
+ ipc_socket = -1;
+ return Error::EXITED;
+ }
+ }
+
if(connected_to_ipc && event_callback) {
Error err = read_ipc_func();
if(err != Error::OK)