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 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(); self.child.wait().ok(); }
76}