Enum Input

Source
pub enum Input {
    Lazy(Box<dyn Compose>),
    Live(LiveInput, Option<Box<dyn Compose>>),
}
Expand description

An audio source, which can be live or lazily initialised.

This can be created from a wide variety of sources:

  • Any owned byte slice: &'static [u8], Bytes, or Vec<u8>,
  • File offers a lazy way to open local audio files,
  • HttpRequest streams a given file from a URL using the reqwest HTTP library,
  • YoutubeDl uses yt-dlp (or any other youtube-dl-like program) to scrape a target URL for a usable audio stream, before opening an HttpRequest.

Any Input (or struct with impl Into<Input>) can also be made into a Track via From/Into.

§Example

use songbird::{
    driver::Driver,
    input::{codecs::*, Compose, Input, MetadataError, YoutubeDl},
    tracks::Track,
};
// Inputs are played using a `Driver`, or `Call`.
let mut driver = Driver::new(Default::default());

// Lazy inputs take very little resources, and don't occupy any resources until we
// need to play them (by default).
let mut lazy = YoutubeDl::new(
    reqwest::Client::new(),
    // Referenced under CC BY-NC-SA 3.0 -- https://creativecommons.org/licenses/by-nc-sa/3.0/
    "https://cloudkicker.bandcamp.com/track/94-days",
);
let lazy_c = lazy.clone();

// With sources like `YoutubeDl`, we can get metadata from, e.g., a track's page.
let aux_metadata = lazy.aux_metadata().await.unwrap();
assert_eq!(aux_metadata.track, Some("94 Days".to_string()));

// Once we pass an `Input` to the `Driver`, we can only remotely control it via
// a `TrackHandle`.
let handle = driver.play_input(lazy.into());

// We can also modify some of its initial state via `Track`s.
let handle = driver.play(Track::from(lazy_c).volume(0.5).pause());

// In-memory sources like `Vec<u8>`, or `&'static [u8]` are easy to use, and only take a
// little time for the mixer to parse their headers.
// You can also use the adapters in `songbird::input::cached::*`to keep a source
// from the Internet, HTTP, or a File in-memory *and* share it among calls.
let in_memory = include_bytes!("../../resources/ting.mp3");
let mut in_memory_input = in_memory.into();

// This source is live...
assert!(matches!(in_memory_input, Input::Live(..)));
// ...but not yet playable, and we can't access its `Metadata`.
assert!(!in_memory_input.is_playable());
assert!(matches!(in_memory_input.metadata(), Err(MetadataError::NotParsed)));

// If we want to inspect metadata (and we can't use AuxMetadata for any reason), we have
// to parse the track ourselves.
//
// We can access it on a live track using `TrackHandle::action()`.
in_memory_input = in_memory_input
    .make_playable_async(get_codec_registry(), get_probe())
    .await
    .expect("WAV support is included, and this file is good!");

// Symphonia's metadata can be difficult to use: prefer `AuxMetadata` when you can!
use symphonia_core::meta::{StandardTagKey, Value};
let mut metadata = in_memory_input.metadata();
let meta = metadata.as_mut().unwrap();
let mut probed = meta.probe.get().unwrap();

let track_name = probed
    .current().unwrap()
    .tags().iter().filter(|v| v.std_key == Some(StandardTagKey::TrackTitle))
    .next().unwrap();
if let Value::String(s) = &track_name.value {
    assert_eq!(s, "Ting!");
} else { panic!() };

// ...and these are played like any other input.
let handle = driver.play_input(in_memory_input);

Variants§

§

Lazy(Box<dyn Compose>)

A byte source which is not yet initialised.

When a parent track is either played or explicitly readied, the inner Compose is used to create an Input::Live.

Tuple Fields

§0: Box<dyn Compose>

A trait object which can be used to (re)create a usable byte stream.

§

Live(LiveInput, Option<Box<dyn Compose>>)

An initialised byte source.

This contains a raw byte stream, the lazy initialiser that was used, as well as any symphonia-specific format data and/or hints.

Tuple Fields

§0: LiveInput

The byte source, plus symphonia-specific data.

§1: Option<Box<dyn Compose>>

The struct used to initialise this source, if available.

This is used to recreate the stream when a source does not support backward seeking, if present.

Implementations§

Source§

impl Input

Source

pub async fn aux_metadata(&mut self) -> Result<AuxMetadata, AuxMetadataError>

Requests auxiliary metadata which can be accessed without parsing the file.

This method will never be called by songbird but allows, for instance, access to metadata which might only be visible to a web crawler, e.g., uploader or source URL.

This requires that the Input has a Compose available to use, otherwise it will always fail with AudioStreamError::Unsupported.

Source

pub fn metadata(&mut self) -> Result<Metadata<'_>, MetadataError>

Tries to get any information about this audio stream acquired during parsing.

Only exists when this input is both Self::Live and has been fully parsed. In general, you probably want to use Self::aux_metadata.

Source

pub fn make_live(self, handle: &TokioHandle) -> Result<Self, AudioStreamError>

Initialises (but does not parse) an Input::Lazy into an Input::Live, placing blocking I/O on the current thread.

This requires a [TokioHandle] to a tokio runtime to spawn any async sources.

This is a blocking operation. If you wish to use this from an async task, you must do so via Self::make_live_async.

This is a no-op for an Input::Live.

Source

pub async fn make_live_async(self) -> Result<Self, AudioStreamError>

Initialises (but does not parse) an Input::Lazy into an Input::Live, placing blocking I/O on the a spawn_blocking executor.

This is a no-op for an Input::Live.

Source

pub fn make_playable( self, codecs: &CodecRegistry, probe: &Probe, handle: &TokioHandle, ) -> Result<Self, MakePlayableError>

Initialises and parses an Input::Lazy into an Input::Live, placing blocking I/O on the current thread.

This requires a [TokioHandle] to a tokio runtime to spawn any async sources. If you can’t access one, then consider manually using LiveInput::promote.

This is a blocking operation. Symphonia uses standard library I/O (e.g., Read, Seek). If you wish to use this from an async task, you must do so within spawn_blocking.

Source

pub async fn make_playable_async( self, codecs: &'static CodecRegistry, probe: &'static Probe, ) -> Result<Self, MakePlayableError>

Initialises and parses an Input::Lazy into an Input::Live, placing blocking I/O on a tokio blocking thread.

Source

pub fn is_playable(&self) -> bool

Returns whether this audio stream is full initialised, parsed, and ready to play (e.g., Self::Live(LiveInput::Parsed(p), _)).

Source

pub fn live(&self) -> Option<&LiveInput>

Returns a reference to the live input, if it has been created via Self::make_live or Self::make_live_async.

Source

pub fn live_mut(&mut self) -> Option<&mut LiveInput>

Returns a mutable reference to the live input, if it been created via Self::make_live or Self::make_live_async.

Source

pub fn parsed(&self) -> Option<&Parsed>

Returns a reference to the data parsed from this input stream, if it has been made available via Self::make_playable or LiveInput::promote.

Source

pub fn parsed_mut(&mut self) -> Option<&mut Parsed>

Returns a mutable reference to the data parsed from this input stream, if it has been made available via Self::make_playable or LiveInput::promote.

Trait Implementations§

Source§

impl From<ChildContainer> for Input

Source§

fn from(val: ChildContainer) -> Self

Converts to this type from the input type.
Source§

impl From<Compressed> for Input

Source§

fn from(val: Compressed) -> Input

Converts to this type from the input type.
Source§

impl From<Decompressed> for Input

Source§

fn from(val: Decompressed) -> Input

Converts to this type from the input type.
Source§

impl<P: AsRef<Path> + Send + Sync + 'static> From<File<P>> for Input

Source§

fn from(val: File<P>) -> Self

Converts to this type from the input type.
Source§

impl From<HlsRequest> for Input

Source§

fn from(val: HlsRequest) -> Self

Converts to this type from the input type.
Source§

impl From<HttpRequest> for Input

Source§

fn from(val: HttpRequest) -> Self

Converts to this type from the input type.
Source§

impl From<Memory> for Input

Source§

fn from(val: Memory) -> Input

Converts to this type from the input type.
Source§

impl<A: MediaSource + Send + Sync + 'static> From<RawAdapter<A>> for Input

Source§

fn from(val: RawAdapter<A>) -> Self

Converts to this type from the input type.
Source§

impl<T: AsRef<[u8]> + Send + Sync + 'static> From<T> for Input

Source§

fn from(val: T) -> Self

Converts to this type from the input type.
Source§

impl From<YoutubeDl<'static>> for Input

Source§

fn from(val: YoutubeDl<'static>) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl Freeze for Input

§

impl !RefUnwindSafe for Input

§

impl Send for Input

§

impl !Sync for Input

§

impl Unpin for Input

§

impl !UnwindSafe for Input

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

§

fn into_sample(self) -> T

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

impl<T> ErasedDestructor for T
where T: 'static,

§

impl<T> MaybeSendSync for T