diff options
author | dec05eba <dec05eba@protonmail.com> | 2022-02-15 21:52:40 +0100 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2022-02-16 02:07:21 +0100 |
commit | 2030684b16004a4f6c60f499584366ae5ad57bc9 (patch) | |
tree | d22d30f8f41b05f75999369c05a6654fe87e5581 /video_player/include | |
parent | 4efce988240473a84a19dc2d378289b875d99a9e (diff) |
Finish video player
Diffstat (limited to 'video_player/include')
-rw-r--r-- | video_player/include/Args.hpp | 136 | ||||
-rw-r--r-- | video_player/include/Utils.hpp | 30 |
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 |