tubest/driver/src/bin/driver.rs
2023-11-12 17:55:21 -08:00

78 lines
2.6 KiB
Rust

use futures::StreamExt;
use libmpv::{FileState, Mpv};
use std::process::Stdio;
use tokio::io::{AsyncBufReadExt, AsyncRead, BufReader};
use tokio::process::Command;
use tokio_stream::wrappers::LinesStream;
use tubest_common::*;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let args: Vec<String> = std::env::args().skip(1).collect();
let mut subprocs: Vec<_> = args
.iter()
.map(|arg| {
Command::new(arg)
.stdout(Stdio::piped())
.spawn()
.unwrap_or_else(|e| panic!("couldn't spawn {arg}: {e:?}"))
})
.collect();
let stdin_box: Box<dyn AsyncRead + Unpin> = Box::new(tokio::io::stdin());
let mut combined =
futures::stream::select_all(Some(LinesStream::new(BufReader::new(stdin_box).lines())));
for subproc in &mut subprocs {
let stdout_box: Box<dyn AsyncRead + Unpin> = Box::new(subproc.stdout.take().unwrap());
combined.push(LinesStream::new(BufReader::new(stdout_box).lines()));
}
let mpv = Mpv::new().expect("couldn't create mpv");
#[allow(deprecated)]
let home = std::env::home_dir().unwrap();
mpv.load_config(home.join(".config/mpv/mpv.conf").to_str().unwrap())
.unwrap();
// TODO: handle other cases of combined.next().await appropriately
while let Some(Ok(line)) = combined.next().await {
// TODO: remove ? and unwrap so stuff is nonfatal
let cmd: Action = serde_json::from_str(line.trim())?;
do_action(&mpv, cmd).unwrap();
}
Ok(())
}
fn do_action(mpv: &Mpv, cmd: Action) -> Result<(), libmpv::Error> {
match cmd {
Action::Media(mcmd) => match mcmd {
MediaAction::Enqueue { path, replace } => {
let action = if replace {
FileState::Replace
} else {
FileState::AppendPlay
};
mpv.playlist_load_files(&[(&path, action, None)])?;
}
MediaAction::Pause => {
mpv.pause()?;
}
MediaAction::Unpause => {
mpv.unpause()?;
}
MediaAction::FastForward(duration) => {
mpv.seek_forward(duration.as_secs_f64())?;
}
MediaAction::Rewind(duration) => {
mpv.seek_backward(duration.as_secs_f64())?;
}
MediaAction::Next => {
mpv.playlist_next_weak()?;
}
MediaAction::Stop => {
mpv.playlist_clear()?;
}
}
}
Ok(())
}