mpv_audio/
lib.rs

1use std::process::{Command, Stdio, Child};
2
3use std::io::{self, Write};
4
5#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
6pub enum AudioFormat {
7    U8,
8    S8,
9    U16Le,
10    U16Be,
11    S16Le,
12    S16Be,
13    U24Le,
14    U24Be,
15    S24Le,
16    S24Be,
17    U32Le,
18    U32Be,
19    S32Le,
20    S32Be,
21    FloatLe,
22    FloatBe,
23    DoubleLe,
24    DoubleBe,
25    U16,
26    S16,
27    U24,
28    S24,
29    U32,
30    S32,
31    Float,
32    Double,
33}
34
35impl std::fmt::Display for AudioFormat {
36    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
37        match *self {
38            default @ _ => write!(f, "{}", format!("{:?}", default).to_ascii_lowercase()),
39        }
40    }
41}
42
43pub struct AudioOut {
44   child: Child 
45}
46
47impl AudioOut {
48    pub fn open(af: AudioFormat, rate: i32, channels: i32) -> io::Result<AudioOut> {
49        // what else did you expect?
50        let mut cmd = Command::new("mpv");
51        cmd.arg("--demuxer=rawaudio")
52            .arg(format!("--demuxer-rawaudio-channels={}", channels))
53            .arg(format!("--demuxer-rawaudio-format={}", af))
54            .arg(format!("--demuxer-rawaudio-rate={}", rate))
55            .arg("-")
56            .stdin(Stdio::piped()).stdout(Stdio::null()).stderr(Stdio::null());
57        cmd.spawn().map(|child| AudioOut { child })
58    }
59}
60
61impl Write for AudioOut {
62    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
63        self.child.stdin.as_mut().unwrap().write(buf)
64    }
65    fn flush(&mut self) -> io::Result<()> {
66        Ok(())
67    }
68}
69
70impl Drop for AudioOut {
71    fn drop(&mut self) {
72        self.child.stdin.take();
73        self.child.kill().ok(); // if for some reason closing the pipe didn't kill it
74        self.child.wait().ok(); // should we do this? idk
75    }
76}