Keeps the socket open for the entire lifetime of the Mpv struct. Now using channels to inform about new events (listen command). Added Readme
This commit is contained in:
parent
e797bd871a
commit
ea0e60097d
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "mpvipc"
|
name = "mpvipc"
|
||||||
version = "1.0.0"
|
version = "1.1.0"
|
||||||
authors = ["Jonas Frei <freijon@gmail.com>"]
|
authors = ["Jonas Frei <freijon@gmail.com>"]
|
||||||
description = "A small library which provides bindings to control existing mpv instances through sockets."
|
description = "A small library which provides bindings to control existing mpv instances through sockets."
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
# mpvipc
|
||||||
|
|
||||||
|
A small library which provides bindings to control existing mpv instances through sockets.
|
||||||
|
|
||||||
|
To make use of this library, please make sure mpv is started with the following option:
|
||||||
|
`
|
||||||
|
$ mpv --input-ipc-server=/tmp/mpvsocket --idle ...
|
||||||
|
`
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- `mpv`
|
||||||
|
- `cargo` (makedep)
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
- [Cargo](https://crates.io/crates/mpvipc)
|
||||||
|
|
||||||
|
You can use this package with cargo.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
Make sure mpv is started with the following option:
|
||||||
|
`
|
||||||
|
$ mpv --input-ipc-server=/tmp/mpvsocket --idle
|
||||||
|
`
|
||||||
|
|
||||||
|
Here is a small code example which connects to the socket /tmp/mpvsocket and toggles playback.
|
||||||
|
|
||||||
|
```
|
||||||
|
use mpvipc::*;
|
||||||
|
use std::sync::mpsc::channel;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mpv = Mpv::connect("/tmp/mpvsocket").unwrap();
|
||||||
|
let paused: bool = mpv.get_property("pause").unwrap();
|
||||||
|
mpv.set_property("pause", !paused).expect("Error pausing");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
For a more extensive example and proof of concept, see project [mpvc](https://github.com/freijon/mpvc-rs).
|
||||||
|
|
||||||
|
## Bugs / Ideas
|
||||||
|
|
||||||
|
Check out the [Issue Tracker](https://github.com/freijon/mpvipc/issues)
|
52
src/ipc.rs
52
src/ipc.rs
|
@ -4,9 +4,8 @@ use std::error::Error;
|
||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::iter::Iterator;
|
use std::iter::Iterator;
|
||||||
use std::os::unix::net::UnixStream;
|
|
||||||
use std::net::Shutdown;
|
|
||||||
use std::sync::mpsc::Sender;
|
use std::sync::mpsc::Sender;
|
||||||
|
use super::Mpv;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PlaylistEntry {
|
pub struct PlaylistEntry {
|
||||||
|
@ -209,18 +208,18 @@ impl TypeHandler for Vec<PlaylistEntry> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_mpv_property<T: TypeHandler>(socket: &str, property: &str) -> Result<T, String> {
|
pub fn get_mpv_property<T: TypeHandler>(instance: &Mpv, property: &str) -> Result<T, String> {
|
||||||
let ipc_string = format!("{{ \"command\": [\"get_property\",\"{}\"] }}\n", property);
|
let ipc_string = format!("{{ \"command\": [\"get_property\",\"{}\"] }}\n", property);
|
||||||
|
|
||||||
match serde_json::from_str::<Value>(&send_command_sync(socket, &ipc_string)) {
|
match serde_json::from_str::<Value>(&send_command_sync(instance, &ipc_string)) {
|
||||||
Ok(val) => T::get_value(val),
|
Ok(val) => T::get_value(val),
|
||||||
Err(why) => Err(format!("Error while getting property: {}", why)),
|
Err(why) => Err(format!("Error while getting property: {}", why)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_mpv_property_string(socket: &str, property: &str) -> Result<String, String> {
|
pub fn get_mpv_property_string(instance: &Mpv, property: &str) -> Result<String, String> {
|
||||||
let ipc_string = format!("{{ \"command\": [\"get_property\",\"{}\"] }}\n", property);
|
let ipc_string = format!("{{ \"command\": [\"get_property\",\"{}\"] }}\n", property);
|
||||||
match serde_json::from_str::<Value>(&send_command_sync(socket, &ipc_string)) {
|
match serde_json::from_str::<Value>(&send_command_sync(instance, &ipc_string)) {
|
||||||
Ok(val) => {
|
Ok(val) => {
|
||||||
if let Value::Object(map) = val {
|
if let Value::Object(map) = val {
|
||||||
if let Value::String(ref error) = map["error"] {
|
if let Value::String(ref error) = map["error"] {
|
||||||
|
@ -247,20 +246,20 @@ pub fn get_mpv_property_string(socket: &str, property: &str) -> Result<String, S
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_mpv_property<T: TypeHandler>(socket: &str,
|
pub fn set_mpv_property<T: TypeHandler>(instance: &Mpv,
|
||||||
property: &str,
|
property: &str,
|
||||||
value: T)
|
value: T)
|
||||||
-> Result<(), String> {
|
-> Result<(), String> {
|
||||||
let ipc_string = format!("{{ \"command\": [\"set_property\", \"{}\", {}] }}\n",
|
let ipc_string = format!("{{ \"command\": [\"set_property\", \"{}\", {}] }}\n",
|
||||||
property,
|
property,
|
||||||
value.as_string());
|
value.as_string());
|
||||||
match serde_json::from_str::<Value>(&send_command_sync(socket, &ipc_string)) {
|
match serde_json::from_str::<Value>(&send_command_sync(instance, &ipc_string)) {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(why) => Err(why.description().to_string()),
|
Err(why) => Err(why.description().to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_mpv_command(socket: &str, command: &str, args: &Vec<&str>) -> Result<(), String> {
|
pub fn run_mpv_command(instance: &Mpv, command: &str, args: &Vec<&str>) -> Result<(), String> {
|
||||||
let mut ipc_string = format!("{{ \"command\": [\"{}\"", command);
|
let mut ipc_string = format!("{{ \"command\": [\"{}\"", command);
|
||||||
if args.len() > 0 {
|
if args.len() > 0 {
|
||||||
for arg in args.iter() {
|
for arg in args.iter() {
|
||||||
|
@ -269,7 +268,7 @@ pub fn run_mpv_command(socket: &str, command: &str, args: &Vec<&str>) -> Result<
|
||||||
}
|
}
|
||||||
ipc_string.push_str("] }\n");
|
ipc_string.push_str("] }\n");
|
||||||
ipc_string = ipc_string;
|
ipc_string = ipc_string;
|
||||||
match serde_json::from_str::<Value>(&send_command_sync(socket, &ipc_string)) {
|
match serde_json::from_str::<Value>(&send_command_sync(instance, &ipc_string)) {
|
||||||
Ok(feedback) => {
|
Ok(feedback) => {
|
||||||
if let Value::String(ref error) = feedback["error"] {
|
if let Value::String(ref error) = feedback["error"] {
|
||||||
if error == "success" {
|
if error == "success" {
|
||||||
|
@ -278,6 +277,7 @@ pub fn run_mpv_command(socket: &str, command: &str, args: &Vec<&str>) -> Result<
|
||||||
Err(error.to_string())
|
Err(error.to_string())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
//Ok(())
|
||||||
Err("Error: Unexpected result received".to_string())
|
Err("Error: Unexpected result received".to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -285,11 +285,11 @@ pub fn run_mpv_command(socket: &str, command: &str, args: &Vec<&str>) -> Result<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn observe_mpv_property(socket: &str, id: &usize, property: &str) -> Result<(), String> {
|
pub fn observe_mpv_property(instance: &Mpv, id: &usize, property: &str) -> Result<(), String> {
|
||||||
let ipc_string = format!("{{ \"command\": [\"observe_property\", {}, \"{}\"] }}\n",
|
let ipc_string = format!("{{ \"command\": [\"observe_property\", {}, \"{}\"] }}\n",
|
||||||
id,
|
id,
|
||||||
property);
|
property);
|
||||||
match serde_json::from_str::<Value>(&send_command_sync(socket, &ipc_string)) {
|
match serde_json::from_str::<Value>(&send_command_sync(instance, &ipc_string)) {
|
||||||
Ok(feedback) => {
|
Ok(feedback) => {
|
||||||
if let Value::String(ref error) = feedback["error"] {
|
if let Value::String(ref error) = feedback["error"] {
|
||||||
if error == "success" {
|
if error == "success" {
|
||||||
|
@ -314,11 +314,9 @@ pub fn observe_mpv_property(socket: &str, id: &usize, property: &str) -> Result<
|
||||||
/// ```
|
/// ```
|
||||||
/// listen("/tmp/mpvsocket");
|
/// listen("/tmp/mpvsocket");
|
||||||
/// ```
|
/// ```
|
||||||
pub fn listen(socket: &str, tx: &Sender<String>) {
|
pub fn listen(instance: &Mpv, tx: &Sender<String>) {
|
||||||
match UnixStream::connect(socket) {
|
|
||||||
Ok(stream) => {
|
|
||||||
let mut response = String::new();
|
let mut response = String::new();
|
||||||
let mut reader = BufReader::new(&stream);
|
let mut reader = BufReader::new(instance);
|
||||||
reader.read_line(&mut response).unwrap();
|
reader.read_line(&mut response).unwrap();
|
||||||
match serde_json::from_str::<Value>(&response) {
|
match serde_json::from_str::<Value>(&response) {
|
||||||
Ok(e) => {
|
Ok(e) => {
|
||||||
|
@ -329,32 +327,22 @@ pub fn listen(socket: &str, tx: &Sender<String>) {
|
||||||
Err(why) => panic!("{}", why.description().to_string()),
|
Err(why) => panic!("{}", why.description().to_string()),
|
||||||
}
|
}
|
||||||
response.clear();
|
response.clear();
|
||||||
stream
|
|
||||||
.shutdown(Shutdown::Both)
|
|
||||||
.expect("shutdown function failed");
|
|
||||||
}
|
|
||||||
Err(why) => panic!("Error: Could not connect to socket: {}", why.description()),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_command_sync(socket: &str, command: &str) -> String {
|
fn send_command_sync(instance: &Mpv, command: &str) -> String {
|
||||||
match UnixStream::connect(socket) {
|
let mut stream = instance;
|
||||||
Ok(mut stream) => {
|
|
||||||
match stream.write_all(command.as_bytes()) {
|
match stream.write_all(command.as_bytes()) {
|
||||||
Err(why) => panic!("Error: Could not write to socket: {}", why.description()),
|
Err(why) => panic!("Error: Could not write to socket: {}", why.description()),
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
let mut response = String::new();
|
let mut response = String::new();
|
||||||
{
|
{
|
||||||
let mut reader = BufReader::new(&stream);
|
let mut reader = BufReader::new(stream);
|
||||||
|
while !response.contains("\"error\":") {
|
||||||
|
response.clear();
|
||||||
reader.read_line(&mut response).unwrap();
|
reader.read_line(&mut response).unwrap();
|
||||||
}
|
}
|
||||||
stream
|
}
|
||||||
.shutdown(Shutdown::Both)
|
|
||||||
.expect("shutdown function failed");
|
|
||||||
response
|
response
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(why) => panic!("Error: Could not connect to socket: {}", why.description()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
172
src/lib.rs
172
src/lib.rs
|
@ -5,10 +5,10 @@ pub mod ipc;
|
||||||
|
|
||||||
use ipc::*;
|
use ipc::*;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::os::unix::net::UnixStream;
|
||||||
use std::sync::mpsc::Sender;
|
use std::sync::mpsc::Sender;
|
||||||
|
|
||||||
|
pub type Mpv = UnixStream;
|
||||||
pub type Socket = String;
|
|
||||||
|
|
||||||
pub enum NumberChangeOptions {
|
pub enum NumberChangeOptions {
|
||||||
Absolute,
|
Absolute,
|
||||||
|
@ -35,159 +35,88 @@ pub enum Switch {
|
||||||
Toggle,
|
Toggle,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Playlist {
|
pub struct Playlist(pub Vec<PlaylistEntry>);
|
||||||
pub socket: Socket,
|
|
||||||
pub entries: Vec<PlaylistEntry>,
|
pub trait MpvConnector {
|
||||||
|
fn connect(socket: &str) -> Result<Mpv, String>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MpvConnector for Mpv {
|
||||||
|
fn connect(socket: &str) -> Result<Mpv, String> {
|
||||||
|
match UnixStream::connect(socket) {
|
||||||
|
Ok(stream) => Ok(stream),
|
||||||
|
Err(msg) => Err(msg.to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GetPropertyTypeHandler: Sized {
|
pub trait GetPropertyTypeHandler: Sized {
|
||||||
fn get_property_generic(socket: &str, property: &str) -> Result<Self, String>;
|
fn get_property_generic(instance: &Mpv, property: &str) -> Result<Self, String>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetPropertyTypeHandler for bool {
|
impl GetPropertyTypeHandler for bool {
|
||||||
fn get_property_generic(socket: &str, property: &str) -> Result<bool, String> {
|
fn get_property_generic(instance: &Mpv, property: &str) -> Result<bool, String> {
|
||||||
get_mpv_property::<bool>(socket, property)
|
get_mpv_property::<bool>(instance, property)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetPropertyTypeHandler for String {
|
impl GetPropertyTypeHandler for String {
|
||||||
fn get_property_generic(socket: &str, property: &str) -> Result<String, String> {
|
fn get_property_generic(instance: &Mpv, property: &str) -> Result<String, String> {
|
||||||
get_mpv_property::<String>(socket, property)
|
get_mpv_property::<String>(instance, property)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetPropertyTypeHandler for f64 {
|
impl GetPropertyTypeHandler for f64 {
|
||||||
fn get_property_generic(socket: &str, property: &str) -> Result<f64, String> {
|
fn get_property_generic(instance: &Mpv, property: &str) -> Result<f64, String> {
|
||||||
get_mpv_property::<f64>(socket, property)
|
get_mpv_property::<f64>(instance, property)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetPropertyTypeHandler for usize {
|
impl GetPropertyTypeHandler for usize {
|
||||||
fn get_property_generic(socket: &str, property: &str) -> Result<usize, String> {
|
fn get_property_generic(instance: &Mpv, property: &str) -> Result<usize, String> {
|
||||||
get_mpv_property::<usize>(socket, property)
|
get_mpv_property::<usize>(instance, property)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetPropertyTypeHandler for Vec<PlaylistEntry> {
|
impl GetPropertyTypeHandler for Vec<PlaylistEntry> {
|
||||||
fn get_property_generic(socket: &str, property: &str) -> Result<Vec<PlaylistEntry>, String> {
|
fn get_property_generic(instance: &Mpv, property: &str) -> Result<Vec<PlaylistEntry>, String> {
|
||||||
get_mpv_property::<Vec<PlaylistEntry>>(socket, property)
|
get_mpv_property::<Vec<PlaylistEntry>>(instance, property)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetPropertyTypeHandler for HashMap<String, String> {
|
impl GetPropertyTypeHandler for HashMap<String, String> {
|
||||||
fn get_property_generic(socket: &str,
|
fn get_property_generic(instance: &Mpv,
|
||||||
property: &str)
|
property: &str)
|
||||||
-> Result<HashMap<String, String>, String> {
|
-> Result<HashMap<String, String>, String> {
|
||||||
get_mpv_property::<HashMap<String, String>>(socket, property)
|
get_mpv_property::<HashMap<String, String>>(instance, property)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait SetPropertyTypeHandler<T> {
|
pub trait SetPropertyTypeHandler<T> {
|
||||||
fn set_property_generic(socket: &str, property: &str, value: T) -> Result<(), String>;
|
fn set_property_generic(instance: &Mpv, property: &str, value: T) -> Result<(), String>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SetPropertyTypeHandler<bool> for bool {
|
impl SetPropertyTypeHandler<bool> for bool {
|
||||||
fn set_property_generic(socket: &str, property: &str, value: bool) -> Result<(), String> {
|
fn set_property_generic(instance: &Mpv, property: &str, value: bool) -> Result<(), String> {
|
||||||
set_mpv_property::<bool>(socket, property, value)
|
set_mpv_property::<bool>(instance, property, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SetPropertyTypeHandler<String> for String {
|
impl SetPropertyTypeHandler<String> for String {
|
||||||
fn set_property_generic(socket: &str, property: &str, value: String) -> Result<(), String> {
|
fn set_property_generic(instance: &Mpv, property: &str, value: String) -> Result<(), String> {
|
||||||
set_mpv_property::<String>(socket, property, value)
|
set_mpv_property::<String>(instance, property, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SetPropertyTypeHandler<f64> for f64 {
|
impl SetPropertyTypeHandler<f64> for f64 {
|
||||||
fn set_property_generic(socket: &str, property: &str, value: f64) -> Result<(), String> {
|
fn set_property_generic(instance: &Mpv, property: &str, value: f64) -> Result<(), String> {
|
||||||
set_mpv_property::<f64>(socket, property, value)
|
set_mpv_property::<f64>(instance, property, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SetPropertyTypeHandler<usize> for usize {
|
impl SetPropertyTypeHandler<usize> for usize {
|
||||||
fn set_property_generic(socket: &str, property: &str, value: usize) -> Result<(), String> {
|
fn set_property_generic(instance: &Mpv, property: &str, value: usize) -> Result<(), String> {
|
||||||
set_mpv_property::<usize>(socket, property, value)
|
set_mpv_property::<usize>(instance, property, value)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait PlaylistHandler {
|
|
||||||
fn get_from(socket: Socket) -> Result<Playlist, String>;
|
|
||||||
fn shuffle(&mut self) -> &mut Playlist;
|
|
||||||
fn remove_id(&mut self, id: usize) -> &mut Playlist;
|
|
||||||
fn move_entry(&mut self, from: usize, to: usize) -> &mut Playlist;
|
|
||||||
fn current_id(&self) -> Option<usize>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PlaylistHandler for Playlist {
|
|
||||||
fn get_from(socket: Socket) -> Result<Playlist, String> {
|
|
||||||
match get_mpv_property(&socket, "playlist") {
|
|
||||||
Ok(playlist) => {
|
|
||||||
Ok(Playlist {
|
|
||||||
socket: socket,
|
|
||||||
entries: playlist,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Err(why) => Err(why),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn shuffle(&mut self) -> &mut Playlist {
|
|
||||||
if let Err(error_msg) = run_mpv_command(&self.socket, "playlist-shuffle", &vec![]) {
|
|
||||||
panic!("Error: {}", error_msg);
|
|
||||||
}
|
|
||||||
if let Ok(mut playlist_entries) =
|
|
||||||
get_mpv_property::<Vec<PlaylistEntry>>(&self.socket, "playlist") {
|
|
||||||
if self.entries.len() == playlist_entries.len() {
|
|
||||||
for (i, entry) in playlist_entries.drain(0..).enumerate() {
|
|
||||||
self.entries[i] = entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_id(&mut self, id: usize) -> &mut Playlist {
|
|
||||||
self.entries.remove(id);
|
|
||||||
if let Err(error_msg) = run_mpv_command(&self.socket,
|
|
||||||
"playlist-remove",
|
|
||||||
&vec![&id.to_string()]) {
|
|
||||||
panic!("Error: {}", error_msg);
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn move_entry(&mut self, from: usize, to: usize) -> &mut Playlist {
|
|
||||||
if from != to {
|
|
||||||
if let Err(error_msg) = run_mpv_command(&self.socket,
|
|
||||||
"playlist-move",
|
|
||||||
&vec![&from.to_string(), &to.to_string()]) {
|
|
||||||
panic!("Error: {}", error_msg);
|
|
||||||
}
|
|
||||||
if from < to {
|
|
||||||
self.entries[from].id = to - 1;
|
|
||||||
self.entries[to].id = to - 2;
|
|
||||||
for i in from..to - 2 {
|
|
||||||
self.entries[i + 1].id = i;
|
|
||||||
}
|
|
||||||
self.entries.sort_by_key(|entry| entry.id);
|
|
||||||
} else if from > to {
|
|
||||||
self.entries[from].id = to;
|
|
||||||
for i in to..from - 1 {
|
|
||||||
self.entries[i].id = i + 1;
|
|
||||||
}
|
|
||||||
self.entries.sort_by_key(|entry| entry.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn current_id(&self) -> Option<usize> {
|
|
||||||
for entry in self.entries.iter() {
|
|
||||||
if entry.current {
|
|
||||||
return Some(entry.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,6 +133,8 @@ pub trait Commands {
|
||||||
/// - bool
|
/// - bool
|
||||||
/// - HashMap<String, String> (e.g. for the 'metadata' property)
|
/// - HashMap<String, String> (e.g. for the 'metadata' property)
|
||||||
/// - Vec<PlaylistEntry> (for the 'playlist' property)
|
/// - Vec<PlaylistEntry> (for the 'playlist' property)
|
||||||
|
/// - usize
|
||||||
|
/// - f64
|
||||||
///
|
///
|
||||||
/// ##Input arguments
|
/// ##Input arguments
|
||||||
///
|
///
|
||||||
|
@ -212,7 +143,7 @@ pub trait Commands {
|
||||||
///
|
///
|
||||||
/// #Example
|
/// #Example
|
||||||
/// ```
|
/// ```
|
||||||
/// let mpv: Socket = String::from(matches.value_of("socket").unwrap());
|
/// let mpv = Mpv::connect("/tmp/mpvsocket").unwrap();
|
||||||
/// let paused: bool = mpv.get_property("pause").unwrap();
|
/// let paused: bool = mpv.get_property("pause").unwrap();
|
||||||
/// let title: String = mpv.get_property("media-title").unwrap();
|
/// let title: String = mpv.get_property("media-title").unwrap();
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -231,7 +162,7 @@ pub trait Commands {
|
||||||
/// #Example
|
/// #Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let mpv: Socket = String::from(matches.value_of("socket").unwrap());
|
/// let mpv = Mpv::connect("/tmp/mpvsocket").unwrap();
|
||||||
/// let title = mpv.get_property_string("media-title").unwrap();
|
/// let title = mpv.get_property_string("media-title").unwrap();
|
||||||
/// ```
|
/// ```
|
||||||
fn get_property_string(&self, property: &str) -> Result<String, String>;
|
fn get_property_string(&self, property: &str) -> Result<String, String>;
|
||||||
|
@ -256,7 +187,7 @@ pub trait Commands {
|
||||||
///
|
///
|
||||||
/// #Example
|
/// #Example
|
||||||
/// ```
|
/// ```
|
||||||
/// let mpv: Socket = String::from(matches.value_of("socket").unwrap());
|
/// let mpv = Mpv::connect("/tmp/mpvsocket").unwrap();
|
||||||
///
|
///
|
||||||
/// //Run command 'playlist-shuffle' which takes no arguments
|
/// //Run command 'playlist-shuffle' which takes no arguments
|
||||||
/// mpv.run_command("playlist-shuffle", &vec![]);
|
/// mpv.run_command("playlist-shuffle", &vec![]);
|
||||||
|
@ -287,7 +218,7 @@ pub trait Commands {
|
||||||
///
|
///
|
||||||
/// #Example
|
/// #Example
|
||||||
/// ```
|
/// ```
|
||||||
/// let mpv: Socket = String::from(matches.value_of("socket").unwrap());
|
/// let mpv = Mpv::connect("/tmp/mpvsocket").unwrap();
|
||||||
/// mpv.set_property("pause", true);
|
/// mpv.set_property("pause", true);
|
||||||
/// ```
|
/// ```
|
||||||
fn set_property<T: SetPropertyTypeHandler<T>>(&self,
|
fn set_property<T: SetPropertyTypeHandler<T>>(&self,
|
||||||
|
@ -300,7 +231,7 @@ pub trait Commands {
|
||||||
fn toggle(&self) -> Result<(), String>;
|
fn toggle(&self) -> Result<(), String>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Commands for Socket {
|
impl Commands for Mpv {
|
||||||
fn get_metadata(&self) -> Result<HashMap<String, String>, String> {
|
fn get_metadata(&self) -> Result<HashMap<String, String>, String> {
|
||||||
match get_mpv_property(self, "metadata") {
|
match get_mpv_property(self, "metadata") {
|
||||||
Ok(map) => Ok(map),
|
Ok(map) => Ok(map),
|
||||||
|
@ -309,7 +240,10 @@ impl Commands for Socket {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_playlist(&self) -> Result<Playlist, String> {
|
fn get_playlist(&self) -> Result<Playlist, String> {
|
||||||
Playlist::get_from(self.to_string())
|
match get_mpv_property::<Vec<PlaylistEntry>>(self, "playlist") {
|
||||||
|
Ok(entries) => Ok(Playlist(entries)),
|
||||||
|
Err(msg) => Err(msg),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_property<T: GetPropertyTypeHandler>(&self, property: &str) -> Result<T, String> {
|
fn get_property<T: GetPropertyTypeHandler>(&self, property: &str) -> Result<T, String> {
|
||||||
|
@ -379,17 +313,13 @@ impl Commands for Socket {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn playlist_play_next(&self, id: usize) -> Result<(), String> {
|
fn playlist_play_next(&self, id: usize) -> Result<(), String> {
|
||||||
match Playlist::get_from(self.to_string()) {
|
match get_mpv_property::<usize>(self, "playlist-pos") {
|
||||||
Ok(playlist) => {
|
Ok(current_id) => {
|
||||||
if let Some(current_id) = playlist.current_id() {
|
|
||||||
run_mpv_command(self,
|
run_mpv_command(self,
|
||||||
"playlist-move",
|
"playlist-move",
|
||||||
&vec![&id.to_string(), &(current_id + 1).to_string()])
|
&vec![&id.to_string(), &(current_id + 1).to_string()])
|
||||||
} else {
|
|
||||||
Err("There is no file playing at the moment.".to_string())
|
|
||||||
}
|
}
|
||||||
}
|
Err(msg) => Err(msg),
|
||||||
Err(why) => Err(why),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue