2017-05-22 18:31:20 +02:00
|
|
|
extern crate serde;
|
|
|
|
extern crate serde_json;
|
|
|
|
|
|
|
|
pub mod ipc;
|
|
|
|
|
|
|
|
use ipc::*;
|
2017-05-24 00:13:23 +02:00
|
|
|
use std::collections::HashMap;
|
2017-05-31 19:32:46 +02:00
|
|
|
use std::fmt::{self, Display};
|
2017-05-29 17:54:12 +02:00
|
|
|
use std::os::unix::net::UnixStream;
|
2017-06-17 13:03:27 +02:00
|
|
|
use std::io::{Read, BufReader};
|
2017-05-24 00:13:23 +02:00
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum Event {
|
|
|
|
Shutdown,
|
|
|
|
// LogMessage {
|
|
|
|
// prefix: &'static str,
|
|
|
|
// level: &'static str,
|
|
|
|
// text: &'static str,
|
|
|
|
// log_level: LogLevel,
|
|
|
|
// },
|
|
|
|
// GetPropertyReply {
|
|
|
|
// name: &'static str,
|
|
|
|
// result: Result<Format<'a>>,
|
|
|
|
// reply_userdata: u32,
|
|
|
|
// },
|
|
|
|
// SetPropertyReply(Result<()>, u32),
|
|
|
|
// CommandReply(Result<()>, u32),
|
|
|
|
StartFile,
|
|
|
|
EndFile,
|
|
|
|
FileLoaded,
|
|
|
|
TracksChanged,
|
|
|
|
TrackSwitched,
|
|
|
|
Idle,
|
|
|
|
Pause,
|
|
|
|
Unpause,
|
|
|
|
Tick,
|
|
|
|
VideoReconfig,
|
|
|
|
AudioReconfig,
|
|
|
|
MetadataUpdate,
|
|
|
|
Seek,
|
|
|
|
PlaybackRestart,
|
2017-06-06 23:08:27 +02:00
|
|
|
PropertyChange {
|
|
|
|
name: String,
|
|
|
|
id: usize,
|
|
|
|
data: MpvDataType,
|
|
|
|
},
|
2017-06-01 19:30:52 +02:00
|
|
|
ChapterChange,
|
|
|
|
Unimplemented,
|
|
|
|
}
|
|
|
|
|
2017-06-06 23:08:27 +02:00
|
|
|
#[derive(Debug)]
|
2017-06-01 19:30:52 +02:00
|
|
|
pub enum MpvDataType {
|
2017-06-17 13:03:27 +02:00
|
|
|
Array(Vec<MpvDataType>),
|
2017-06-01 19:30:52 +02:00
|
|
|
Bool(bool),
|
|
|
|
Double(f64),
|
2017-06-06 23:08:27 +02:00
|
|
|
HashMap(HashMap<String, MpvDataType>),
|
2017-06-17 13:03:27 +02:00
|
|
|
Null,
|
2017-06-01 19:30:52 +02:00
|
|
|
Playlist(Playlist),
|
2017-06-17 13:03:27 +02:00
|
|
|
String(String),
|
|
|
|
Usize(usize),
|
2017-06-01 19:30:52 +02:00
|
|
|
}
|
2017-05-22 18:31:20 +02:00
|
|
|
|
|
|
|
pub enum NumberChangeOptions {
|
|
|
|
Absolute,
|
|
|
|
Increase,
|
|
|
|
Decrease,
|
|
|
|
}
|
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
pub enum PlaylistAddOptions {
|
|
|
|
Replace,
|
|
|
|
Append,
|
|
|
|
AppendPlay,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub enum PlaylistAddTypeOptions {
|
|
|
|
File,
|
|
|
|
Playlist,
|
|
|
|
}
|
|
|
|
|
2017-05-22 18:31:20 +02:00
|
|
|
pub enum SeekOptions {
|
|
|
|
Relative,
|
|
|
|
Absolute,
|
|
|
|
RelativePercent,
|
|
|
|
AbsolutePercent,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub enum Switch {
|
|
|
|
On,
|
|
|
|
Off,
|
|
|
|
Toggle,
|
|
|
|
}
|
|
|
|
|
2017-05-31 19:32:46 +02:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum ErrorCode {
|
|
|
|
MpvError(String),
|
|
|
|
JsonParseError(String),
|
|
|
|
ConnectError(String),
|
2017-06-06 23:08:27 +02:00
|
|
|
JsonContainsUnexptectedType,
|
2017-05-31 19:32:46 +02:00
|
|
|
UnexpectedResult,
|
2017-06-01 19:30:52 +02:00
|
|
|
UnexpectedValue,
|
2017-05-31 19:32:46 +02:00
|
|
|
UnsupportedType,
|
|
|
|
ValueDoesNotContainBool,
|
|
|
|
ValueDoesNotContainF64,
|
|
|
|
ValueDoesNotContainHashMap,
|
|
|
|
ValueDoesNotContainPlaylist,
|
|
|
|
ValueDoesNotContainString,
|
|
|
|
ValueDoesNotContainUsize,
|
|
|
|
}
|
|
|
|
|
2017-06-17 13:03:27 +02:00
|
|
|
pub struct Mpv {
|
|
|
|
stream: UnixStream,
|
|
|
|
reader: BufReader<UnixStream>,
|
|
|
|
}
|
2017-06-06 23:08:27 +02:00
|
|
|
#[derive(Debug)]
|
2017-05-29 17:54:12 +02:00
|
|
|
pub struct Playlist(pub Vec<PlaylistEntry>);
|
2017-05-31 19:32:46 +02:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct Error(pub ErrorCode);
|
2017-05-29 17:54:12 +02:00
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
impl Drop for Mpv {
|
|
|
|
fn drop(&mut self) {
|
2017-06-17 13:03:27 +02:00
|
|
|
self.disconnect();
|
2017-06-01 19:30:52 +02:00
|
|
|
}
|
2017-05-31 19:32:46 +02:00
|
|
|
}
|
|
|
|
|
2017-06-06 23:08:27 +02:00
|
|
|
impl Clone for Mpv {
|
|
|
|
fn clone(&self) -> Self {
|
2017-06-17 13:03:27 +02:00
|
|
|
let stream = self.stream.try_clone().expect("cloning UnixStream");
|
|
|
|
let cloned_stream = stream.try_clone().expect("cloning UnixStream");
|
|
|
|
Mpv {
|
|
|
|
stream,
|
|
|
|
reader: BufReader::new(cloned_stream),
|
|
|
|
}
|
2017-06-06 23:08:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
fn clone_from(&mut self, source: &Self) {
|
2017-06-17 13:03:27 +02:00
|
|
|
let stream = source.stream.try_clone().expect("cloning UnixStream");
|
|
|
|
let cloned_stream = stream.try_clone().expect("cloning UnixStream");
|
|
|
|
*self = Mpv {
|
|
|
|
stream,
|
|
|
|
reader: BufReader::new(cloned_stream),
|
|
|
|
}
|
2017-06-06 23:08:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-31 19:32:46 +02:00
|
|
|
impl Display for Error {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
Display::fmt(&self.0, f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Display for ErrorCode {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match *self {
|
|
|
|
ErrorCode::ConnectError(ref msg) => f.write_str(&format!("ConnectError: {}", msg)),
|
|
|
|
ErrorCode::JsonParseError(ref msg) => f.write_str(&format!("JsonParseError: {}", msg)),
|
2017-07-14 01:21:09 +02:00
|
|
|
ErrorCode::MpvError(ref msg) => f.write_str(&format!("MpvError: {}", msg)),
|
2017-06-06 23:08:27 +02:00
|
|
|
ErrorCode::JsonContainsUnexptectedType => {
|
|
|
|
f.write_str("Mpv sent a value with an unexpected type")
|
|
|
|
}
|
2017-05-31 19:32:46 +02:00
|
|
|
ErrorCode::UnexpectedResult => f.write_str("Unexpected result received"),
|
2017-06-01 19:30:52 +02:00
|
|
|
ErrorCode::UnexpectedValue => f.write_str("Unexpected value received"),
|
2017-05-31 19:32:46 +02:00
|
|
|
ErrorCode::UnsupportedType => f.write_str("Unsupported type received"),
|
|
|
|
ErrorCode::ValueDoesNotContainBool => {
|
|
|
|
f.write_str("The received value is not of type \'std::bool\'")
|
|
|
|
}
|
|
|
|
ErrorCode::ValueDoesNotContainF64 => {
|
|
|
|
f.write_str("The received value is not of type \'std::f64\'")
|
|
|
|
}
|
|
|
|
ErrorCode::ValueDoesNotContainHashMap => {
|
2017-06-17 13:03:27 +02:00
|
|
|
f.write_str(
|
|
|
|
"The received value is not of type \'std::collections::HashMap\'",
|
|
|
|
)
|
2017-05-31 19:32:46 +02:00
|
|
|
}
|
|
|
|
ErrorCode::ValueDoesNotContainPlaylist => {
|
|
|
|
f.write_str("The received value is not of type \'mpvipc::Playlist\'")
|
|
|
|
}
|
|
|
|
ErrorCode::ValueDoesNotContainString => {
|
|
|
|
f.write_str("The received value is not of type \'std::string::String\'")
|
|
|
|
}
|
|
|
|
ErrorCode::ValueDoesNotContainUsize => {
|
|
|
|
f.write_str("The received value is not of type \'std::usize\'")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-05-29 17:54:12 +02:00
|
|
|
}
|
|
|
|
|
2017-05-22 18:31:20 +02:00
|
|
|
pub trait GetPropertyTypeHandler: Sized {
|
2017-05-31 19:32:46 +02:00
|
|
|
fn get_property_generic(instance: &Mpv, property: &str) -> Result<Self, Error>;
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
impl GetPropertyTypeHandler for bool {
|
2017-05-31 19:32:46 +02:00
|
|
|
fn get_property_generic(instance: &Mpv, property: &str) -> Result<bool, Error> {
|
2017-05-29 17:54:12 +02:00
|
|
|
get_mpv_property::<bool>(instance, property)
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl GetPropertyTypeHandler for String {
|
2017-05-31 19:32:46 +02:00
|
|
|
fn get_property_generic(instance: &Mpv, property: &str) -> Result<String, Error> {
|
2017-05-29 17:54:12 +02:00
|
|
|
get_mpv_property::<String>(instance, property)
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl GetPropertyTypeHandler for f64 {
|
2017-05-31 19:32:46 +02:00
|
|
|
fn get_property_generic(instance: &Mpv, property: &str) -> Result<f64, Error> {
|
2017-05-29 17:54:12 +02:00
|
|
|
get_mpv_property::<f64>(instance, property)
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl GetPropertyTypeHandler for usize {
|
2017-05-31 19:32:46 +02:00
|
|
|
fn get_property_generic(instance: &Mpv, property: &str) -> Result<usize, Error> {
|
2017-05-29 17:54:12 +02:00
|
|
|
get_mpv_property::<usize>(instance, property)
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl GetPropertyTypeHandler for Vec<PlaylistEntry> {
|
2017-05-31 19:32:46 +02:00
|
|
|
fn get_property_generic(instance: &Mpv, property: &str) -> Result<Vec<PlaylistEntry>, Error> {
|
2017-05-29 17:54:12 +02:00
|
|
|
get_mpv_property::<Vec<PlaylistEntry>>(instance, property)
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-06 23:08:27 +02:00
|
|
|
impl GetPropertyTypeHandler for HashMap<String, MpvDataType> {
|
2017-06-17 13:03:27 +02:00
|
|
|
fn get_property_generic(
|
|
|
|
instance: &Mpv,
|
|
|
|
property: &str,
|
|
|
|
) -> Result<HashMap<String, MpvDataType>, Error> {
|
2017-06-06 23:08:27 +02:00
|
|
|
get_mpv_property::<HashMap<String, MpvDataType>>(instance, property)
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub trait SetPropertyTypeHandler<T> {
|
2017-05-31 19:32:46 +02:00
|
|
|
fn set_property_generic(instance: &Mpv, property: &str, value: T) -> Result<(), Error>;
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
impl SetPropertyTypeHandler<bool> for bool {
|
2017-05-31 19:32:46 +02:00
|
|
|
fn set_property_generic(instance: &Mpv, property: &str, value: bool) -> Result<(), Error> {
|
2017-05-29 17:54:12 +02:00
|
|
|
set_mpv_property::<bool>(instance, property, value)
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl SetPropertyTypeHandler<String> for String {
|
2017-05-31 19:32:46 +02:00
|
|
|
fn set_property_generic(instance: &Mpv, property: &str, value: String) -> Result<(), Error> {
|
2017-05-29 17:54:12 +02:00
|
|
|
set_mpv_property::<String>(instance, property, value)
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl SetPropertyTypeHandler<f64> for f64 {
|
2017-05-31 19:32:46 +02:00
|
|
|
fn set_property_generic(instance: &Mpv, property: &str, value: f64) -> Result<(), Error> {
|
2017-05-29 17:54:12 +02:00
|
|
|
set_mpv_property::<f64>(instance, property, value)
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl SetPropertyTypeHandler<usize> for usize {
|
2017-05-31 19:32:46 +02:00
|
|
|
fn set_property_generic(instance: &Mpv, property: &str, value: usize) -> Result<(), Error> {
|
2017-05-29 17:54:12 +02:00
|
|
|
set_mpv_property::<usize>(instance, property, value)
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
impl Mpv {
|
|
|
|
pub fn connect(socket: &str) -> Result<Mpv, Error> {
|
|
|
|
match UnixStream::connect(socket) {
|
2017-06-17 13:03:27 +02:00
|
|
|
Ok(stream) => {
|
|
|
|
let cloned_stream = stream.try_clone().expect("cloning UnixStream");
|
|
|
|
return Ok(Mpv {
|
|
|
|
stream,
|
|
|
|
reader: BufReader::new(cloned_stream),
|
|
|
|
});
|
|
|
|
}
|
2017-06-01 19:30:52 +02:00
|
|
|
Err(internal_error) => Err(Error(ErrorCode::ConnectError(internal_error.to_string()))),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-17 13:03:27 +02:00
|
|
|
pub fn disconnect(&self) {
|
|
|
|
let mut stream = &self.stream;
|
|
|
|
stream.shutdown(std::net::Shutdown::Both).expect(
|
|
|
|
"socket disconnect",
|
|
|
|
);
|
|
|
|
let mut buffer = [0; 32];
|
|
|
|
for _ in 0..stream.bytes().count() {
|
|
|
|
stream.read(&mut buffer[..]).unwrap();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_stream_ref(&self) -> &UnixStream {
|
|
|
|
&self.stream
|
|
|
|
}
|
|
|
|
|
2017-06-06 23:08:27 +02:00
|
|
|
pub fn get_metadata(&self) -> Result<HashMap<String, MpvDataType>, Error> {
|
2017-06-01 19:30:52 +02:00
|
|
|
match get_mpv_property(self, "metadata") {
|
|
|
|
Ok(map) => Ok(map),
|
|
|
|
Err(err) => Err(err),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_playlist(&self) -> Result<Playlist, Error> {
|
|
|
|
match get_mpv_property::<Vec<PlaylistEntry>>(self, "playlist") {
|
|
|
|
Ok(entries) => Ok(Playlist(entries)),
|
|
|
|
Err(msg) => Err(msg),
|
|
|
|
}
|
|
|
|
}
|
2017-05-24 00:13:23 +02:00
|
|
|
|
|
|
|
/// #Description
|
|
|
|
///
|
|
|
|
/// Retrieves the property value from mpv.
|
|
|
|
///
|
|
|
|
/// ##Supported types
|
|
|
|
/// - String
|
|
|
|
/// - bool
|
|
|
|
/// - HashMap<String, String> (e.g. for the 'metadata' property)
|
|
|
|
/// - Vec<PlaylistEntry> (for the 'playlist' property)
|
2017-05-29 17:54:12 +02:00
|
|
|
/// - usize
|
|
|
|
/// - f64
|
2017-05-24 00:13:23 +02:00
|
|
|
///
|
|
|
|
/// ##Input arguments
|
|
|
|
///
|
|
|
|
/// - **property** defines the mpv property that should be retrieved
|
|
|
|
///
|
|
|
|
/// #Example
|
|
|
|
/// ```
|
2019-06-18 17:33:34 +02:00
|
|
|
/// # use mpvipc::Mpv;
|
2017-05-29 17:54:12 +02:00
|
|
|
/// let mpv = Mpv::connect("/tmp/mpvsocket").unwrap();
|
2017-05-24 00:13:23 +02:00
|
|
|
/// let paused: bool = mpv.get_property("pause").unwrap();
|
|
|
|
/// let title: String = mpv.get_property("media-title").unwrap();
|
|
|
|
/// ```
|
2017-06-01 19:30:52 +02:00
|
|
|
pub fn get_property<T: GetPropertyTypeHandler>(&self, property: &str) -> Result<T, Error> {
|
|
|
|
T::get_property_generic(self, property)
|
|
|
|
}
|
2017-05-24 00:13:23 +02:00
|
|
|
|
|
|
|
/// #Description
|
|
|
|
///
|
2017-05-31 19:36:12 +02:00
|
|
|
/// Retrieves the property value from mpv.
|
2017-05-24 00:13:23 +02:00
|
|
|
/// The result is always of type String, regardless of the type of the value of the mpv property
|
|
|
|
///
|
|
|
|
/// ##Input arguments
|
|
|
|
///
|
|
|
|
/// - **property** defines the mpv property that should be retrieved
|
|
|
|
///
|
|
|
|
/// #Example
|
|
|
|
///
|
|
|
|
/// ```
|
2019-06-18 17:33:34 +02:00
|
|
|
/// # use mpvipc::Mpv;
|
2017-05-29 17:54:12 +02:00
|
|
|
/// let mpv = Mpv::connect("/tmp/mpvsocket").unwrap();
|
2017-05-24 00:13:23 +02:00
|
|
|
/// let title = mpv.get_property_string("media-title").unwrap();
|
|
|
|
/// ```
|
2017-06-01 19:30:52 +02:00
|
|
|
pub fn get_property_string(&self, property: &str) -> Result<String, Error> {
|
2017-05-22 18:31:20 +02:00
|
|
|
get_mpv_property_string(self, property)
|
|
|
|
}
|
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
pub fn kill(&self) -> Result<(), Error> {
|
2017-05-31 19:32:46 +02:00
|
|
|
run_mpv_command(self, "quit", &[])
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
|
2017-06-06 23:08:27 +02:00
|
|
|
/// #Description
|
|
|
|
///
|
2017-06-17 13:03:27 +02:00
|
|
|
/// Waits until an mpv event occurs and returns the Event.
|
2017-06-06 23:08:27 +02:00
|
|
|
///
|
|
|
|
/// #Example
|
|
|
|
///
|
|
|
|
/// ```
|
2019-06-18 17:33:34 +02:00
|
|
|
/// # use mpvipc::Mpv;
|
|
|
|
/// let mut mpv = Mpv::connect("/tmp/mpvsocket").unwrap();
|
2017-06-06 23:08:27 +02:00
|
|
|
/// loop {
|
2017-06-17 13:03:27 +02:00
|
|
|
/// let event = mpv.event_listen().unwrap();
|
2017-06-06 23:08:27 +02:00
|
|
|
/// println!("{:?}", event);
|
|
|
|
/// }
|
|
|
|
/// ```
|
2017-06-17 13:03:27 +02:00
|
|
|
pub fn event_listen(&mut self) -> Result<Event, Error> {
|
|
|
|
listen(self)
|
2017-05-24 00:13:23 +02:00
|
|
|
}
|
|
|
|
|
2017-06-17 13:03:27 +02:00
|
|
|
pub fn event_listen_raw(&mut self) -> String {
|
|
|
|
listen_raw(self)
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
pub fn next(&self) -> Result<(), Error> {
|
2017-05-31 19:32:46 +02:00
|
|
|
run_mpv_command(self, "playlist-next", &[])
|
|
|
|
}
|
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
pub fn observe_property(&self, id: &usize, property: &str) -> Result<(), Error> {
|
2017-05-24 00:13:23 +02:00
|
|
|
observe_mpv_property(self, id, property)
|
|
|
|
}
|
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
pub fn pause(&self) -> Result<(), Error> {
|
2017-05-22 18:31:20 +02:00
|
|
|
set_mpv_property(self, "pause", true)
|
|
|
|
}
|
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
pub fn prev(&self) -> Result<(), Error> {
|
2017-05-31 19:32:46 +02:00
|
|
|
run_mpv_command(self, "playlist-prev", &[])
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
pub fn restart(&self) -> Result<(), Error> {
|
2017-05-31 19:32:46 +02:00
|
|
|
run_mpv_command(self, "seek", &["0", "absolute"])
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
/// #Description
|
|
|
|
///
|
|
|
|
/// Runs mpv commands. The arguments are passed as a String-Vector reference:
|
|
|
|
///
|
|
|
|
/// ##Input arguments
|
|
|
|
///
|
|
|
|
/// - **command** defines the mpv command that should be executed
|
|
|
|
/// - **args** a slice of &str's which define the arguments
|
|
|
|
///
|
|
|
|
/// #Example
|
|
|
|
/// ```
|
2019-06-18 17:33:34 +02:00
|
|
|
/// # use mpvipc::Mpv;
|
2017-06-01 19:30:52 +02:00
|
|
|
/// let mpv = Mpv::connect("/tmp/mpvsocket").unwrap();
|
|
|
|
///
|
|
|
|
/// //Run command 'playlist-shuffle' which takes no arguments
|
|
|
|
/// mpv.run_command("playlist-shuffle", &[]);
|
|
|
|
///
|
|
|
|
/// //Run command 'seek' which in this case takes two arguments
|
|
|
|
/// mpv.run_command("seek", &["0", "absolute"]);
|
|
|
|
/// ```
|
|
|
|
pub fn run_command(&self, command: &str, args: &[&str]) -> Result<(), Error> {
|
2017-05-22 18:31:20 +02:00
|
|
|
run_mpv_command(self, command, args)
|
|
|
|
}
|
|
|
|
|
2017-06-17 13:03:27 +02:00
|
|
|
pub fn playlist_add(
|
|
|
|
&self,
|
|
|
|
file: &str,
|
|
|
|
file_type: PlaylistAddTypeOptions,
|
|
|
|
option: PlaylistAddOptions,
|
|
|
|
) -> Result<(), Error> {
|
2017-06-01 19:30:52 +02:00
|
|
|
match file_type {
|
|
|
|
PlaylistAddTypeOptions::File => {
|
|
|
|
match option {
|
|
|
|
PlaylistAddOptions::Replace => {
|
|
|
|
run_mpv_command(self, "loadfile", &[file, "replace"])
|
|
|
|
}
|
|
|
|
PlaylistAddOptions::Append => {
|
|
|
|
run_mpv_command(self, "loadfile", &[file, "append"])
|
|
|
|
}
|
|
|
|
PlaylistAddOptions::AppendPlay => {
|
|
|
|
run_mpv_command(self, "loadfile", &[file, "append-play"])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PlaylistAddTypeOptions::Playlist => {
|
|
|
|
match option {
|
|
|
|
PlaylistAddOptions::Replace => {
|
|
|
|
run_mpv_command(self, "loadlist", &[file, "replace"])
|
|
|
|
}
|
|
|
|
PlaylistAddOptions::Append |
|
|
|
|
PlaylistAddOptions::AppendPlay => {
|
|
|
|
run_mpv_command(self, "loadlist", &[file, "append"])
|
|
|
|
}
|
|
|
|
}
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
}
|
2017-06-01 19:30:52 +02:00
|
|
|
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
pub fn playlist_clear(&self) -> Result<(), Error> {
|
2017-05-31 19:32:46 +02:00
|
|
|
run_mpv_command(self, "playlist-clear", &[])
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
pub fn playlist_move_id(&self, from: usize, to: usize) -> Result<(), Error> {
|
2017-06-17 13:03:27 +02:00
|
|
|
run_mpv_command(self, "playlist-move", &[&from.to_string(), &to.to_string()])
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
pub fn playlist_play_id(&self, id: usize) -> Result<(), Error> {
|
2017-05-22 18:31:20 +02:00
|
|
|
set_mpv_property(self, "playlist-pos", id)
|
|
|
|
}
|
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
pub fn playlist_play_next(&self, id: usize) -> Result<(), Error> {
|
2017-05-29 17:54:12 +02:00
|
|
|
match get_mpv_property::<usize>(self, "playlist-pos") {
|
|
|
|
Ok(current_id) => {
|
2017-06-17 13:03:27 +02:00
|
|
|
run_mpv_command(
|
|
|
|
self,
|
|
|
|
"playlist-move",
|
|
|
|
&[&id.to_string(), &(current_id + 1).to_string()],
|
|
|
|
)
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
2017-05-29 17:54:12 +02:00
|
|
|
Err(msg) => Err(msg),
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
pub fn playlist_remove_id(&self, id: usize) -> Result<(), Error> {
|
2017-05-31 19:32:46 +02:00
|
|
|
run_mpv_command(self, "playlist-remove", &[&id.to_string()])
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
pub fn playlist_shuffle(&self) -> Result<(), Error> {
|
2017-05-31 19:32:46 +02:00
|
|
|
run_mpv_command(self, "playlist-shuffle", &[])
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
pub fn seek(&self, seconds: f64, option: SeekOptions) -> Result<(), Error> {
|
2017-05-22 18:31:20 +02:00
|
|
|
match option {
|
|
|
|
SeekOptions::Absolute => {
|
2017-05-31 19:32:46 +02:00
|
|
|
run_mpv_command(self, "seek", &[&seconds.to_string(), "absolute"])
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
SeekOptions::AbsolutePercent => {
|
2017-05-31 19:32:46 +02:00
|
|
|
run_mpv_command(self, "seek", &[&seconds.to_string(), "absolute-percent"])
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
SeekOptions::Relative => {
|
2017-05-31 19:32:46 +02:00
|
|
|
run_mpv_command(self, "seek", &[&seconds.to_string(), "relative"])
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
SeekOptions::RelativePercent => {
|
2017-05-31 19:32:46 +02:00
|
|
|
run_mpv_command(self, "seek", &[&seconds.to_string(), "relative-percent"])
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
pub fn set_loop_file(&self, option: Switch) -> Result<(), Error> {
|
2017-05-22 18:31:20 +02:00
|
|
|
let mut enabled = false;
|
|
|
|
match option {
|
|
|
|
Switch::On => enabled = true,
|
|
|
|
Switch::Off => {}
|
|
|
|
Switch::Toggle => {
|
|
|
|
match get_mpv_property_string(self, "loop-file") {
|
|
|
|
Ok(value) => {
|
|
|
|
match value.as_ref() {
|
|
|
|
"false" => {
|
|
|
|
enabled = true;
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
enabled = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(msg) => return Err(msg),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
set_mpv_property(self, "loop-file", enabled)
|
|
|
|
}
|
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
pub fn set_loop_playlist(&self, option: Switch) -> Result<(), Error> {
|
2017-05-22 18:31:20 +02:00
|
|
|
let mut enabled = false;
|
|
|
|
match option {
|
|
|
|
Switch::On => enabled = true,
|
|
|
|
Switch::Off => {}
|
|
|
|
Switch::Toggle => {
|
|
|
|
match get_mpv_property_string(self, "loop-playlist") {
|
|
|
|
Ok(value) => {
|
|
|
|
match value.as_ref() {
|
|
|
|
"false" => {
|
|
|
|
enabled = true;
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
enabled = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(msg) => return Err(msg),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
set_mpv_property(self, "loop-playlist", enabled)
|
|
|
|
}
|
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
pub fn set_mute(&self, option: Switch) -> Result<(), Error> {
|
2017-05-22 18:31:20 +02:00
|
|
|
let mut enabled = false;
|
|
|
|
match option {
|
|
|
|
Switch::On => enabled = true,
|
|
|
|
Switch::Off => {}
|
|
|
|
Switch::Toggle => {
|
|
|
|
match get_mpv_property::<bool>(self, "mute") {
|
|
|
|
Ok(value) => {
|
|
|
|
enabled = !value;
|
|
|
|
}
|
|
|
|
Err(msg) => return Err(msg),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
set_mpv_property(self, "mute", enabled)
|
|
|
|
}
|
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
/// #Description
|
|
|
|
///
|
|
|
|
/// Sets the mpv property _<property>_ to _<value>_.
|
|
|
|
///
|
|
|
|
/// ##Supported types
|
|
|
|
/// - String
|
|
|
|
/// - bool
|
|
|
|
/// - f64
|
|
|
|
/// - usize
|
|
|
|
///
|
|
|
|
/// ##Input arguments
|
|
|
|
///
|
|
|
|
/// - **property** defines the mpv property that should be retrieved
|
|
|
|
/// - **value** defines the value of the given mpv property _<property>_
|
|
|
|
///
|
|
|
|
/// #Example
|
|
|
|
/// ```
|
2019-06-18 17:33:34 +02:00
|
|
|
/// # use mpvipc::Mpv;
|
2017-06-01 19:30:52 +02:00
|
|
|
/// let mpv = Mpv::connect("/tmp/mpvsocket").unwrap();
|
|
|
|
/// mpv.set_property("pause", true);
|
|
|
|
/// ```
|
2017-06-17 13:03:27 +02:00
|
|
|
pub fn set_property<T: SetPropertyTypeHandler<T>>(
|
|
|
|
&self,
|
|
|
|
property: &str,
|
|
|
|
value: T,
|
|
|
|
) -> Result<(), Error> {
|
2017-05-22 18:31:20 +02:00
|
|
|
T::set_property_generic(self, property, value)
|
|
|
|
}
|
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
pub fn set_speed(&self, input_speed: f64, option: NumberChangeOptions) -> Result<(), Error> {
|
2017-05-22 18:31:20 +02:00
|
|
|
match get_mpv_property::<f64>(self, "speed") {
|
|
|
|
Ok(speed) => {
|
|
|
|
match option {
|
|
|
|
NumberChangeOptions::Increase => {
|
|
|
|
set_mpv_property(self, "speed", speed + input_speed)
|
|
|
|
}
|
|
|
|
|
|
|
|
NumberChangeOptions::Decrease => {
|
|
|
|
set_mpv_property(self, "speed", speed - input_speed)
|
|
|
|
}
|
|
|
|
|
|
|
|
NumberChangeOptions::Absolute => set_mpv_property(self, "speed", input_speed),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(msg) => Err(msg),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
pub fn set_volume(&self, input_volume: f64, option: NumberChangeOptions) -> Result<(), Error> {
|
2017-05-22 18:31:20 +02:00
|
|
|
match get_mpv_property::<f64>(self, "volume") {
|
|
|
|
Ok(volume) => {
|
|
|
|
match option {
|
|
|
|
NumberChangeOptions::Increase => {
|
|
|
|
set_mpv_property(self, "volume", volume + input_volume)
|
|
|
|
}
|
|
|
|
|
|
|
|
NumberChangeOptions::Decrease => {
|
|
|
|
set_mpv_property(self, "volume", volume - input_volume)
|
|
|
|
}
|
|
|
|
|
|
|
|
NumberChangeOptions::Absolute => set_mpv_property(self, "volume", input_volume),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(msg) => Err(msg),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
pub fn stop(&self) -> Result<(), Error> {
|
2017-05-31 19:32:46 +02:00
|
|
|
run_mpv_command(self, "stop", &[])
|
2017-05-22 18:31:20 +02:00
|
|
|
}
|
|
|
|
|
2017-06-01 19:30:52 +02:00
|
|
|
pub fn toggle(&self) -> Result<(), Error> {
|
2017-05-22 18:31:20 +02:00
|
|
|
match get_mpv_property::<bool>(self, "pause") {
|
|
|
|
Ok(paused) => set_mpv_property(self, "pause", !paused),
|
|
|
|
Err(msg) => Err(msg),
|
|
|
|
}
|
|
|
|
}
|
2019-06-18 17:33:34 +02:00
|
|
|
}
|