Skip to content

Commit 1e54913

Browse files
authored
Fix --device argument to various backends (#938)
Fix `--device` argument to various backends
1 parent a605444 commit 1e54913

5 files changed

Lines changed: 42 additions & 57 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
- [contrib] Hardened security of the systemd service units
1515
- [main] Verbose logging mode (`-v`, `--verbose`) now logs all parsed environment variables and command line arguments (credentials are redacted).
1616
- [playback] `Sink`: `write()` now receives ownership of the packet (breaking).
17+
- [playback] `pipe`: create file if it doesn't already exist
1718

1819
### Added
1920
- [cache] Add `disable-credential-cache` flag (breaking).

playback/src/audio_backend/pipe.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,27 @@ use crate::convert::Converter;
44
use crate::decoder::AudioPacket;
55
use std::fs::OpenOptions;
66
use std::io::{self, Write};
7+
use std::process::exit;
78

89
pub struct StdoutSink {
910
output: Option<Box<dyn Write>>,
10-
path: Option<String>,
11+
file: Option<String>,
1112
format: AudioFormat,
1213
}
1314

1415
impl Open for StdoutSink {
15-
fn open(path: Option<String>, format: AudioFormat) -> Self {
16+
fn open(file: Option<String>, format: AudioFormat) -> Self {
17+
if let Some("?") = file.as_deref() {
18+
info!("Usage:");
19+
println!(" Output to stdout: --backend pipe");
20+
println!(" Output to file: --backend pipe --device {{filename}}");
21+
exit(0);
22+
}
23+
1624
info!("Using pipe sink with format: {:?}", format);
1725
Self {
1826
output: None,
19-
path,
27+
file,
2028
format,
2129
}
2230
}
@@ -25,11 +33,12 @@ impl Open for StdoutSink {
2533
impl Sink for StdoutSink {
2634
fn start(&mut self) -> SinkResult<()> {
2735
if self.output.is_none() {
28-
let output: Box<dyn Write> = match self.path.as_deref() {
29-
Some(path) => {
36+
let output: Box<dyn Write> = match self.file.as_deref() {
37+
Some(file) => {
3038
let open_op = OpenOptions::new()
3139
.write(true)
32-
.open(path)
40+
.create(true)
41+
.open(file)
3342
.map_err(|e| SinkError::ConnectionRefused(e.to_string()))?;
3443
Box::new(open_op)
3544
}

playback/src/audio_backend/rodio.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -135,21 +135,18 @@ fn create_sink(
135135
host: &cpal::Host,
136136
device: Option<String>,
137137
) -> Result<(rodio::Sink, rodio::OutputStream), RodioError> {
138-
let rodio_device = match device {
139-
Some(ask) if &ask == "?" => {
140-
let exit_code = match list_outputs(host) {
141-
Ok(()) => 0,
142-
Err(e) => {
143-
error!("{}", e);
144-
1
145-
}
146-
};
147-
exit(exit_code)
148-
}
138+
let rodio_device = match device.as_deref() {
139+
Some("?") => match list_outputs(host) {
140+
Ok(()) => exit(0),
141+
Err(e) => {
142+
error!("{}", e);
143+
exit(1);
144+
}
145+
},
149146
Some(device_name) => {
150147
host.output_devices()?
151148
.find(|d| d.name().ok().map_or(false, |name| name == device_name)) // Ignore devices for which getting name fails
152-
.ok_or(RodioError::DeviceNotAvailable(device_name))?
149+
.ok_or_else(|| RodioError::DeviceNotAvailable(device_name.to_string()))?
153150
}
154151
None => host
155152
.default_output_device()

playback/src/audio_backend/subprocess.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::decoder::AudioPacket;
55
use shell_words::split;
66

77
use std::io::Write;
8-
use std::process::{Child, Command, Stdio};
8+
use std::process::{exit, Child, Command, Stdio};
99

1010
pub struct SubprocessSink {
1111
shell_command: String,
@@ -15,16 +15,24 @@ pub struct SubprocessSink {
1515

1616
impl Open for SubprocessSink {
1717
fn open(shell_command: Option<String>, format: AudioFormat) -> Self {
18+
let shell_command = match shell_command.as_deref() {
19+
Some("?") => {
20+
info!("Usage: --backend subprocess --device {{shell_command}}");
21+
exit(0);
22+
}
23+
Some(cmd) => cmd.to_owned(),
24+
None => {
25+
error!("subprocess sink requires specifying a shell command");
26+
exit(1);
27+
}
28+
};
29+
1830
info!("Using subprocess sink with format: {:?}", format);
1931

20-
if let Some(shell_command) = shell_command {
21-
SubprocessSink {
22-
shell_command,
23-
child: None,
24-
format,
25-
}
26-
} else {
27-
panic!("subprocess sink requires specifying a shell command");
32+
Self {
33+
shell_command,
34+
child: None,
35+
format,
2836
}
2937
}
3038
}

src/main.rs

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -748,18 +748,7 @@ fn get_setup() -> Setup {
748748
})
749749
.unwrap_or_default();
750750

751-
#[cfg(any(
752-
feature = "alsa-backend",
753-
feature = "rodio-backend",
754-
feature = "portaudio-backend"
755-
))]
756751
let device = opt_str(DEVICE);
757-
758-
#[cfg(any(
759-
feature = "alsa-backend",
760-
feature = "rodio-backend",
761-
feature = "portaudio-backend"
762-
))]
763752
if let Some(ref value) = device {
764753
if value == "?" {
765754
backend(device, format);
@@ -769,25 +758,6 @@ fn get_setup() -> Setup {
769758
}
770759
}
771760

772-
#[cfg(not(any(
773-
feature = "alsa-backend",
774-
feature = "rodio-backend",
775-
feature = "portaudio-backend"
776-
)))]
777-
let device: Option<String> = None;
778-
779-
#[cfg(not(any(
780-
feature = "alsa-backend",
781-
feature = "rodio-backend",
782-
feature = "portaudio-backend"
783-
)))]
784-
if opt_present(DEVICE) {
785-
warn!(
786-
"The `--{}` / `-{}` option is not supported by the included audio backend(s), and has no effect.",
787-
DEVICE, DEVICE_SHORT,
788-
);
789-
}
790-
791761
#[cfg(feature = "alsa-backend")]
792762
let mixer_type = opt_str(MIXER_TYPE);
793763
#[cfg(not(feature = "alsa-backend"))]

0 commit comments

Comments
 (0)