Merge branch 'fixes' into 'master'
Misc improvements to this crate See merge request mpv-ipc/mpvipc!1
This commit is contained in:
commit
a4bcf78229
|
@ -7,8 +7,12 @@ license = "GPL-3.0"
|
||||||
homepage = "https://gitlab.com/mpv-ipc/mpvipc"
|
homepage = "https://gitlab.com/mpv-ipc/mpvipc"
|
||||||
repository = "https://gitlab.com/mpv-ipc/mpvipc"
|
repository = "https://gitlab.com/mpv-ipc/mpvipc"
|
||||||
documentation = "https://docs.rs/mpvipc/"
|
documentation = "https://docs.rs/mpvipc/"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = "1.0.1"
|
serde = "1.0.1"
|
||||||
serde_json = "1.0.0"
|
serde_json = "1.0.0"
|
||||||
|
log = "0.4.6"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
env_logger = "*"
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
use env_logger;
|
||||||
|
use mpvipc::{Error as MpvError, Mpv};
|
||||||
|
|
||||||
|
fn main() -> Result<(), MpvError> {
|
||||||
|
env_logger::init();
|
||||||
|
|
||||||
|
let mpv = Mpv::connect("/tmp/mpvsocket")?;
|
||||||
|
let meta = mpv.get_metadata()?;
|
||||||
|
println!("metadata: {:?}", meta);
|
||||||
|
let playlist = mpv.get_playlist()?;
|
||||||
|
println!("playlist: {:?}", playlist);
|
||||||
|
let playback_time: f64 = mpv.get_property("playback-time")?;
|
||||||
|
println!("playback-time: {}", playback_time);
|
||||||
|
Ok(())
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
use env_logger;
|
||||||
|
use mpvipc::{Error, Event, Mpv, MpvDataType, Property};
|
||||||
|
use std::io::{self, Write};
|
||||||
|
|
||||||
|
fn seconds_to_hms(total: f64) -> String {
|
||||||
|
let total = total as u64;
|
||||||
|
let seconds = total % 60;
|
||||||
|
let total = total / 60;
|
||||||
|
let minutes = total % 60;
|
||||||
|
let hours = total / 60;
|
||||||
|
format!("{:02}:{:02}:{:02}", hours, minutes, seconds)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<(), Error> {
|
||||||
|
env_logger::init();
|
||||||
|
|
||||||
|
let mut mpv = Mpv::connect("/tmp/mpvsocket")?;
|
||||||
|
let mut pause = false;
|
||||||
|
let mut playback_time = std::f64::NAN;
|
||||||
|
let mut duration = std::f64::NAN;
|
||||||
|
mpv.observe_property(&1, "path")?;
|
||||||
|
mpv.observe_property(&2, "pause")?;
|
||||||
|
mpv.observe_property(&3, "playback-time")?;
|
||||||
|
mpv.observe_property(&4, "duration")?;
|
||||||
|
mpv.observe_property(&5, "metadata")?;
|
||||||
|
loop {
|
||||||
|
let event = mpv.event_listen()?;
|
||||||
|
match event {
|
||||||
|
Event::PropertyChange(property) => match property {
|
||||||
|
Property::Path(Some(value)) => println!("\nPlaying: {}[K", value),
|
||||||
|
Property::Path(None) => (),
|
||||||
|
Property::Pause(value) => pause = value,
|
||||||
|
Property::PlaybackTime(Some(value)) => playback_time = value,
|
||||||
|
Property::PlaybackTime(None) => playback_time = std::f64::NAN,
|
||||||
|
Property::Duration(Some(value)) => duration = value,
|
||||||
|
Property::Duration(None) => duration = std::f64::NAN,
|
||||||
|
Property::Metadata(Some(value)) => {
|
||||||
|
println!("File tags:[K");
|
||||||
|
if let Some(MpvDataType::String(value)) = value.get("ARTIST") {
|
||||||
|
println!(" Artist: {}[K", value);
|
||||||
|
}
|
||||||
|
if let Some(MpvDataType::String(value)) = value.get("ALBUM") {
|
||||||
|
println!(" Album: {}[K", value);
|
||||||
|
}
|
||||||
|
if let Some(MpvDataType::String(value)) = value.get("TITLE") {
|
||||||
|
println!(" Title: {}[K", value);
|
||||||
|
}
|
||||||
|
if let Some(MpvDataType::String(value)) = value.get("TRACK") {
|
||||||
|
println!(" Track: {}[K", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Property::Metadata(None) => (),
|
||||||
|
Property::Unknown {
|
||||||
|
name: _,
|
||||||
|
id: _,
|
||||||
|
data: _,
|
||||||
|
} => (),
|
||||||
|
},
|
||||||
|
Event::Shutdown => return Ok(()),
|
||||||
|
Event::Unimplemented => panic!("Unimplemented event"),
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
print!(
|
||||||
|
"{}{} / {} ({:.0}%)[K\r",
|
||||||
|
if pause { "(Paused) " } else { "" },
|
||||||
|
seconds_to_hms(playback_time),
|
||||||
|
seconds_to_hms(duration),
|
||||||
|
100. * playback_time / duration
|
||||||
|
);
|
||||||
|
io::stdout().flush().unwrap();
|
||||||
|
}
|
||||||
|
}
|
65
src/ipc.rs
65
src/ipc.rs
|
@ -1,9 +1,10 @@
|
||||||
|
use super::*;
|
||||||
|
use log::{debug, warn};
|
||||||
use serde_json::{self, Value};
|
use serde_json::{self, Value};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::BufReader;
|
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
|
use std::io::BufReader;
|
||||||
use std::iter::Iterator;
|
use std::iter::Iterator;
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PlaylistEntry {
|
pub struct PlaylistEntry {
|
||||||
|
@ -256,11 +257,10 @@ pub fn run_mpv_command(instance: &Mpv, command: &str, args: &[&str]) -> Result<(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn observe_mpv_property(instance: &Mpv, id: &usize, property: &str) -> Result<(), Error> {
|
pub fn observe_mpv_property(instance: &Mpv, id: &isize, property: &str) -> Result<(), Error> {
|
||||||
let ipc_string = format!(
|
let ipc_string = format!(
|
||||||
"{{ \"command\": [\"observe_property\", {}, \"{}\"] }}\n",
|
"{{ \"command\": [\"observe_property\", {}, \"{}\"] }}\n",
|
||||||
id,
|
id, property
|
||||||
property
|
|
||||||
);
|
);
|
||||||
match serde_json::from_str::<Value>(&send_command_sync(instance, &ipc_string)) {
|
match serde_json::from_str::<Value>(&send_command_sync(instance, &ipc_string)) {
|
||||||
Ok(feedback) => {
|
Ok(feedback) => {
|
||||||
|
@ -278,10 +278,49 @@ pub fn observe_mpv_property(instance: &Mpv, id: &usize, property: &str) -> Resul
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_convert_property(name: &str, id: isize, data: MpvDataType) -> Event {
|
||||||
|
let property = match name {
|
||||||
|
"path" => match data {
|
||||||
|
MpvDataType::String(value) => Property::Path(Some(value)),
|
||||||
|
MpvDataType::Null => Property::Path(None),
|
||||||
|
_ => unimplemented!(),
|
||||||
|
},
|
||||||
|
"pause" => match data {
|
||||||
|
MpvDataType::Bool(value) => Property::Pause(value),
|
||||||
|
_ => unimplemented!(),
|
||||||
|
},
|
||||||
|
"playback-time" => match data {
|
||||||
|
MpvDataType::Double(value) => Property::PlaybackTime(Some(value)),
|
||||||
|
MpvDataType::Null => Property::PlaybackTime(None),
|
||||||
|
_ => unimplemented!(),
|
||||||
|
},
|
||||||
|
"duration" => match data {
|
||||||
|
MpvDataType::Double(value) => Property::Duration(Some(value)),
|
||||||
|
MpvDataType::Null => Property::Duration(None),
|
||||||
|
_ => unimplemented!(),
|
||||||
|
},
|
||||||
|
"metadata" => match data {
|
||||||
|
MpvDataType::HashMap(value) => Property::Metadata(Some(value)),
|
||||||
|
MpvDataType::Null => Property::Metadata(None),
|
||||||
|
_ => unimplemented!(),
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
warn!("Property {} not implemented", name);
|
||||||
|
Property::Unknown {
|
||||||
|
name: name.to_string(),
|
||||||
|
id,
|
||||||
|
data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Event::PropertyChange(property)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn listen(instance: &mut Mpv) -> Result<Event, Error> {
|
pub fn listen(instance: &mut Mpv) -> Result<Event, Error> {
|
||||||
let mut response = String::new();
|
let mut response = String::new();
|
||||||
instance.reader.read_line(&mut response).unwrap();
|
instance.reader.read_line(&mut response).unwrap();
|
||||||
response = response.trim_right().to_string();
|
response = response.trim_end().to_string();
|
||||||
|
debug!("Event: {}", response);
|
||||||
match serde_json::from_str::<Value>(&response) {
|
match serde_json::from_str::<Value>(&response) {
|
||||||
Ok(e) => {
|
Ok(e) => {
|
||||||
if let Value::String(ref name) = e["event"] {
|
if let Value::String(ref name) = e["event"] {
|
||||||
|
@ -337,7 +376,7 @@ pub fn listen(instance: &mut Mpv) -> Result<Event, Error> {
|
||||||
}
|
}
|
||||||
"property-change" => {
|
"property-change" => {
|
||||||
let name: String;
|
let name: String;
|
||||||
let id: usize;
|
let id: isize;
|
||||||
let data: MpvDataType;
|
let data: MpvDataType;
|
||||||
|
|
||||||
if let Value::String(ref n) = e["name"] {
|
if let Value::String(ref n) = e["name"] {
|
||||||
|
@ -347,9 +386,9 @@ pub fn listen(instance: &mut Mpv) -> Result<Event, Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Value::Number(ref n) = e["id"] {
|
if let Value::Number(ref n) = e["id"] {
|
||||||
id = n.as_u64().unwrap() as usize;
|
id = n.as_i64().unwrap() as isize;
|
||||||
} else {
|
} else {
|
||||||
return Err(Error(ErrorCode::JsonContainsUnexptectedType));
|
id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
match e["data"] {
|
match e["data"] {
|
||||||
|
@ -389,7 +428,7 @@ pub fn listen(instance: &mut Mpv) -> Result<Event, Error> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
event = Event::PropertyChange { name, id, data }
|
event = try_convert_property(name.as_ref(), id, data);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
event = Event::Unimplemented;
|
event = Event::Unimplemented;
|
||||||
|
@ -406,7 +445,7 @@ pub fn listen(instance: &mut Mpv) -> Result<Event, Error> {
|
||||||
pub fn listen_raw(instance: &mut Mpv) -> String {
|
pub fn listen_raw(instance: &mut Mpv) -> String {
|
||||||
let mut response = String::new();
|
let mut response = String::new();
|
||||||
instance.reader.read_line(&mut response).unwrap();
|
instance.reader.read_line(&mut response).unwrap();
|
||||||
response.trim_right().to_string()
|
response.trim_end().to_string()
|
||||||
// let mut stream = &instance.0;
|
// let mut stream = &instance.0;
|
||||||
// let mut buffer = [0; 32];
|
// let mut buffer = [0; 32];
|
||||||
// stream.read(&mut buffer[..]).unwrap();
|
// stream.read(&mut buffer[..]).unwrap();
|
||||||
|
@ -418,6 +457,7 @@ fn send_command_sync(instance: &Mpv, command: &str) -> String {
|
||||||
match stream.write_all(command.as_bytes()) {
|
match stream.write_all(command.as_bytes()) {
|
||||||
Err(why) => panic!("Error: Could not write to socket: {}", why),
|
Err(why) => panic!("Error: Could not write to socket: {}", why),
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
|
debug!("Command: {}", command.trim_end());
|
||||||
let mut response = String::new();
|
let mut response = String::new();
|
||||||
{
|
{
|
||||||
let mut reader = BufReader::new(stream);
|
let mut reader = BufReader::new(stream);
|
||||||
|
@ -426,6 +466,7 @@ fn send_command_sync(instance: &Mpv, command: &str) -> String {
|
||||||
reader.read_line(&mut response).unwrap();
|
reader.read_line(&mut response).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
debug!("Response: {}", response.trim_end());
|
||||||
response
|
response
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -554,4 +595,4 @@ fn json_array_to_playlist(array: &Vec<Value>) -> Vec<PlaylistEntry> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
|
245
src/lib.rs
245
src/lib.rs
|
@ -1,13 +1,10 @@
|
||||||
extern crate serde;
|
|
||||||
extern crate serde_json;
|
|
||||||
|
|
||||||
pub mod ipc;
|
pub mod ipc;
|
||||||
|
|
||||||
use ipc::*;
|
use ipc::*;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt::{self, Display};
|
use std::fmt::{self, Display};
|
||||||
|
use std::io::{BufReader, Read};
|
||||||
use std::os::unix::net::UnixStream;
|
use std::os::unix::net::UnixStream;
|
||||||
use std::io::{Read, BufReader};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
|
@ -39,15 +36,25 @@ pub enum Event {
|
||||||
MetadataUpdate,
|
MetadataUpdate,
|
||||||
Seek,
|
Seek,
|
||||||
PlaybackRestart,
|
PlaybackRestart,
|
||||||
PropertyChange {
|
PropertyChange(Property),
|
||||||
name: String,
|
|
||||||
id: usize,
|
|
||||||
data: MpvDataType,
|
|
||||||
},
|
|
||||||
ChapterChange,
|
ChapterChange,
|
||||||
Unimplemented,
|
Unimplemented,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Property {
|
||||||
|
Path(Option<String>),
|
||||||
|
Pause(bool),
|
||||||
|
PlaybackTime(Option<f64>),
|
||||||
|
Duration(Option<f64>),
|
||||||
|
Metadata(Option<HashMap<String, MpvDataType>>),
|
||||||
|
Unknown {
|
||||||
|
name: String,
|
||||||
|
id: isize,
|
||||||
|
data: MpvDataType,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum MpvDataType {
|
pub enum MpvDataType {
|
||||||
Array(Vec<MpvDataType>),
|
Array(Vec<MpvDataType>),
|
||||||
|
@ -110,6 +117,7 @@ pub enum ErrorCode {
|
||||||
pub struct Mpv {
|
pub struct Mpv {
|
||||||
stream: UnixStream,
|
stream: UnixStream,
|
||||||
reader: BufReader<UnixStream>,
|
reader: BufReader<UnixStream>,
|
||||||
|
name: String,
|
||||||
}
|
}
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Playlist(pub Vec<PlaylistEntry>);
|
pub struct Playlist(pub Vec<PlaylistEntry>);
|
||||||
|
@ -122,6 +130,12 @@ impl Drop for Mpv {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for Mpv {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
fmt.debug_tuple("Mpv").field(&self.name).finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Clone for Mpv {
|
impl Clone for Mpv {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
let stream = self.stream.try_clone().expect("cloning UnixStream");
|
let stream = self.stream.try_clone().expect("cloning UnixStream");
|
||||||
|
@ -129,6 +143,7 @@ impl Clone for Mpv {
|
||||||
Mpv {
|
Mpv {
|
||||||
stream,
|
stream,
|
||||||
reader: BufReader::new(cloned_stream),
|
reader: BufReader::new(cloned_stream),
|
||||||
|
name: self.name.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +153,7 @@ impl Clone for Mpv {
|
||||||
*self = Mpv {
|
*self = Mpv {
|
||||||
stream,
|
stream,
|
||||||
reader: BufReader::new(cloned_stream),
|
reader: BufReader::new(cloned_stream),
|
||||||
|
name: source.name.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,9 +183,7 @@ impl Display for ErrorCode {
|
||||||
f.write_str("The received value is not of type \'std::f64\'")
|
f.write_str("The received value is not of type \'std::f64\'")
|
||||||
}
|
}
|
||||||
ErrorCode::ValueDoesNotContainHashMap => {
|
ErrorCode::ValueDoesNotContainHashMap => {
|
||||||
f.write_str(
|
f.write_str("The received value is not of type \'std::collections::HashMap\'")
|
||||||
"The received value is not of type \'std::collections::HashMap\'",
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
ErrorCode::ValueDoesNotContainPlaylist => {
|
ErrorCode::ValueDoesNotContainPlaylist => {
|
||||||
f.write_str("The received value is not of type \'mpvipc::Playlist\'")
|
f.write_str("The received value is not of type \'mpvipc::Playlist\'")
|
||||||
|
@ -263,6 +277,7 @@ impl Mpv {
|
||||||
return Ok(Mpv {
|
return Ok(Mpv {
|
||||||
stream,
|
stream,
|
||||||
reader: BufReader::new(cloned_stream),
|
reader: BufReader::new(cloned_stream),
|
||||||
|
name: String::from(socket),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Err(internal_error) => Err(Error(ErrorCode::ConnectError(internal_error.to_string()))),
|
Err(internal_error) => Err(Error(ErrorCode::ConnectError(internal_error.to_string()))),
|
||||||
|
@ -271,9 +286,9 @@ impl Mpv {
|
||||||
|
|
||||||
pub fn disconnect(&self) {
|
pub fn disconnect(&self) {
|
||||||
let mut stream = &self.stream;
|
let mut stream = &self.stream;
|
||||||
stream.shutdown(std::net::Shutdown::Both).expect(
|
stream
|
||||||
"socket disconnect",
|
.shutdown(std::net::Shutdown::Both)
|
||||||
);
|
.expect("socket disconnect");
|
||||||
let mut buffer = [0; 32];
|
let mut buffer = [0; 32];
|
||||||
for _ in 0..stream.bytes().count() {
|
for _ in 0..stream.bytes().count() {
|
||||||
stream.read(&mut buffer[..]).unwrap();
|
stream.read(&mut buffer[..]).unwrap();
|
||||||
|
@ -316,9 +331,13 @@ impl Mpv {
|
||||||
///
|
///
|
||||||
/// #Example
|
/// #Example
|
||||||
/// ```
|
/// ```
|
||||||
/// let mpv = Mpv::connect("/tmp/mpvsocket").unwrap();
|
/// # use mpvipc::{Mpv, Error};
|
||||||
/// let paused: bool = mpv.get_property("pause").unwrap();
|
/// # fn main() -> Result<(), Error> {
|
||||||
/// let title: String = mpv.get_property("media-title").unwrap();
|
/// let mpv = Mpv::connect("/tmp/mpvsocket")?;
|
||||||
|
/// let paused: bool = mpv.get_property("pause")?;
|
||||||
|
/// let title: String = mpv.get_property("media-title")?;
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn get_property<T: GetPropertyTypeHandler>(&self, property: &str) -> Result<T, Error> {
|
pub fn get_property<T: GetPropertyTypeHandler>(&self, property: &str) -> Result<T, Error> {
|
||||||
T::get_property_generic(self, property)
|
T::get_property_generic(self, property)
|
||||||
|
@ -336,8 +355,12 @@ impl Mpv {
|
||||||
/// #Example
|
/// #Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let mpv = Mpv::connect("/tmp/mpvsocket").unwrap();
|
/// # use mpvipc::{Mpv, Error};
|
||||||
/// let title = mpv.get_property_string("media-title").unwrap();
|
/// # fn main() -> Result<(), Error> {
|
||||||
|
/// let mpv = Mpv::connect("/tmp/mpvsocket")?;
|
||||||
|
/// let title = mpv.get_property_string("media-title")?;
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn get_property_string(&self, property: &str) -> Result<String, Error> {
|
pub fn get_property_string(&self, property: &str) -> Result<String, Error> {
|
||||||
get_mpv_property_string(self, property)
|
get_mpv_property_string(self, property)
|
||||||
|
@ -353,10 +376,10 @@ impl Mpv {
|
||||||
///
|
///
|
||||||
/// #Example
|
/// #Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```ignore
|
||||||
/// let mpv = Mpv::connect("/tmp/mpvsocket").unwrap();
|
/// let mut mpv = Mpv::connect("/tmp/mpvsocket")?;
|
||||||
/// loop {
|
/// loop {
|
||||||
/// let event = mpv.event_listen().unwrap();
|
/// let event = mpv.event_listen()?;
|
||||||
/// println!("{:?}", event);
|
/// println!("{:?}", event);
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -372,7 +395,7 @@ impl Mpv {
|
||||||
run_mpv_command(self, "playlist-next", &[])
|
run_mpv_command(self, "playlist-next", &[])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn observe_property(&self, id: &usize, property: &str) -> Result<(), Error> {
|
pub fn observe_property(&self, id: &isize, property: &str) -> Result<(), Error> {
|
||||||
observe_mpv_property(self, id, property)
|
observe_mpv_property(self, id, property)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,13 +422,17 @@ impl Mpv {
|
||||||
///
|
///
|
||||||
/// #Example
|
/// #Example
|
||||||
/// ```
|
/// ```
|
||||||
/// let mpv = Mpv::connect("/tmp/mpvsocket").unwrap();
|
/// # use mpvipc::{Mpv, Error};
|
||||||
|
/// # fn main() -> Result<(), Error> {
|
||||||
|
/// let mpv = Mpv::connect("/tmp/mpvsocket")?;
|
||||||
///
|
///
|
||||||
/// //Run command 'playlist-shuffle' which takes no arguments
|
/// //Run command 'playlist-shuffle' which takes no arguments
|
||||||
/// mpv.run_command("playlist-shuffle", &[]);
|
/// mpv.run_command("playlist-shuffle", &[])?;
|
||||||
///
|
///
|
||||||
/// //Run command 'seek' which in this case takes two arguments
|
/// //Run command 'seek' which in this case takes two arguments
|
||||||
/// mpv.run_command("seek", &["0", "absolute"]);
|
/// mpv.run_command("seek", &["0", "absolute"])?;
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn run_command(&self, command: &str, args: &[&str]) -> Result<(), Error> {
|
pub fn run_command(&self, command: &str, args: &[&str]) -> Result<(), Error> {
|
||||||
run_mpv_command(self, command, args)
|
run_mpv_command(self, command, args)
|
||||||
|
@ -418,33 +445,25 @@ impl Mpv {
|
||||||
option: PlaylistAddOptions,
|
option: PlaylistAddOptions,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
match file_type {
|
match file_type {
|
||||||
PlaylistAddTypeOptions::File => {
|
PlaylistAddTypeOptions::File => match option {
|
||||||
match option {
|
PlaylistAddOptions::Replace => {
|
||||||
PlaylistAddOptions::Replace => {
|
run_mpv_command(self, "loadfile", &[file, "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"])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
PlaylistAddOptions::Append => run_mpv_command(self, "loadfile", &[file, "append"]),
|
||||||
|
PlaylistAddOptions::AppendPlay => {
|
||||||
|
run_mpv_command(self, "loadfile", &[file, "append-play"])
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
PlaylistAddTypeOptions::Playlist => {
|
PlaylistAddTypeOptions::Playlist => match option {
|
||||||
match option {
|
PlaylistAddOptions::Replace => {
|
||||||
PlaylistAddOptions::Replace => {
|
run_mpv_command(self, "loadlist", &[file, "replace"])
|
||||||
run_mpv_command(self, "loadlist", &[file, "replace"])
|
|
||||||
}
|
|
||||||
PlaylistAddOptions::Append |
|
|
||||||
PlaylistAddOptions::AppendPlay => {
|
|
||||||
run_mpv_command(self, "loadlist", &[file, "append"])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
PlaylistAddOptions::Append | PlaylistAddOptions::AppendPlay => {
|
||||||
|
run_mpv_command(self, "loadlist", &[file, "append"])
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn playlist_clear(&self) -> Result<(), Error> {
|
pub fn playlist_clear(&self) -> Result<(), Error> {
|
||||||
|
@ -461,13 +480,11 @@ impl Mpv {
|
||||||
|
|
||||||
pub fn playlist_play_next(&self, id: usize) -> Result<(), Error> {
|
pub fn playlist_play_next(&self, id: usize) -> Result<(), Error> {
|
||||||
match get_mpv_property::<usize>(self, "playlist-pos") {
|
match get_mpv_property::<usize>(self, "playlist-pos") {
|
||||||
Ok(current_id) => {
|
Ok(current_id) => run_mpv_command(
|
||||||
run_mpv_command(
|
self,
|
||||||
self,
|
"playlist-move",
|
||||||
"playlist-move",
|
&[&id.to_string(), &(current_id + 1).to_string()],
|
||||||
&[&id.to_string(), &(current_id + 1).to_string()],
|
),
|
||||||
)
|
|
||||||
}
|
|
||||||
Err(msg) => Err(msg),
|
Err(msg) => Err(msg),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -502,21 +519,17 @@ impl Mpv {
|
||||||
match option {
|
match option {
|
||||||
Switch::On => enabled = true,
|
Switch::On => enabled = true,
|
||||||
Switch::Off => {}
|
Switch::Off => {}
|
||||||
Switch::Toggle => {
|
Switch::Toggle => match get_mpv_property_string(self, "loop-file") {
|
||||||
match get_mpv_property_string(self, "loop-file") {
|
Ok(value) => match value.as_ref() {
|
||||||
Ok(value) => {
|
"false" => {
|
||||||
match value.as_ref() {
|
enabled = true;
|
||||||
"false" => {
|
|
||||||
enabled = true;
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
enabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Err(msg) => return Err(msg),
|
_ => {
|
||||||
}
|
enabled = false;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
Err(msg) => return Err(msg),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
set_mpv_property(self, "loop-file", enabled)
|
set_mpv_property(self, "loop-file", enabled)
|
||||||
}
|
}
|
||||||
|
@ -526,21 +539,17 @@ impl Mpv {
|
||||||
match option {
|
match option {
|
||||||
Switch::On => enabled = true,
|
Switch::On => enabled = true,
|
||||||
Switch::Off => {}
|
Switch::Off => {}
|
||||||
Switch::Toggle => {
|
Switch::Toggle => match get_mpv_property_string(self, "loop-playlist") {
|
||||||
match get_mpv_property_string(self, "loop-playlist") {
|
Ok(value) => match value.as_ref() {
|
||||||
Ok(value) => {
|
"false" => {
|
||||||
match value.as_ref() {
|
enabled = true;
|
||||||
"false" => {
|
|
||||||
enabled = true;
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
enabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Err(msg) => return Err(msg),
|
_ => {
|
||||||
}
|
enabled = false;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
Err(msg) => return Err(msg),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
set_mpv_property(self, "loop-playlist", enabled)
|
set_mpv_property(self, "loop-playlist", enabled)
|
||||||
}
|
}
|
||||||
|
@ -550,14 +559,12 @@ impl Mpv {
|
||||||
match option {
|
match option {
|
||||||
Switch::On => enabled = true,
|
Switch::On => enabled = true,
|
||||||
Switch::Off => {}
|
Switch::Off => {}
|
||||||
Switch::Toggle => {
|
Switch::Toggle => match get_mpv_property::<bool>(self, "mute") {
|
||||||
match get_mpv_property::<bool>(self, "mute") {
|
Ok(value) => {
|
||||||
Ok(value) => {
|
enabled = !value;
|
||||||
enabled = !value;
|
|
||||||
}
|
|
||||||
Err(msg) => return Err(msg),
|
|
||||||
}
|
}
|
||||||
}
|
Err(msg) => return Err(msg),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
set_mpv_property(self, "mute", enabled)
|
set_mpv_property(self, "mute", enabled)
|
||||||
}
|
}
|
||||||
|
@ -579,8 +586,12 @@ impl Mpv {
|
||||||
///
|
///
|
||||||
/// #Example
|
/// #Example
|
||||||
/// ```
|
/// ```
|
||||||
/// let mpv = Mpv::connect("/tmp/mpvsocket").unwrap();
|
/// # use mpvipc::{Mpv, Error};
|
||||||
/// mpv.set_property("pause", true);
|
/// # fn main() -> Result<(), Error> {
|
||||||
|
/// let mpv = Mpv::connect("/tmp/mpvsocket")?;
|
||||||
|
/// mpv.set_property("pause", true)?;
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn set_property<T: SetPropertyTypeHandler<T>>(
|
pub fn set_property<T: SetPropertyTypeHandler<T>>(
|
||||||
&self,
|
&self,
|
||||||
|
@ -592,38 +603,34 @@ impl Mpv {
|
||||||
|
|
||||||
pub fn set_speed(&self, input_speed: f64, option: NumberChangeOptions) -> Result<(), Error> {
|
pub fn set_speed(&self, input_speed: f64, option: NumberChangeOptions) -> Result<(), Error> {
|
||||||
match get_mpv_property::<f64>(self, "speed") {
|
match get_mpv_property::<f64>(self, "speed") {
|
||||||
Ok(speed) => {
|
Ok(speed) => match option {
|
||||||
match option {
|
NumberChangeOptions::Increase => {
|
||||||
NumberChangeOptions::Increase => {
|
set_mpv_property(self, "speed", speed + input_speed)
|
||||||
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),
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
NumberChangeOptions::Decrease => {
|
||||||
|
set_mpv_property(self, "speed", speed - input_speed)
|
||||||
|
}
|
||||||
|
|
||||||
|
NumberChangeOptions::Absolute => set_mpv_property(self, "speed", input_speed),
|
||||||
|
},
|
||||||
Err(msg) => Err(msg),
|
Err(msg) => Err(msg),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_volume(&self, input_volume: f64, option: NumberChangeOptions) -> Result<(), Error> {
|
pub fn set_volume(&self, input_volume: f64, option: NumberChangeOptions) -> Result<(), Error> {
|
||||||
match get_mpv_property::<f64>(self, "volume") {
|
match get_mpv_property::<f64>(self, "volume") {
|
||||||
Ok(volume) => {
|
Ok(volume) => match option {
|
||||||
match option {
|
NumberChangeOptions::Increase => {
|
||||||
NumberChangeOptions::Increase => {
|
set_mpv_property(self, "volume", volume + input_volume)
|
||||||
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),
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
NumberChangeOptions::Decrease => {
|
||||||
|
set_mpv_property(self, "volume", volume - input_volume)
|
||||||
|
}
|
||||||
|
|
||||||
|
NumberChangeOptions::Absolute => set_mpv_property(self, "volume", input_volume),
|
||||||
|
},
|
||||||
Err(msg) => Err(msg),
|
Err(msg) => Err(msg),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -638,4 +645,4 @@ impl Mpv {
|
||||||
Err(msg) => Err(msg),
|
Err(msg) => Err(msg),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue