Fix --device argument to various backends (#938)

Fix `--device` argument to various backends
This commit is contained in:
Roderick van Domburg 2022-01-14 08:20:29 +01:00 committed by GitHub
parent a605444d18
commit 1e54913523
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 42 additions and 57 deletions

View file

@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [contrib] Hardened security of the systemd service units
- [main] Verbose logging mode (`-v`, `--verbose`) now logs all parsed environment variables and command line arguments (credentials are redacted).
- [playback] `Sink`: `write()` now receives ownership of the packet (breaking).
- [playback] `pipe`: create file if it doesn't already exist
### Added
- [cache] Add `disable-credential-cache` flag (breaking).

View file

@ -4,19 +4,27 @@ use crate::convert::Converter;
use crate::decoder::AudioPacket;
use std::fs::OpenOptions;
use std::io::{self, Write};
use std::process::exit;
pub struct StdoutSink {
output: Option<Box<dyn Write>>,
path: Option<String>,
file: Option<String>,
format: AudioFormat,
}
impl Open for StdoutSink {
fn open(path: Option<String>, format: AudioFormat) -> Self {
fn open(file: Option<String>, format: AudioFormat) -> Self {
if let Some("?") = file.as_deref() {
info!("Usage:");
println!(" Output to stdout: --backend pipe");
println!(" Output to file: --backend pipe --device {{filename}}");
exit(0);
}
info!("Using pipe sink with format: {:?}", format);
Self {
output: None,
path,
file,
format,
}
}
@ -25,11 +33,12 @@ impl Open for StdoutSink {
impl Sink for StdoutSink {
fn start(&mut self) -> SinkResult<()> {
if self.output.is_none() {
let output: Box<dyn Write> = match self.path.as_deref() {
Some(path) => {
let output: Box<dyn Write> = match self.file.as_deref() {
Some(file) => {
let open_op = OpenOptions::new()
.write(true)
.open(path)
.create(true)
.open(file)
.map_err(|e| SinkError::ConnectionRefused(e.to_string()))?;
Box::new(open_op)
}

View file

@ -135,21 +135,18 @@ fn create_sink(
host: &cpal::Host,
device: Option<String>,
) -> Result<(rodio::Sink, rodio::OutputStream), RodioError> {
let rodio_device = match device {
Some(ask) if &ask == "?" => {
let exit_code = match list_outputs(host) {
Ok(()) => 0,
Err(e) => {
error!("{}", e);
1
}
};
exit(exit_code)
}
let rodio_device = match device.as_deref() {
Some("?") => match list_outputs(host) {
Ok(()) => exit(0),
Err(e) => {
error!("{}", e);
exit(1);
}
},
Some(device_name) => {
host.output_devices()?
.find(|d| d.name().ok().map_or(false, |name| name == device_name)) // Ignore devices for which getting name fails
.ok_or(RodioError::DeviceNotAvailable(device_name))?
.ok_or_else(|| RodioError::DeviceNotAvailable(device_name.to_string()))?
}
None => host
.default_output_device()

View file

@ -5,7 +5,7 @@ use crate::decoder::AudioPacket;
use shell_words::split;
use std::io::Write;
use std::process::{Child, Command, Stdio};
use std::process::{exit, Child, Command, Stdio};
pub struct SubprocessSink {
shell_command: String,
@ -15,16 +15,24 @@ pub struct SubprocessSink {
impl Open for SubprocessSink {
fn open(shell_command: Option<String>, format: AudioFormat) -> Self {
let shell_command = match shell_command.as_deref() {
Some("?") => {
info!("Usage: --backend subprocess --device {{shell_command}}");
exit(0);
}
Some(cmd) => cmd.to_owned(),
None => {
error!("subprocess sink requires specifying a shell command");
exit(1);
}
};
info!("Using subprocess sink with format: {:?}", format);
if let Some(shell_command) = shell_command {
SubprocessSink {
shell_command,
child: None,
format,
}
} else {
panic!("subprocess sink requires specifying a shell command");
Self {
shell_command,
child: None,
format,
}
}
}

View file

@ -748,18 +748,7 @@ fn get_setup() -> Setup {
})
.unwrap_or_default();
#[cfg(any(
feature = "alsa-backend",
feature = "rodio-backend",
feature = "portaudio-backend"
))]
let device = opt_str(DEVICE);
#[cfg(any(
feature = "alsa-backend",
feature = "rodio-backend",
feature = "portaudio-backend"
))]
if let Some(ref value) = device {
if value == "?" {
backend(device, format);
@ -769,25 +758,6 @@ fn get_setup() -> Setup {
}
}
#[cfg(not(any(
feature = "alsa-backend",
feature = "rodio-backend",
feature = "portaudio-backend"
)))]
let device: Option<String> = None;
#[cfg(not(any(
feature = "alsa-backend",
feature = "rodio-backend",
feature = "portaudio-backend"
)))]
if opt_present(DEVICE) {
warn!(
"The `--{}` / `-{}` option is not supported by the included audio backend(s), and has no effect.",
DEVICE, DEVICE_SHORT,
);
}
#[cfg(feature = "alsa-backend")]
let mixer_type = opt_str(MIXER_TYPE);
#[cfg(not(feature = "alsa-backend"))]