From 2030684b16004a4f6c60f499584366ae5ad57bc9 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Tue, 15 Feb 2022 21:52:40 +0100 Subject: Finish video player --- video_player/include/Args.hpp | 136 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 video_player/include/Args.hpp (limited to 'video_player/include/Args.hpp') 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 +#include +#include +#include +#include + +#include +#include + +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 mpv_properties; +}; + +static void usage() { + fprintf(stderr, "usage: quickmedia-video-player [--ipc-fd ] [--audio-file ] [--key=value...] \n"); + fprintf(stderr, " --ipc-fd A bi-directional (socketpair) file descriptor to receive commands from. Optional\n"); + fprintf(stderr, " --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 -- cgit v1.2.3