aboutsummaryrefslogtreecommitdiff
path: root/video_player/include
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2022-02-15 21:52:40 +0100
committerdec05eba <dec05eba@protonmail.com>2022-02-16 02:07:21 +0100
commit2030684b16004a4f6c60f499584366ae5ad57bc9 (patch)
treed22d30f8f41b05f75999369c05a6654fe87e5581 /video_player/include
parent4efce988240473a84a19dc2d378289b875d99a9e (diff)
Finish video player
Diffstat (limited to 'video_player/include')
-rw-r--r--video_player/include/Args.hpp136
-rw-r--r--video_player/include/Utils.hpp30
2 files changed, 166 insertions, 0 deletions
diff --git a/video_player/include/Args.hpp b/video_player/include/Args.hpp
new file mode 100644
index 0000000..610f0b0
--- /dev/null
+++ b/video_player/include/Args.hpp
@@ -0,0 +1,136 @@
+#pragma once
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <string>
+#include <vector>
+
+struct MpvProperty {
+ std::string key;
+ std::string value;
+};
+
+struct Args {
+ long wid_num = 0;
+ long ipc_fd_num = 0;
+
+ const char *ipc_fd = nullptr;
+ const char *audio_file = nullptr;
+ const char *file_to_play = nullptr;
+
+ std::vector<MpvProperty> mpv_properties;
+};
+
+static void usage() {
+ fprintf(stderr, "usage: quickmedia-video-player [--ipc-fd <fd>] [--audio-file <audio_file>] [--key=value...] <file>\n");
+ fprintf(stderr, " --ipc-fd <fd> A bi-directional (socketpair) file descriptor to receive commands from. Optional\n");
+ fprintf(stderr, " --audio-file <audio_file> Load the given audio file. Optional\n");
+ fprintf(stderr, " --key=value Additional options in the format --key=value are passed directly to mpv as string properties. Optional\n");
+ fprintf(stderr, "examples:\n");
+ fprintf(stderr, " quickmedia-video-player video.mp4\n");
+ fprintf(stderr, " quickmedia-video-player --wid 30481231 -- video.mp4\n");
+ exit(1);
+}
+
+static bool string_to_long(const char *str, long &result) {
+ errno = 0;
+ char *endptr = NULL;
+ result = strtol(str, &endptr, 0);
+ return endptr != str && errno == 0;
+}
+
+static bool string_to_double(const char *str, double &result) {
+ errno = 0;
+ char *endptr = NULL;
+ result = strtod(str, &endptr);
+ return endptr != str && errno == 0;
+}
+
+static bool fd_is_valid(int fd) {
+ errno = 0;
+ return fcntl(fd, F_GETFD) != -1 && errno != EBADF;
+}
+
+static Args parse_args(int argc, char **argv) {
+ Args args;
+
+ for(int i = 1; i < argc; ++i) {
+ const char *arg = argv[i];
+ if(strcmp(arg, "--audio-file") == 0) {
+ if(args.audio_file) {
+ fprintf(stderr, "Error: option --audio-file was specified multiple times\n");
+ usage();
+ }
+
+ if(i + 1 == argc) {
+ fprintf(stderr, "Error: missing audio file after option --audio-file\n");
+ usage();
+ }
+
+ args.audio_file = argv[i + 1];
+ ++i;
+ } else if(strcmp(arg, "--ipc-fd") == 0) {
+ if(args.ipc_fd) {
+ fprintf(stderr, "Error: option --ipc-fd was specified multiple times\n");
+ usage();
+ }
+
+ if(i + 1 == argc) {
+ fprintf(stderr, "Error: missing fd after option --ipc-fd\n");
+ usage();
+ }
+
+ args.ipc_fd = argv[i + 1];
+ ++i;
+ } else if(strcmp(arg, "--") == 0) {
+ if(i + 1 == argc) {
+ fprintf(stderr, "Error: missing file option after --\n");
+ usage();
+ } else if(i + 1 != argc - 1) {
+ fprintf(stderr, "Error: more than one option was specified after --\n");
+ usage();
+ }
+
+ args.file_to_play = argv[i + 1];
+ ++i;
+ } else if(strncmp(arg, "--", 2) == 0) {
+ const char *equal_p = strchr(arg, '=');
+ if(!equal_p) {
+ fprintf(stderr, "Error: mpv option %s is missing \"=\"\n", arg);
+ usage();
+ }
+
+ args.mpv_properties.push_back({ std::string(arg + 2, equal_p - (arg + 2)), equal_p + 1 });
+ } else {
+ if(args.file_to_play) {
+ fprintf(stderr, "Error: file option was specified multiple times\n");
+ usage();
+ }
+
+ args.file_to_play = arg;
+ }
+ }
+
+ if(!args.file_to_play) {
+ fprintf(stderr, "Error: missing file option\n");
+ usage();
+ }
+
+ if(args.ipc_fd) {
+ if(!string_to_long(args.ipc_fd, args.ipc_fd_num)) {
+ fprintf(stderr, "Error: invalid number %s was specified for option --ipc-fd\n", args.ipc_fd);
+ usage();
+ }
+
+ if(!fd_is_valid(args.ipc_fd_num)) {
+ fprintf(stderr, "Error: invalid fd %s was specified for option --ipc-fd\n", args.ipc_fd);
+ usage();
+ }
+ }
+
+ return args;
+} \ No newline at end of file
diff --git a/video_player/include/Utils.hpp b/video_player/include/Utils.hpp
new file mode 100644
index 0000000..a5219f4
--- /dev/null
+++ b/video_player/include/Utils.hpp
@@ -0,0 +1,30 @@
+#pragma once
+
+#include <unistd.h>
+#include <errno.h>
+
+static ssize_t read_eintr(int fd, void *buffer, size_t size) {
+ while(true) {
+ ssize_t bytes_read = read(fd, buffer, size);
+ if(bytes_read == -1) {
+ if(errno != EINTR)
+ return -1;
+ } else {
+ return bytes_read;
+ }
+ }
+}
+
+static ssize_t write_all(int fd, const void *buffer, size_t size) {
+ ssize_t bytes_written = 0;
+ while((size_t)bytes_written < size) {
+ ssize_t written = write(fd, (char*)buffer + bytes_written, size - bytes_written);
+ if(written == -1) {
+ if(errno != EINTR)
+ return -1;
+ } else {
+ bytes_written += written;
+ }
+ }
+ return bytes_written;
+} \ No newline at end of file