about summary refs log tree commit diff stats
path: root/crates/libmpv2/src/lib.rs
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2024-08-23 12:57:19 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2024-08-23 12:58:02 +0200
commit0ae5018c33cc4bfe27583c9902472b499f4bd269 (patch)
treeafc2fbfcb126215f47afbc32e555d203d4d6d88c /crates/libmpv2/src/lib.rs
parentchore(yt_dlp/progress_hook): Also consider the `total_bytes_estimate` field (diff)
downloadyt-0ae5018c33cc4bfe27583c9902472b499f4bd269.tar.gz
yt-0ae5018c33cc4bfe27583c9902472b499f4bd269.zip
refactor(libmpv2): Move to the `crates` directory
Diffstat (limited to 'crates/libmpv2/src/lib.rs')
-rw-r--r--crates/libmpv2/src/lib.rs175
1 files changed, 175 insertions, 0 deletions
diff --git a/crates/libmpv2/src/lib.rs b/crates/libmpv2/src/lib.rs
new file mode 100644
index 0000000..4d8d18a
--- /dev/null
+++ b/crates/libmpv2/src/lib.rs
@@ -0,0 +1,175 @@
+// yt - A fully featured command line YouTube client
+//
+// Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of Yt.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+//! This crate provides abstractions for
+//! [libmpv](https://github.com/mpv-player/mpv/tree/master/libmpv) of the
+//! [mpv media player](https://github.com/mpv-player/mpv).
+//!
+//! Libmpv requires `LC_NUMERIC` to be `C`, which should be the default value.
+//!
+//! Most of the documentation is paraphrased or even copied from the
+//! [mpv manual](https://mpv.io/manual/master/),
+//! if any questions arise it will probably answer them in much more depth than this documentation.
+//!
+//! # Examples
+//!
+//! See the 'examples' directory in the crate root.
+
+// Procedure for updating to new libmpv:
+// - make any nessecary API change (if so, bump crate version)
+// - update MPV_CLIENT_API consts in lib.rs
+// - run tests and examples to test whether they still work
+
+#![allow(non_upper_case_globals)]
+
+use std::fmt::Display;
+use std::os::raw as ctype;
+
+pub const MPV_CLIENT_API_MAJOR: ctype::c_ulong = 2;
+pub const MPV_CLIENT_API_MINOR: ctype::c_ulong = 2;
+pub const MPV_CLIENT_API_VERSION: ctype::c_ulong =
+    MPV_CLIENT_API_MAJOR << 16 | MPV_CLIENT_API_MINOR;
+
+mod mpv;
+#[cfg(test)]
+mod tests;
+
+pub use crate::mpv::*;
+
+/// A format mpv can use.
+pub use libmpv2_sys::mpv_format as MpvFormat;
+pub mod mpv_format {
+    pub use libmpv2_sys::mpv_format_MPV_FORMAT_DOUBLE as Double;
+    pub use libmpv2_sys::mpv_format_MPV_FORMAT_FLAG as Flag;
+    pub use libmpv2_sys::mpv_format_MPV_FORMAT_INT64 as Int64;
+    pub use libmpv2_sys::mpv_format_MPV_FORMAT_NODE as Node;
+    pub use libmpv2_sys::mpv_format_MPV_FORMAT_NODE_ARRAY as Array;
+    pub use libmpv2_sys::mpv_format_MPV_FORMAT_NODE_MAP as Map;
+    pub use libmpv2_sys::mpv_format_MPV_FORMAT_NONE as None;
+    pub use libmpv2_sys::mpv_format_MPV_FORMAT_OSD_STRING as OsdString;
+    pub use libmpv2_sys::mpv_format_MPV_FORMAT_STRING as String;
+}
+
+/// An libmpv2_sys mpv error.
+pub use libmpv2_sys::mpv_error as MpvError;
+pub mod mpv_error {
+    pub use libmpv2_sys::mpv_error_MPV_ERROR_AO_INIT_FAILED as AoInitFailed;
+    pub use libmpv2_sys::mpv_error_MPV_ERROR_COMMAND as Command;
+    pub use libmpv2_sys::mpv_error_MPV_ERROR_EVENT_QUEUE_FULL as EventQueueFull;
+    pub use libmpv2_sys::mpv_error_MPV_ERROR_GENERIC as Generic;
+    pub use libmpv2_sys::mpv_error_MPV_ERROR_INVALID_PARAMETER as InvalidParameter;
+    pub use libmpv2_sys::mpv_error_MPV_ERROR_LOADING_FAILED as LoadingFailed;
+    pub use libmpv2_sys::mpv_error_MPV_ERROR_NOMEM as NoMem;
+    pub use libmpv2_sys::mpv_error_MPV_ERROR_NOTHING_TO_PLAY as NothingToPlay;
+    pub use libmpv2_sys::mpv_error_MPV_ERROR_NOT_IMPLEMENTED as NotImplemented;
+    pub use libmpv2_sys::mpv_error_MPV_ERROR_OPTION_ERROR as OptionError;
+    pub use libmpv2_sys::mpv_error_MPV_ERROR_OPTION_FORMAT as OptionFormat;
+    pub use libmpv2_sys::mpv_error_MPV_ERROR_OPTION_NOT_FOUND as OptionNotFound;
+    pub use libmpv2_sys::mpv_error_MPV_ERROR_PROPERTY_ERROR as PropertyError;
+    pub use libmpv2_sys::mpv_error_MPV_ERROR_PROPERTY_FORMAT as PropertyFormat;
+    pub use libmpv2_sys::mpv_error_MPV_ERROR_PROPERTY_NOT_FOUND as PropertyNotFound;
+    pub use libmpv2_sys::mpv_error_MPV_ERROR_PROPERTY_UNAVAILABLE as PropertyUnavailable;
+    pub use libmpv2_sys::mpv_error_MPV_ERROR_SUCCESS as Success;
+    pub use libmpv2_sys::mpv_error_MPV_ERROR_UNINITIALIZED as Uninitialized;
+    pub use libmpv2_sys::mpv_error_MPV_ERROR_UNKNOWN_FORMAT as UnknownFormat;
+    pub use libmpv2_sys::mpv_error_MPV_ERROR_UNSUPPORTED as Unsupported;
+    pub use libmpv2_sys::mpv_error_MPV_ERROR_VO_INIT_FAILED as VoInitFailed;
+}
+
+/// Log verbosity level.
+pub use libmpv2_sys::mpv_log_level as LogLevel;
+pub mod mpv_log_level {
+    pub use libmpv2_sys::mpv_log_level_MPV_LOG_LEVEL_DEBUG as Debug;
+    pub use libmpv2_sys::mpv_log_level_MPV_LOG_LEVEL_ERROR as Error;
+    pub use libmpv2_sys::mpv_log_level_MPV_LOG_LEVEL_FATAL as Fatal;
+    pub use libmpv2_sys::mpv_log_level_MPV_LOG_LEVEL_INFO as Info;
+    pub use libmpv2_sys::mpv_log_level_MPV_LOG_LEVEL_NONE as None;
+    pub use libmpv2_sys::mpv_log_level_MPV_LOG_LEVEL_TRACE as Trace;
+    pub use libmpv2_sys::mpv_log_level_MPV_LOG_LEVEL_V as V;
+    pub use libmpv2_sys::mpv_log_level_MPV_LOG_LEVEL_WARN as Warn;
+}
+
+/// The reason a file stopped.
+#[derive(Debug, Clone, Copy)]
+pub enum EndFileReason {
+    /**
+     * The end of file was reached. Sometimes this may also happen on
+     * incomplete or corrupted files, or if the network connection was
+     * interrupted when playing a remote file. It also happens if the
+     * playback range was restricted with --end or --frames or similar.
+     */
+    Eof,
+
+    /**
+     * Playback was stopped by an external action (e.g. playlist controls).
+     */
+    Stop,
+
+    /**
+     * Playback was stopped by the quit command or player shutdown.
+     */
+    Quit,
+
+    /**
+     * Some kind of error happened that lead to playback abort. Does not
+     * necessarily happen on incomplete or broken files (in these cases, both
+     * MPV_END_FILE_REASON_ERROR or MPV_END_FILE_REASON_EOF are possible).
+     *
+     * mpv_event_end_file.error will be set.
+     */
+    Error,
+
+    /**
+     * The file was a playlist or similar. When the playlist is read, its
+     * entries will be appended to the playlist after the entry of the current
+     * file, the entry of the current file is removed, and a MPV_EVENT_END_FILE
+     * event is sent with reason set to MPV_END_FILE_REASON_REDIRECT. Then
+     * playback continues with the playlist contents.
+     * Since API version 1.18.
+     */
+    Redirect,
+}
+
+impl From<libmpv2_sys::mpv_end_file_reason> for EndFileReason {
+    fn from(value: libmpv2_sys::mpv_end_file_reason) -> Self {
+        match value {
+            0 => Self::Eof,
+            2 => Self::Stop,
+            3 => Self::Quit,
+            4 => Self::Error,
+            5 => Self::Redirect,
+            _ => unreachable!("Other enum variants do not exist yet"),
+        }
+    }
+}
+
+impl Display for EndFileReason {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        match self {
+            EndFileReason::Eof => f.write_str("The end of file was reached.")?,
+            EndFileReason::Error => {
+                f.write_str(
+                    "Playback was stopped by an external action (e.g. playlist controls).",
+                )?;
+            }
+            EndFileReason::Quit => {
+                f.write_str("Playback was stopped by the quit command or player shutdown.")?;
+            }
+            EndFileReason::Redirect => {
+                f.write_str("Some kind of error happened that lead to playback abort.")?;
+            }
+            EndFileReason::Stop => {
+                f.write_str("The file was a playlist or similar.")?;
+            }
+        }
+
+        Ok(())
+    }
+}