mirror of
https://github.com/librespot-org/librespot.git
synced 2024-12-18 17:11:53 +00:00
Merge pull request #422 from misuzu/subprocess
Subprocess audio backend
This commit is contained in:
commit
4c9a8b5cac
5 changed files with 72 additions and 0 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -908,6 +908,7 @@ dependencies = [
|
|||
"portaudio-rs 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rodio 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sdl2 0.32.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"shell-words 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1725,6 +1726,11 @@ dependencies = [
|
|||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shell-words"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.1.10"
|
||||
|
@ -2540,6 +2546,7 @@ dependencies = [
|
|||
"checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68"
|
||||
"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d"
|
||||
"checksum shannon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7ea5b41c9427b56caa7b808cb548a04fb50bb5b9e98590b53f28064ff4174561"
|
||||
"checksum shell-words 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "39acde55a154c4cd3ae048ac78cc21c25f3a0145e44111b523279113dce0d94a"
|
||||
"checksum signal-hook 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4f61c4d59f3aaa9f61bba6450a9b80ba48362fd7d651689e7a10c453b1f6dc68"
|
||||
"checksum signal-hook-registry 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "913661ac8848a61e39684a3c3e7a7a14a4deec7f54b4976d0641e70dda3939b1"
|
||||
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
|
||||
|
|
|
@ -20,6 +20,7 @@ version = "0.1.0"
|
|||
futures = "0.1"
|
||||
log = "0.4"
|
||||
byteorder = "1.3"
|
||||
shell-words = "0.1.0"
|
||||
|
||||
alsa = { version = "0.2.1", optional = true }
|
||||
portaudio-rs = { version = "0.3.0", optional = true }
|
||||
|
|
|
@ -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>> {
|
||||
|
|
59
playback/src/audio_backend/subprocess.rs
Normal file
59
playback/src/audio_backend/subprocess.rs
Normal 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(())
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ extern crate log;
|
|||
|
||||
extern crate byteorder;
|
||||
extern crate futures;
|
||||
extern crate shell_words;
|
||||
|
||||
#[cfg(feature = "alsa-backend")]
|
||||
extern crate alsa;
|
||||
|
|
Loading…
Reference in a new issue