framilano
framilano

Reputation: 101

Sending "p" keyboard press to MPV in CLI using Rust std::process crate

I'm trying to create a program that interacts with MPV in its CLI implementation

let mut output = Command::new("mpv")
    .arg(selected_song.unwrap())
    .arg("--no-video")
    .arg("--vo=null")
    .arg("--video=no")
    .stdin(Stdio::piped())
    .spawn()
    .expect("Failed to execute command");

let mut mpv_stdin = output.stdin.as_ref().unwrap();
loop {
    match get_pressed_key().unwrap().as_str() {
        "exit" => {
            let _ = mpv_stdin.write_all(b"q");
            break;
        },
        "pause" => {
            let _ = mpv_stdin.write_all(b"p");
            println!("Pressed pause")
        }
        _ => {}
    }
}

let _exit_status = output.wait();

I correctly match my "pause" event in get_pressed_key and write "p" to mpv process standard input buffer, but nothing happens, the song keeps playing normally

This question has been marked as a duplicate to another one linked to the use of .flush, but it's not the correct solution or related with it, something else is going on and the linked question doesn't help as I explained in the comments.

Upvotes: 0

Views: 47

Answers (1)

Jmb
Jmb

Reputation: 23443

I managed to fix it after reading the MPV IPC documentation, we can't use STDIN to communicate with it, but we create a communication socket between commands

fn spawn_command(cmd: &str, args: &Vec<&str>) -> Result<Child, RustyError> {
    let mut command = Command::new(cmd);
    for arg in args.iter() {
        command.arg(arg);
    }
    let cmd_result = command.spawn();
    if cmd_result.is_ok() { Ok(cmd_result.unwrap()) }
    else { Err(RustyError) }
}

let mut mpv_child = spawn_command("mpv", 
    &vec![
        selected_song.unwrap().as_str(), 
        "--no-video", "--vo=null", "--video=no", 
        r"--input-ipc-server=\\.\pipe\mpvsocket"
    ]
).unwrap();

loop {
    match get_pressed_key().unwrap().as_str() {
        "exit" => {
            break;
        },
        "pause" => {
            spawn_command("cmd", 
                &vec![
                    "/C", 
                    "echo", "cycle", "pause", ">",
                    r"\\.\pipe\mpvsocket"
                ]
            ).unwrap();
        }
        _ => {}
    }
}

Upvotes: 0

Related Questions