From 66312068bde937b0a5455800d1806e3f3077689c Mon Sep 17 00:00:00 2001 From: dec05eba Date: Mon, 14 Feb 2022 02:38:39 +0100 Subject: Initial video player setup (playing a video with local config and gpu acceleration and window embedding) --- README.md | 3 +- build.sh | 8 ++++ install.sh | 6 +-- project.conf | 1 + video_player/project.conf | 8 ++++ video_player/src/main.cpp | 120 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 141 insertions(+), 5 deletions(-) create mode 100755 build.sh create mode 100644 video_player/project.conf create mode 100644 video_player/src/main.cpp diff --git a/README.md b/README.md index eaf0660..91f89bb 100644 --- a/README.md +++ b/README.md @@ -25,14 +25,13 @@ EXAMPLES: If you are running arch linux then you can install QuickMedia from aur (https://aur.archlinux.org/packages/quickmedia-git/), otherwise you will need to first install [sibs](https://git.dec05eba.com/sibs/) and then run `./install.sh` as root. ## Dependencies ### Libraries -`libglvnd (LibGL.so)`, `libx11`, `libxrandr` +`libglvnd (LibGL.so)`, `libx11`, `libxrandr`, `libmpv` ### Executables `curl` ### Fonts `noto-fonts` (when `use_system_fonts` config is not set to `true`) ### Optional `noto-fonts-cjk` needs to be installed to view chinese, japanese and korean characters (when `use_system_fonts` config is not set to `true`).\ -`mpv` needs to be installed to play videos.\ `youtube-dl` needs to be installed to play/download xxx videos.\ `notify-send` (which is part of `libnotify`) needs to be installed to show notifications (on Linux and other systems that uses d-bus notification system).\ [automedia](https://git.dec05eba.com/AutoMedia/) needs to be installed when tracking manga with `Ctrl + T`.\ diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..1a23f0b --- /dev/null +++ b/build.sh @@ -0,0 +1,8 @@ +#!/bin/sh -e + +script_dir=$(dirname "$0") +cd "$script_dir" + +sibs build --release video_player +sibs build --release +echo "Successfully built the video player and QuickMedia" diff --git a/install.sh b/install.sh index 3c65224..9300df3 100755 --- a/install.sh +++ b/install.sh @@ -1,14 +1,14 @@ -#!/bin/sh - -set -e +#!/bin/sh -e script_dir=$(dirname "$0") cd "$script_dir" [ $(id -u) -ne 0 ] && echo "You need root privileges to run the install script" && exit 1 +sibs build --release video_player sibs build --release +install -Dm755 "video_player/sibs-build/$(sibs platform)/release/quickmedia-video-player" "/usr/bin/quickmedia-video-player" install -Dm755 "sibs-build/$(sibs platform)/release/quickmedia" "/usr/bin/quickmedia" ln -sf "/usr/bin/quickmedia" "/usr/bin/qm" install -Dm644 boards.json "/usr/share/quickmedia/boards.json" diff --git a/project.conf b/project.conf index fbeaa67..b737123 100644 --- a/project.conf +++ b/project.conf @@ -7,6 +7,7 @@ platforms = ["posix"] [config] # This needs to be commented out for now because rapidjson depends on undefined behavior according to gcc... #error_on_warning = "true" +ignore_dirs = ["video_player"] [lang.cpp] version = "c++17" diff --git a/video_player/project.conf b/video_player/project.conf new file mode 100644 index 0000000..b71b204 --- /dev/null +++ b/video_player/project.conf @@ -0,0 +1,8 @@ +[package] +name = "quickmedia-video-player" +type = "executable" +version = "0.1.0" +platforms = ["posix"] + +[dependencies] +mpv = "2" diff --git a/video_player/src/main.cpp b/video_player/src/main.cpp new file mode 100644 index 0000000..3a06f92 --- /dev/null +++ b/video_player/src/main.cpp @@ -0,0 +1,120 @@ +#include +#include +#include +#include +#include + +#include + +static void usage() { + fprintf(stderr, "usage: quickmedia-video-player [--wid ] \n"); + fprintf(stderr, " --wid The window to embed the video player into. 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 inline void check_error(int status) { + if (status < 0) { + fprintf(stderr, "mpv API error: %s\n", mpv_error_string(status)); + exit(2); + } +} + +int main(int argc, char **argv) { + long wid_num = 0; + const char *wid = nullptr; + const char *file_to_play = nullptr; + + for(int i = 1; i < argc; ++i) { + const char *arg = argv[i]; + if(strcmp(arg, "--wid") == 0) { + if(wid) { + fprintf(stderr, "Error: option --wid was specified multiple times\n"); + usage(); + } + + if(i + 1 == argc) { + fprintf(stderr, "Error: missing window id after option --wid\n"); + usage(); + } + + wid = 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(); + } + + file_to_play = argv[i + 1]; + ++i; + } else if(strncmp(arg, "--", 2) == 0) { + fprintf(stderr, "Error: invalid option %s\n", arg); + usage(); + } else { + if(file_to_play) { + fprintf(stderr, "Error: file option was specified multiple times\n"); + usage(); + } + + file_to_play = arg; + } + } + + if(!file_to_play) { + fprintf(stderr, "Error: missing file option\n"); + usage(); + } + + if(wid) { + if(!string_to_long(wid, wid_num)) { + fprintf(stderr, "Error: invalid number %s was specified for option --wid\n", wid); + usage(); + } + } + + mpv_handle *ctx = mpv_create(); + if (!ctx) { + printf("failed creating context\n"); + return 1; + } + + check_error(mpv_set_option_string(ctx, "input-default-bindings", "yes")); + check_error(mpv_set_option_string(ctx, "input-vo-keyboard", "yes")); + check_error(mpv_set_option_string(ctx, "osc", "yes")); + + check_error(mpv_set_option_string(ctx, "profile", "gpu-hq")); + check_error(mpv_set_option_string(ctx, "vo", "gpu")); + check_error(mpv_set_option_string(ctx, "hwdec", "auto")); + check_error(mpv_set_option_string(ctx, "config", "yes")); + + if(wid) + check_error(mpv_set_option_string(ctx, "wid", wid)); + + check_error(mpv_initialize(ctx)); + + const char *cmd[] = { "loadfile", file_to_play, NULL }; + check_error(mpv_command(ctx, cmd)); + + while (true) { + mpv_event *event = mpv_wait_event(ctx, 10000); + printf("event: %s\n", mpv_event_name(event->event_id)); + if (event->event_id == MPV_EVENT_SHUTDOWN) + break; + } + + mpv_terminate_destroy(ctx); + return 0; +} -- cgit v1.2.3