1
0
Fork 0
mirror of https://github.com/librespot-org/librespot.git synced 2025-10-06 03:50:06 +02:00

Added subprocess audio backend

This commit is contained in:
misuzu 2020-01-24 02:35:24 +02:00
parent 01be8e7efa
commit b8617f54a9
5 changed files with 72 additions and 0 deletions

View file

@ -46,6 +46,9 @@ use self::sdl::SdlSink;
mod pipe;
use self::pipe::StdoutSink;
mod subprocess;
use self::subprocess::SubprocessSink;
pub const BACKENDS: &'static [(&'static str, fn(Option<String>) -> Box<dyn Sink>)] = &[
#[cfg(feature = "alsa-backend")]
("alsa", mk_sink::<AlsaSink>),
@ -60,6 +63,7 @@ pub const BACKENDS: &'static [(&'static str, fn(Option<String>) -> Box<dyn Sink>
#[cfg(feature = "sdl-backend")]
("sdl", mk_sink::<SdlSink>),
("pipe", mk_sink::<StdoutSink>),
("subprocess", mk_sink::<SubprocessSink>),
];
pub fn find(name: Option<String>) -> Option<fn(Option<String>) -> Box<dyn Sink>> {

View file

@ -0,0 +1,59 @@
use super::{Open, Sink};
use shell_words::split;
use std::io::{self, Write};
use std::mem;
use std::process::{Child, Command, Stdio};
use std::slice;
pub struct SubprocessSink {
shell_command: String,
child: Option<Child>,
}
impl Open for SubprocessSink {
fn open(shell_command: Option<String>) -> SubprocessSink {
if let Some(shell_command) = shell_command {
SubprocessSink {
shell_command: shell_command,
child: None,
}
} else {
panic!("subprocess sink requires specifying a shell command");
}
}
}
impl Sink for SubprocessSink {
fn start(&mut self) -> io::Result<()> {
let args = split(&self.shell_command).unwrap();
self.child = Some(
Command::new(&args[0])
.args(&args[1..])
.stdin(Stdio::piped())
.spawn()?,
);
Ok(())
}
fn stop(&mut self) -> io::Result<()> {
if let Some(child) = &mut self.child.take() {
child.kill()?;
child.wait()?;
}
Ok(())
}
fn write(&mut self, data: &[i16]) -> io::Result<()> {
let data: &[u8] = unsafe {
slice::from_raw_parts(
data.as_ptr() as *const u8,
data.len() * mem::size_of::<i16>(),
)
};
if let Some(child) = &mut self.child {
let child_stdin = child.stdin.as_mut().unwrap();
child_stdin.write_all(data)?;
}
Ok(())
}
}