mirror of
https://github.com/librespot-org/librespot.git
synced 2024-12-18 17:11:53 +00:00
Feature-gate passthrough decoder
This commit is contained in:
parent
3f95a45b27
commit
552d9145f4
5 changed files with 36 additions and 14 deletions
|
@ -72,6 +72,8 @@ gstreamer-backend = ["librespot-playback/gstreamer-backend"]
|
|||
|
||||
with-dns-sd = ["librespot-core/with-dns-sd", "librespot-discovery/with-dns-sd"]
|
||||
|
||||
passthrough-decoder = ["librespot-playback/passthrough-decoder"]
|
||||
|
||||
default = ["rodio-backend"]
|
||||
|
||||
[package.metadata.deb]
|
||||
|
|
|
@ -46,7 +46,7 @@ cpal = { version = "0.13", optional = true }
|
|||
symphonia = { version = "0.4", default-features = false, features = ["mp3", "ogg", "vorbis"] }
|
||||
|
||||
# Legacy Ogg container decoder for the passthrough decoder
|
||||
ogg = "0.8"
|
||||
ogg = { version = "0.8", optional = true }
|
||||
|
||||
# Dithering
|
||||
rand = { version = "0.8", features = ["small_rng"] }
|
||||
|
@ -61,3 +61,5 @@ rodio-backend = ["rodio", "cpal"]
|
|||
rodiojack-backend = ["rodio", "cpal/jack"]
|
||||
sdl-backend = ["sdl2"]
|
||||
gstreamer-backend = ["gstreamer", "gstreamer-app", "glib"]
|
||||
|
||||
passthrough-decoder = ["ogg"]
|
||||
|
|
|
@ -2,7 +2,9 @@ use std::ops::Deref;
|
|||
|
||||
use thiserror::Error;
|
||||
|
||||
#[cfg(feature = "passthrough-decoder")]
|
||||
mod passthrough_decoder;
|
||||
#[cfg(feature = "passthrough-decoder")]
|
||||
pub use passthrough_decoder::PassthroughDecoder;
|
||||
|
||||
mod symphonia_decoder;
|
||||
|
@ -41,7 +43,7 @@ impl AudioPacket {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn oggdata(&self) -> AudioPacketResult<&[u8]> {
|
||||
pub fn raw(&self) -> AudioPacketResult<&[u8]> {
|
||||
match self {
|
||||
AudioPacket::Raw(d) => Ok(d),
|
||||
AudioPacket::Samples(_) => Err(AudioPacketError::Samples),
|
||||
|
|
|
@ -35,13 +35,14 @@ use crate::{
|
|||
config::{Bitrate, NormalisationMethod, NormalisationType, PlayerConfig},
|
||||
convert::Converter,
|
||||
core::{util::SeqGenerator, Error, Session, SpotifyId},
|
||||
decoder::{
|
||||
AudioDecoder, AudioPacket, AudioPacketPosition, PassthroughDecoder, SymphoniaDecoder,
|
||||
},
|
||||
decoder::{AudioDecoder, AudioPacket, AudioPacketPosition, SymphoniaDecoder},
|
||||
metadata::audio::{AudioFileFormat, AudioFiles, AudioItem},
|
||||
mixer::AudioFilter,
|
||||
};
|
||||
|
||||
#[cfg(feature = "passthrough-decoder")]
|
||||
use crate::decoder::PassthroughDecoder;
|
||||
|
||||
use crate::SAMPLES_PER_SECOND;
|
||||
|
||||
const PRELOAD_NEXT_TRACK_BEFORE_END_DURATION_MS: u32 = 30000;
|
||||
|
@ -931,9 +932,7 @@ impl PlayerTrackLoader {
|
|||
}
|
||||
};
|
||||
|
||||
let result = if self.config.passthrough {
|
||||
PassthroughDecoder::new(audio_file, format).map(|x| Box::new(x) as Decoder)
|
||||
} else {
|
||||
let mut symphonia_decoder = |audio_file, format| {
|
||||
SymphoniaDecoder::new(audio_file, format).map(|mut decoder| {
|
||||
// For formats other that Vorbis, we'll try getting normalisation data from
|
||||
// ReplayGain metadata fields, if present.
|
||||
|
@ -944,12 +943,22 @@ impl PlayerTrackLoader {
|
|||
})
|
||||
};
|
||||
|
||||
#[cfg(feature = "passthrough-decoder")]
|
||||
let decoder_type = if self.config.passthrough {
|
||||
PassthroughDecoder::new(audio_file, format).map(|x| Box::new(x) as Decoder)
|
||||
} else {
|
||||
symphonia_decoder(audio_file, format)
|
||||
};
|
||||
|
||||
#[cfg(not(feature = "passthrough-decoder"))]
|
||||
let decoder_type = symphonia_decoder(audio_file, format);
|
||||
|
||||
let normalisation_data = normalisation_data.unwrap_or_else(|| {
|
||||
warn!("Unable to get normalisation data, continuing with defaults.");
|
||||
NormalisationData::default()
|
||||
});
|
||||
|
||||
let mut decoder = match result {
|
||||
let mut decoder = match decoder_type {
|
||||
Ok(decoder) => decoder,
|
||||
Err(e) if is_cached => {
|
||||
warn!(
|
||||
|
|
17
src/main.rs
17
src/main.rs
|
@ -227,6 +227,7 @@ fn get_setup() -> Setup {
|
|||
const NORMALISATION_RELEASE: &str = "normalisation-release";
|
||||
const NORMALISATION_THRESHOLD: &str = "normalisation-threshold";
|
||||
const ONEVENT: &str = "onevent";
|
||||
#[cfg(feature = "passthrough-decoder")]
|
||||
const PASSTHROUGH: &str = "passthrough";
|
||||
const PASSWORD: &str = "password";
|
||||
const PROXY: &str = "proxy";
|
||||
|
@ -262,6 +263,7 @@ fn get_setup() -> Setup {
|
|||
const NAME_SHORT: &str = "n";
|
||||
const DISABLE_DISCOVERY_SHORT: &str = "O";
|
||||
const ONEVENT_SHORT: &str = "o";
|
||||
#[cfg(feature = "passthrough-decoder")]
|
||||
const PASSTHROUGH_SHORT: &str = "P";
|
||||
const PASSWORD_SHORT: &str = "p";
|
||||
const EMIT_SINK_EVENTS_SHORT: &str = "Q";
|
||||
|
@ -371,11 +373,6 @@ fn get_setup() -> Setup {
|
|||
EMIT_SINK_EVENTS,
|
||||
"Run PROGRAM set by `--onevent` before the sink is opened and after it is closed.",
|
||||
)
|
||||
.optflag(
|
||||
PASSTHROUGH_SHORT,
|
||||
PASSTHROUGH,
|
||||
"Pass a raw stream to the output. Only works with the pipe and subprocess backends.",
|
||||
)
|
||||
.optflag(
|
||||
ENABLE_VOLUME_NORMALISATION_SHORT,
|
||||
ENABLE_VOLUME_NORMALISATION,
|
||||
|
@ -568,6 +565,13 @@ fn get_setup() -> Setup {
|
|||
"PORT",
|
||||
);
|
||||
|
||||
#[cfg(feature = "passthrough-decoder")]
|
||||
opts.optflag(
|
||||
PASSTHROUGH_SHORT,
|
||||
PASSTHROUGH,
|
||||
"Pass a raw stream to the output. Only works with the pipe and subprocess backends.",
|
||||
);
|
||||
|
||||
let args: Vec<_> = std::env::args_os()
|
||||
.filter_map(|s| match s.into_string() {
|
||||
Ok(valid) => Some(valid),
|
||||
|
@ -1505,7 +1509,10 @@ fn get_setup() -> Setup {
|
|||
},
|
||||
};
|
||||
|
||||
#[cfg(feature = "passthrough-decoder")]
|
||||
let passthrough = opt_present(PASSTHROUGH);
|
||||
#[cfg(not(feature = "passthrough-decoder"))]
|
||||
let passthrough = false;
|
||||
|
||||
PlayerConfig {
|
||||
bitrate,
|
||||
|
|
Loading…
Reference in a new issue