Docs: Move to new intra-doc links, make events non-exhaustive. (#19)
Far cleaner and more reliable than the old doc-link pattern. Also allowed me to spot some event types and sources which should have been made non_exhaustive.
This commit is contained in:
@@ -12,7 +12,7 @@ pub struct Config {
|
||||
/// driver is actively connected, but will apply to subsequent
|
||||
/// sessions.
|
||||
///
|
||||
/// [`CryptoMode::Normal`]: enum.CryptoMode.html#variant.Normal
|
||||
/// [`CryptoMode::Normal`]: CryptoMode::Normal
|
||||
pub crypto_mode: CryptoMode,
|
||||
/// Configures whether decoding and decryption occur for all received packets.
|
||||
///
|
||||
@@ -24,10 +24,10 @@ pub struct Config {
|
||||
/// Defaults to [`DecodeMode::Decrypt`]. This is due to per-packet decoding costs,
|
||||
/// which most users will not want to pay, but allowing speaking events which are commonly used.
|
||||
///
|
||||
/// [`DecodeMode::Decode`]: enum.DecodeMode.html#variant.Decode
|
||||
/// [`DecodeMode::Decrypt`]: enum.DecodeMode.html#variant.Decrypt
|
||||
/// [`DecodeMode::Pass`]: enum.DecodeMode.html#variant.Pass
|
||||
/// [user speaking events]: ../events/enum.CoreEvent.html#variant.SpeakingUpdate
|
||||
/// [`DecodeMode::Decode`]: DecodeMode::Decode
|
||||
/// [`DecodeMode::Decrypt`]: DecodeMode::Decrypt
|
||||
/// [`DecodeMode::Pass`]: DecodeMode::Pass
|
||||
/// [user speaking events]: crate::events::CoreEvent::SpeakingUpdate
|
||||
pub decode_mode: DecodeMode,
|
||||
/// Number of concurrently active tracks to allocate memory for.
|
||||
///
|
||||
|
||||
@@ -12,7 +12,7 @@ pub enum DecodeMode {
|
||||
/// are not present, as they are encrypted.
|
||||
/// This event requires such functionality.*
|
||||
///
|
||||
/// [user speaking events]: ../events/enum.CoreEvent.html#variant.SpeakingUpdate
|
||||
/// [user speaking events]: crate::events::CoreEvent::SpeakingUpdate
|
||||
Pass,
|
||||
/// Decrypts the body of each received packet.
|
||||
///
|
||||
|
||||
@@ -125,8 +125,8 @@ impl Driver {
|
||||
///
|
||||
/// This can be a source created via [`ffmpeg`] or [`ytdl`].
|
||||
///
|
||||
/// [`ffmpeg`]: ../input/fn.ffmpeg.html
|
||||
/// [`ytdl`]: ../input/fn.ytdl.html
|
||||
/// [`ffmpeg`]: crate::input::ffmpeg
|
||||
/// [`ytdl`]: crate::input::ytdl
|
||||
#[instrument(skip(self))]
|
||||
pub fn play_source(&mut self, source: Input) -> TrackHandle {
|
||||
let (player, handle) = super::create_player(source);
|
||||
@@ -140,7 +140,7 @@ impl Driver {
|
||||
/// Unlike [`play_source`], this stops all other sources attached
|
||||
/// to the channel.
|
||||
///
|
||||
/// [`play_source`]: #method.play_source
|
||||
/// [`play_source`]: Driver::play_source
|
||||
#[instrument(skip(self))]
|
||||
pub fn play_only_source(&mut self, source: Input) -> TrackHandle {
|
||||
let (player, handle) = super::create_player(source);
|
||||
@@ -156,9 +156,9 @@ impl Driver {
|
||||
/// that this allows for direct manipulation of the [`Track`] object
|
||||
/// before it is passed over to the voice and mixing contexts.
|
||||
///
|
||||
/// [`create_player`]: ../tracks/fn.create_player.html
|
||||
/// [`Track`]: ../tracks/struct.Track.html
|
||||
/// [`play_source`]: #method.play_source
|
||||
/// [`create_player`]: crate::tracks::create_player
|
||||
/// [`create_player`]: crate::tracks::Track
|
||||
/// [`play_source`]: Driver::play_source
|
||||
#[instrument(skip(self))]
|
||||
pub fn play(&mut self, track: Track) {
|
||||
self.send(CoreMessage::AddTrack(track));
|
||||
@@ -171,10 +171,10 @@ impl Driver {
|
||||
/// channel. Like [`play`], however, this allows for direct manipulation of the
|
||||
/// [`Track`] object before it is passed over to the voice and mixing contexts.
|
||||
///
|
||||
/// [`create_player`]: ../tracks/fn.create_player.html
|
||||
/// [`Track`]: ../tracks/struct.Track.html
|
||||
/// [`play_only_source`]: #method.play_only_source
|
||||
/// [`play`]: #method.play
|
||||
/// [`create_player`]: crate::tracks::create_player
|
||||
/// [`Track`]: crate::tracks::Track
|
||||
/// [`play_only_source`]: Driver::play_only_source
|
||||
/// [`play`]: Driver::play
|
||||
#[instrument(skip(self))]
|
||||
pub fn play_only(&mut self, track: Track) {
|
||||
self.send(CoreMessage::SetTrack(Some(track)));
|
||||
@@ -216,9 +216,9 @@ impl Driver {
|
||||
/// within the supplied function or closure. *Taking excess time could prevent
|
||||
/// timely sending of packets, causing audio glitches and delays*.
|
||||
///
|
||||
/// [`Track`]: ../tracks/struct.Track.html
|
||||
/// [`TrackEvent`]: ../events/enum.TrackEvent.html
|
||||
/// [`EventContext`]: ../events/enum.EventContext.html
|
||||
/// [`Track`]: crate::tracks::Track
|
||||
/// [`TrackEvent`]: crate::events::TrackEvent
|
||||
/// [`EventContext`]: crate::events::EventContext
|
||||
#[instrument(skip(self, action))]
|
||||
pub fn add_global_event<F: EventHandler + 'static>(&mut self, event: Event, action: F) {
|
||||
self.send(CoreMessage::AddEvent(EventData::new(event, action)));
|
||||
@@ -243,8 +243,8 @@ impl Driver {
|
||||
/// Queue additions should be made via [`enqueue`] and
|
||||
/// [`enqueue_source`].
|
||||
///
|
||||
/// [`enqueue`]: #method.enqueue
|
||||
/// [`enqueue_source`]: #method.enqueue_source
|
||||
/// [`enqueue`]: Driver::enqueue
|
||||
/// [`enqueue_source`]: Driver::enqueue_source
|
||||
pub fn queue(&self) -> &TrackQueue {
|
||||
&self.queue
|
||||
}
|
||||
@@ -253,7 +253,7 @@ impl Driver {
|
||||
///
|
||||
/// Requires the `"builtin-queue"` feature.
|
||||
///
|
||||
/// [`Input`]: ../input/struct.input.html
|
||||
/// [`Input`]: crate::input::Input
|
||||
pub fn enqueue_source(&mut self, source: Input) {
|
||||
let (mut track, _) = tracks::create_player(source);
|
||||
self.queue.add_raw(&mut track);
|
||||
@@ -264,7 +264,7 @@ impl Driver {
|
||||
///
|
||||
/// Requires the `"builtin-queue"` feature.
|
||||
///
|
||||
/// [`Track`]: ../tracks/struct.track.html
|
||||
/// [`Track`]: crate::tracks::Track
|
||||
pub fn enqueue(&mut self, mut track: Track) {
|
||||
self.queue.add_raw(&mut track);
|
||||
self.play(track);
|
||||
|
||||
@@ -19,7 +19,7 @@ pub enum JoinError {
|
||||
NoSender,
|
||||
/// Tried to leave a [`Call`] which was not found.
|
||||
///
|
||||
/// [`Call`]: ../struct.Call.html
|
||||
/// [`Call`]: crate::Call
|
||||
NoCall,
|
||||
#[cfg(feature = "serenity")]
|
||||
/// Serenity-specific WebSocket send error.
|
||||
|
||||
@@ -8,17 +8,18 @@ use discortp::{rtcp::Rtcp, rtp::Rtp};
|
||||
/// Information about which tracks or data fired an event.
|
||||
///
|
||||
/// [`Track`] events may be local or global, and have no tracks
|
||||
/// if fired on the global context via [`Handler::add_global_event`].
|
||||
/// if fired on the global context via [`Driver::add_global_event`].
|
||||
///
|
||||
/// [`Track`]: ../tracks/struct.Track.html
|
||||
/// [`Handler::add_global_event`]: ../struct.Handler.html#method.add_global_event
|
||||
/// [`Track`]: crate::tracks::Track
|
||||
/// [`Driver::add_global_event`]: crate::driver::Driver::add_global_event
|
||||
#[derive(Clone, Debug)]
|
||||
#[non_exhaustive]
|
||||
pub enum EventContext<'a> {
|
||||
/// Track event context, passed to events created via [`TrackHandle::add_event`],
|
||||
/// [`EventStore::add_event`], or relevant global events.
|
||||
///
|
||||
/// [`EventStore::add_event`]: struct.EventStore.html#method.add_event
|
||||
/// [`TrackHandle::add_event`]: ../tracks/struct.TrackHandle.html#method.add_event
|
||||
/// [`EventStore::add_event`]: EventStore::add_event
|
||||
/// [`TrackHandle::add_event`]: TrackHandle::add_event
|
||||
Track(&'a [(&'a TrackState, &'a TrackHandle)]),
|
||||
/// Speaking state update, typically describing how another voice
|
||||
/// user is transmitting audio data. Clients must send at least one such
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
/// Voice core events occur on receipt of
|
||||
/// voice packets and telemetry.
|
||||
///
|
||||
/// Core events persist while the `action` in [`EventData`]
|
||||
/// returns `None`.
|
||||
///
|
||||
/// [`EventData`]: struct.EventData.html
|
||||
/// [`EventData`]: super::EventData
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
#[non_exhaustive]
|
||||
pub enum CoreEvent {
|
||||
/// Fired on receipt of a speaking state update from another host.
|
||||
///
|
||||
|
||||
@@ -17,10 +17,10 @@ impl EventData {
|
||||
/// Event handlers will be re-added with their new trigger condition,
|
||||
/// or removed if [`Cancel`]led
|
||||
///
|
||||
/// [`EventContext`]: enum.EventContext.html
|
||||
/// [`Event`]: enum.Event.html
|
||||
/// [`Delayed`]: enum.Event.html#variant.Delayed
|
||||
/// [`Cancel`]: enum.Event.html#variant.Cancel
|
||||
/// [`EventContext`]: EventContext
|
||||
/// [`Event`]: Event
|
||||
/// [`Delayed`]: Event::Delayed
|
||||
/// [`Cancel`]: Event::Cancel
|
||||
pub fn new<F: EventHandler + 'static>(event: Event, action: F) -> Self {
|
||||
Self {
|
||||
event,
|
||||
|
||||
@@ -12,16 +12,15 @@ pub use self::{context::*, core::*, data::*, store::*, track::*, untimed::*};
|
||||
use async_trait::async_trait;
|
||||
use std::time::Duration;
|
||||
|
||||
#[async_trait]
|
||||
/// Trait to handle an event which can be fired per-track, or globally.
|
||||
///
|
||||
/// These may be feasibly reused between several event sources.
|
||||
#[async_trait]
|
||||
pub trait EventHandler: Send + Sync {
|
||||
/// Respond to one received event.
|
||||
async fn act(&self, ctx: &EventContext<'_>) -> Option<Event>;
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
/// Classes of event which may occur, triggering a handler
|
||||
/// at the local (track-specific) or global level.
|
||||
///
|
||||
@@ -32,7 +31,9 @@ pub trait EventHandler: Send + Sync {
|
||||
///
|
||||
/// Event handlers themselves are described in [`EventData::action`].
|
||||
///
|
||||
/// [`EventData::action`]: struct.EventData.html#method.action
|
||||
/// [`EventData::action`]: EventData::action
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
#[non_exhaustive]
|
||||
pub enum Event {
|
||||
/// Periodic events rely upon two parameters: a *period*
|
||||
/// and an optional *phase*.
|
||||
@@ -41,7 +42,7 @@ pub enum Event {
|
||||
/// in one *period*. Periodic events repeat automatically
|
||||
/// so long as the `action` in [`EventData`] returns `None`.
|
||||
///
|
||||
/// [`EventData`]: struct.EventData.html
|
||||
/// [`EventData`]: EventData
|
||||
Periodic(Duration, Option<Duration>),
|
||||
/// Delayed events rely upon a *delay* parameter, and
|
||||
/// fire one *delay* after the audio context processes them.
|
||||
@@ -49,7 +50,7 @@ pub enum Event {
|
||||
/// Delayed events are automatically removed once fired,
|
||||
/// so long as the `action` in [`EventData`] returns `None`.
|
||||
///
|
||||
/// [`EventData`]: struct.EventData.html
|
||||
/// [`EventData`]: EventData
|
||||
Delayed(Duration),
|
||||
/// Track events correspond to certain actions or changes
|
||||
/// of state, such as a track finishing, looping, or being
|
||||
@@ -58,7 +59,7 @@ pub enum Event {
|
||||
/// Track events persist while the `action` in [`EventData`]
|
||||
/// returns `None`.
|
||||
///
|
||||
/// [`EventData`]: struct.EventData.html
|
||||
/// [`EventData`]: EventData
|
||||
Track(TrackEvent),
|
||||
/// Core events
|
||||
///
|
||||
@@ -66,7 +67,7 @@ pub enum Event {
|
||||
/// returns `None`. Core events **must** be applied globally,
|
||||
/// as attaching them to a track is a no-op.
|
||||
///
|
||||
/// [`EventData`]: struct.EventData.html
|
||||
/// [`EventData`]: EventData
|
||||
Core(CoreEvent),
|
||||
/// Cancels the event, if it was intended to persist.
|
||||
Cancel,
|
||||
|
||||
@@ -15,7 +15,7 @@ use tracing::info;
|
||||
/// Timed events are stored in a binary heap for fast selection, and have custom `Eq`,
|
||||
/// `Ord`, etc. implementations to support (only) this.
|
||||
///
|
||||
/// [`EventData`]: struct.EventData.html
|
||||
/// [`EventData`]: EventData
|
||||
pub struct EventStore {
|
||||
timed: BinaryHeap<EventData>,
|
||||
untimed: HashMap<UntimedEvent, Vec<EventData>>,
|
||||
@@ -33,7 +33,7 @@ impl EventStore {
|
||||
/// This is usually automatically installed by the driver once
|
||||
/// a track has been registered.
|
||||
///
|
||||
/// [`Track`]: ../tracks/struct.Track.html
|
||||
/// [`Track`]: crate::tracks::Track
|
||||
pub fn new_local() -> Self {
|
||||
EventStore {
|
||||
local_only: true,
|
||||
@@ -45,7 +45,7 @@ impl EventStore {
|
||||
///
|
||||
/// Updates `evt` according to [`EventData::compute_activation`].
|
||||
///
|
||||
/// [`EventData::compute_activation`]: struct.EventData.html#method.compute_activation
|
||||
/// [`EventData::compute_activation`]: EventData::compute_activation
|
||||
pub fn add_event(&mut self, mut evt: EventData, now: Duration) {
|
||||
evt.compute_activation(now);
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
/// Track events correspond to certain actions or changes
|
||||
/// of state, such as a track finishing, looping, or being
|
||||
/// manually stopped. Voice core events occur on receipt of
|
||||
@@ -7,7 +6,9 @@
|
||||
/// Track events persist while the `action` in [`EventData`]
|
||||
/// returns `None`.
|
||||
///
|
||||
/// [`EventData`]: struct.EventData.html
|
||||
/// [`EventData`]: super::EventData
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
#[non_exhaustive]
|
||||
pub enum TrackEvent {
|
||||
/// The attached track has ended.
|
||||
End,
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
use super::*;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
/// Track and voice core events.
|
||||
///
|
||||
/// Untimed events persist while the `action` in [`EventData`]
|
||||
/// returns `None`.
|
||||
///
|
||||
/// [`EventData`]: struct.EventData.html
|
||||
/// [`EventData`]: EventData
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
#[non_exhaustive]
|
||||
pub enum UntimedEvent {
|
||||
/// Untimed events belonging to a track, such as state changes, end, or loops.
|
||||
Track(TrackEvent),
|
||||
|
||||
@@ -29,8 +29,7 @@ enum Return {
|
||||
/// If the `"driver"` feature is enabled, then a Call exposes all control methods of
|
||||
/// [`Driver`] via `Deref(Mut)`.
|
||||
///
|
||||
/// [`Driver`]: driver/struct.Driver.html
|
||||
/// [`Shard`]: ../gateway/struct.Shard.html
|
||||
/// [`Driver`]: struct@Driver
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Call {
|
||||
connection: Option<(ChannelId, ConnectionProgress, Return)>,
|
||||
@@ -45,11 +44,14 @@ pub struct Call {
|
||||
/// Whether the current handler is set to mute voice connections.
|
||||
self_mute: bool,
|
||||
user_id: UserId,
|
||||
/// Will be set when a `Call` is made via the [`new`][`Call::new`]
|
||||
/// Will be set when a `Call` is made via the [`new`]
|
||||
/// method.
|
||||
///
|
||||
/// When set via [`standalone`][`Call::standalone`], it will not be
|
||||
/// When set via [`standalone`](`Call::standalone`), it will not be
|
||||
/// present.
|
||||
///
|
||||
/// [`new`]: Call::new
|
||||
/// [`standalone`]: Call::standalone
|
||||
ws: Option<Shard>,
|
||||
}
|
||||
|
||||
@@ -153,7 +155,7 @@ impl Call {
|
||||
/// **Note**: If the `Call` was created via [`standalone`], then this
|
||||
/// will _only_ update whether the connection is internally deafened.
|
||||
///
|
||||
/// [`standalone`]: #method.standalone
|
||||
/// [`standalone`]: Call::standalone
|
||||
#[instrument(skip(self))]
|
||||
pub async fn deafen(&mut self, deaf: bool) -> JoinResult<()> {
|
||||
self.self_deaf = deaf;
|
||||
@@ -217,7 +219,7 @@ impl Call {
|
||||
/// will _only_ update whether the connection is internally connected to a
|
||||
/// voice channel.
|
||||
///
|
||||
/// [`standalone`]: #method.standalone
|
||||
/// [`standalone`]: Call::standalone
|
||||
#[instrument(skip(self))]
|
||||
pub async fn leave(&mut self) -> JoinResult<()> {
|
||||
// Only send an update if we were in a voice channel.
|
||||
@@ -237,7 +239,7 @@ impl Call {
|
||||
/// **Note**: If the `Call` was created via [`standalone`], then this
|
||||
/// will _only_ update whether the connection is internally muted.
|
||||
///
|
||||
/// [`standalone`]: #method.standalone
|
||||
/// [`standalone`]: Call::standalone
|
||||
#[instrument(skip(self))]
|
||||
pub async fn mute(&mut self, mute: bool) -> JoinResult<()> {
|
||||
self.self_mute = mute;
|
||||
@@ -259,11 +261,7 @@ impl Call {
|
||||
/// You should only need to use this if you initialized the `Call` via
|
||||
/// [`standalone`].
|
||||
///
|
||||
/// Refer to the documentation for [`connect`] for when this will
|
||||
/// automatically connect to a voice channel.
|
||||
///
|
||||
/// [`connect`]: #method.connect
|
||||
/// [`standalone`]: #method.standalone
|
||||
/// [`standalone`]: Call::standalone
|
||||
#[instrument(skip(self, token))]
|
||||
pub fn update_server(&mut self, endpoint: String, token: String) {
|
||||
let try_conn = if let Some((_, ref mut progress, _)) = self.connection.as_mut() {
|
||||
@@ -282,11 +280,7 @@ impl Call {
|
||||
/// You should only need to use this if you initialized the `Call` via
|
||||
/// [`standalone`].
|
||||
///
|
||||
/// refer to the documentation for [`connect`] for when this will
|
||||
/// automatically connect to a voice channel.
|
||||
///
|
||||
/// [`connect`]: #method.connect
|
||||
/// [`standalone`]: #method.standalone
|
||||
/// [`standalone`]: Call::standalone
|
||||
#[instrument(skip(self))]
|
||||
pub fn update_state(&mut self, session_id: String) {
|
||||
let try_conn = if let Some((_, ref mut progress, _)) = self.connection.as_mut() {
|
||||
@@ -304,7 +298,7 @@ impl Call {
|
||||
///
|
||||
/// Does nothing if initialized via [`standalone`].
|
||||
///
|
||||
/// [`standalone`]: #method.standalone
|
||||
/// [`standalone`]: Call::standalone
|
||||
#[instrument(skip(self))]
|
||||
async fn update(&mut self) -> JoinResult<()> {
|
||||
if let Some(ws) = self.ws.as_mut() {
|
||||
|
||||
@@ -43,9 +43,9 @@ use tracing::{debug, trace};
|
||||
/// retrieved as **compressed Opus audio**. There is an associated memory cost,
|
||||
/// but this is far smaller than using a [`Memory`].
|
||||
///
|
||||
/// [`Input`]: ../struct.Input.html
|
||||
/// [`Memory`]: struct.Memory.html
|
||||
/// [`Restartable`]: ../struct.Restartable.html
|
||||
/// [`Input`]: Input
|
||||
/// [`Memory`]: super::Memory
|
||||
/// [`Restartable`]: crate::input::restartable::Restartable
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Compressed {
|
||||
/// Inner shared bytestore.
|
||||
@@ -59,7 +59,7 @@ pub struct Compressed {
|
||||
impl Compressed {
|
||||
/// Wrap an existing [`Input`] with an in-memory store, compressed using Opus.
|
||||
///
|
||||
/// [`Input`]: ../struct.Input.html
|
||||
/// [`Input`]: Input
|
||||
/// [`Metadata.duration`]: ../struct.Metadata.html#structfield.duration
|
||||
pub fn new(source: Input, bitrate: Bitrate) -> Result<Self> {
|
||||
Self::with_config(source, bitrate, None)
|
||||
@@ -69,10 +69,10 @@ impl Compressed {
|
||||
///
|
||||
/// `config.length_hint` may be used to control the size of the initial chunk, preventing
|
||||
/// needless allocations and copies. If this is not present, the value specified in
|
||||
/// `source`'s [`Metadata.duration`] will be used.
|
||||
/// `source`'s [`Metadata::duration`] will be used.
|
||||
///
|
||||
/// [`Input`]: ../struct.Input.html
|
||||
/// [`Metadata.duration`]: ../struct.Metadata.html#structfield.duration
|
||||
/// [`Input`]: Input
|
||||
/// [`Metadata::duration`]: crate::input::Metadata::duration
|
||||
pub fn with_config(source: Input, bitrate: Bitrate, config: Option<Config>) -> Result<Self> {
|
||||
let channels = if source.stereo {
|
||||
Channels::Stereo
|
||||
@@ -92,8 +92,8 @@ impl Compressed {
|
||||
/// `length_hint` functions as in [`new`]. This function's behaviour is undefined if your encoder
|
||||
/// has a different sample rate than 48kHz, and if the decoder has a different channel count from the source.
|
||||
///
|
||||
/// [`Input`]: ../struct.Input.html
|
||||
/// [`new`]: #method.new
|
||||
/// [`Input`]: Input
|
||||
/// [`new`]: Compressed::new
|
||||
pub fn with_encoder(
|
||||
mut source: Input,
|
||||
encoder: OpusEncoder,
|
||||
@@ -154,7 +154,7 @@ impl From<Compressed> for Input {
|
||||
///
|
||||
/// Created and managed by [`Compressed`].
|
||||
///
|
||||
/// [`Compressed`]: struct.Compressed.html
|
||||
/// [`Compressed`]: Compressed
|
||||
#[derive(Debug)]
|
||||
pub struct OpusCompressor {
|
||||
encoder: OpusEncoder,
|
||||
|
||||
@@ -25,9 +25,9 @@ use streamcatcher::{Catcher, Config};
|
||||
/// cost of audio processing. This is a significant *3 Mbps (375 kiB/s)*,
|
||||
/// or 131 MiB of RAM for a 6 minute song.
|
||||
///
|
||||
/// [`Input`]: ../struct.Input.html
|
||||
/// [`Compressed`]: struct.Compressed.html
|
||||
/// [`Restartable`]: ../struct.Restartable.html
|
||||
/// [`Input`]: Input
|
||||
/// [`Compressed`]: super::Compressed
|
||||
/// [`Restartable`]: crate::input::restartable::Restartable
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Memory {
|
||||
/// Inner shared bytestore.
|
||||
@@ -45,7 +45,7 @@ pub struct Memory {
|
||||
impl Memory {
|
||||
/// Wrap an existing [`Input`] with an in-memory store with the same codec and framing.
|
||||
///
|
||||
/// [`Input`]: ../struct.Input.html
|
||||
/// [`Input`]: Input
|
||||
pub fn new(source: Input) -> Result<Self> {
|
||||
Self::with_config(source, None)
|
||||
}
|
||||
@@ -54,10 +54,10 @@ impl Memory {
|
||||
///
|
||||
/// `length_hint` may be used to control the size of the initial chunk, preventing
|
||||
/// needless allocations and copies. If this is not present, the value specified in
|
||||
/// `source`'s [`Metadata.duration`] will be used, assuming that the source is uncompressed.
|
||||
/// `source`'s [`Metadata::duration`] will be used, assuming that the source is uncompressed.
|
||||
///
|
||||
/// [`Input`]: ../struct.Input.html
|
||||
/// [`Metadata.duration`]: ../struct.Metadata.html#structfield.duration
|
||||
/// [`Input`]: Input
|
||||
/// [`Metadata::duration`]: crate::input::Metadata::duration
|
||||
pub fn with_config(mut source: Input, config: Option<Config>) -> Result<Self> {
|
||||
let stereo = source.stereo;
|
||||
let kind = (&source.kind).into();
|
||||
|
||||
@@ -9,7 +9,7 @@ use std::{fmt::Debug, mem};
|
||||
|
||||
/// State used to decode input bytes of an [`Input`].
|
||||
///
|
||||
/// [`Input`]: ../struct.Input.html
|
||||
/// [`Input`]: Input
|
||||
#[non_exhaustive]
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Codec {
|
||||
@@ -18,19 +18,19 @@ pub enum Codec {
|
||||
///
|
||||
/// Must be combined with a non-[`Raw`] container.
|
||||
///
|
||||
/// [`Raw`]: ../enum.Container.html#variant.Raw
|
||||
/// [`Raw`]: Container::Raw
|
||||
Opus(OpusDecoderState),
|
||||
/// The inner bytestream is encoded using raw `i16` samples.
|
||||
///
|
||||
/// Must be combined with a [`Raw`] container.
|
||||
///
|
||||
/// [`Raw`]: ../enum.Container.html#variant.Raw
|
||||
/// [`Raw`]: Container::Raw
|
||||
Pcm,
|
||||
/// The inner bytestream is encoded using raw `f32` samples.
|
||||
///
|
||||
/// Must be combined with a [`Raw`] container.
|
||||
///
|
||||
/// [`Raw`]: ../enum.Container.html#variant.Raw
|
||||
/// [`Raw`]: Container::Raw
|
||||
FloatPcm,
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ impl From<&Codec> for CodecType {
|
||||
|
||||
/// Type of data being passed into an [`Input`].
|
||||
///
|
||||
/// [`Input`]: ../struct.Input.html
|
||||
/// [`Input`]: Input
|
||||
#[non_exhaustive]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum CodecType {
|
||||
@@ -56,19 +56,19 @@ pub enum CodecType {
|
||||
///
|
||||
/// Must be combined with a non-[`Raw`] container.
|
||||
///
|
||||
/// [`Raw`]: ../enum.Container.html#variant.Raw
|
||||
/// [`Raw`]: Container::Raw
|
||||
Opus,
|
||||
/// The inner bytestream is encoded using raw `i16` samples.
|
||||
///
|
||||
/// Must be combined with a [`Raw`] container.
|
||||
///
|
||||
/// [`Raw`]: ../enum.Container.html#variant.Raw
|
||||
/// [`Raw`]: Container::Raw
|
||||
Pcm,
|
||||
/// The inner bytestream is encoded using raw `f32` samples.
|
||||
///
|
||||
/// Must be combined with a [`Raw`] container.
|
||||
///
|
||||
/// [`Raw`]: ../enum.Container.html#variant.Raw
|
||||
/// [`Raw`]: Container::Raw
|
||||
FloatPcm,
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ use parking_lot::Mutex;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Inner state
|
||||
/// Inner state used to decode Opus input sources.
|
||||
pub struct OpusDecoderState {
|
||||
/// Inner decoder used to convert opus frames into a stream of samples.
|
||||
pub decoder: Arc<Mutex<OpusDecoder>>,
|
||||
|
||||
@@ -7,7 +7,7 @@ use streamcatcher::CatcherError;
|
||||
|
||||
/// An error returned when creating a new [`Input`].
|
||||
///
|
||||
/// [`Input`]: ../struct.Input.html
|
||||
/// [`Input`]: crate::input::Input
|
||||
#[derive(Debug)]
|
||||
#[non_exhaustive]
|
||||
pub enum Error {
|
||||
@@ -71,7 +71,7 @@ impl From<OpusError> for Error {
|
||||
|
||||
/// An error returned from the [`dca`] method.
|
||||
///
|
||||
/// [`dca`]: ../fn.dca.html
|
||||
/// [`dca`]: crate::input::dca
|
||||
#[derive(Debug)]
|
||||
#[non_exhaustive]
|
||||
pub enum DcaError {
|
||||
@@ -89,5 +89,5 @@ pub enum DcaError {
|
||||
|
||||
/// Convenience type for fallible return of [`Input`]s.
|
||||
///
|
||||
/// [`Input`]: ../struct.Input.html
|
||||
/// [`Input`]: crate::input::Input
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
@@ -72,6 +72,8 @@ pub(crate) async fn _ffmpeg(path: &OsStr) -> Result<Input> {
|
||||
/// "-",
|
||||
/// ]));
|
||||
/// ```
|
||||
///
|
||||
/// [`ffmpeg`]: ffmpeg
|
||||
pub async fn ffmpeg_optioned<P: AsRef<OsStr>>(
|
||||
path: P,
|
||||
pre_input_args: &[&str],
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::time::Duration;
|
||||
|
||||
/// Information about an [`Input`] source.
|
||||
///
|
||||
/// [`Input`]: struct.Input.html
|
||||
/// [`Input`]: crate::input::Input
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
||||
pub struct Metadata {
|
||||
/// The title of this stream.
|
||||
@@ -95,7 +95,7 @@ impl Metadata {
|
||||
}
|
||||
}
|
||||
|
||||
/// Use `youtube-dl` to extract metadata for an online resource.
|
||||
/// Use `youtube-dl`'s JSON output for metadata for an online resource.
|
||||
pub fn from_ytdl_output(value: Value) -> Self {
|
||||
let obj = value.as_object();
|
||||
|
||||
|
||||
@@ -20,13 +20,13 @@
|
||||
//! * its [`Input`] [meets the promises described herein](codec/struct.OpusDecoderState.html#structfield.allow_passthrough),
|
||||
//! * and that track's volume is set to `1.0`.
|
||||
//!
|
||||
//! [`Input`]: struct.Input.html
|
||||
//! [`Reader`]: reader/enum.Reader.html
|
||||
//! [`Container`]: enum.Container.html
|
||||
//! [`Codec`]: codec/enum.Codec.html
|
||||
//! [`Input`]: Input
|
||||
//! [`Reader`]: reader::Reader
|
||||
//! [`Container`]: Container
|
||||
//! [`Codec`]: Codec
|
||||
//! [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
|
||||
//! [`Compressed`]: cached/struct.Compressed.html
|
||||
//! [`dca`]: fn.dca.html
|
||||
//! [`Compressed`]: cached::Compressed
|
||||
//! [`dca`]: dca()
|
||||
|
||||
pub mod cached;
|
||||
mod child;
|
||||
@@ -80,8 +80,8 @@ use tracing::{debug, error};
|
||||
///
|
||||
/// See the [module root] for more information.
|
||||
///
|
||||
/// [`Reader`]: enum.Reader.html
|
||||
/// [module root]: index.html
|
||||
/// [`Reader`]: Reader
|
||||
/// [module root]: super
|
||||
#[derive(Debug)]
|
||||
pub struct Input {
|
||||
/// Information about the played source.
|
||||
@@ -130,7 +130,7 @@ impl Input {
|
||||
|
||||
/// Returns whether the inner [`Reader`] implements [`Seek`].
|
||||
///
|
||||
/// [`Reader`]: reader/enum.Reader.html
|
||||
/// [`Reader`]: reader::Reader
|
||||
/// [`Seek`]: https://doc.rust-lang.org/std/io/trait.Seek.html
|
||||
pub fn is_seekable(&self) -> bool {
|
||||
self.reader.is_seekable()
|
||||
@@ -143,7 +143,7 @@ impl Input {
|
||||
|
||||
/// Returns the type of the inner [`Codec`].
|
||||
///
|
||||
/// [`Codec`]: codec/enum.Codec.html
|
||||
/// [`Codec`]: Codec
|
||||
pub fn get_type(&self) -> CodecType {
|
||||
(&self.kind).into()
|
||||
}
|
||||
|
||||
@@ -23,14 +23,14 @@ use streamcatcher::{Catcher, TxCatcher};
|
||||
/// Users may define their own data sources using [`Extension`]
|
||||
/// and [`ExtensionSeek`].
|
||||
///
|
||||
/// [`Extension`]: #variant.Extension
|
||||
/// [`ExtensionSeek`]: #variant.ExtensionSeek
|
||||
/// [`Extension`]: Reader::Extension
|
||||
/// [`ExtensionSeek`]: Reader::ExtensionSeek
|
||||
pub enum Reader {
|
||||
/// Piped output of another program (i.e., [`ffmpeg`]).
|
||||
///
|
||||
/// Does not support seeking.
|
||||
///
|
||||
/// [`ffmpeg`]: ../fn.ffmpeg.html
|
||||
/// [`ffmpeg`]: super::ffmpeg
|
||||
Pipe(BufReader<ChildContainer>),
|
||||
/// A cached, raw in-memory store, provided by Songbird.
|
||||
///
|
||||
|
||||
@@ -37,9 +37,9 @@ type RecreateChannel = Receiver<Result<(Box<Input>, Recreator)>>;
|
||||
/// cannot be spared. Forward seeks will drain the track until reaching
|
||||
/// the desired timestamp.
|
||||
///
|
||||
/// [`Input`]: struct.Input.html
|
||||
/// [`Memory`]: cached/struct.Memory.html
|
||||
/// [`Compressed`]: cached/struct.Compressed.html
|
||||
/// [`Input`]: Input
|
||||
/// [`Memory`]: cached::Memory
|
||||
/// [`Compressed`]: cached::Compressed
|
||||
pub struct Restartable {
|
||||
async_handle: Option<Handle>,
|
||||
awaiting_source: Option<RecreateChannel>,
|
||||
@@ -89,7 +89,7 @@ impl Restartable {
|
||||
/// Trait used to create an instance of a [`Reader`] at instantiation and when
|
||||
/// a backwards seek is needed.
|
||||
///
|
||||
/// [`Reader`]: ../reader/enum.Reader.html
|
||||
/// [`Reader`]: reader::Reader
|
||||
#[async_trait]
|
||||
pub trait Restart {
|
||||
/// Tries to create a replacement source.
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
html_favicon_url = "https://raw.githubusercontent.com/serenity-rs/songbird/current/songbird-ico.png"
|
||||
)]
|
||||
#![deny(missing_docs)]
|
||||
#![deny(broken_intra_doc_links)]
|
||||
//! ![project logo][logo]
|
||||
//!
|
||||
//! Songbird is an async, cross-library compatible voice system for Discord, written in Rust.
|
||||
@@ -33,7 +34,7 @@
|
||||
//! [twilight]: https://github.com/twilight-rs/twilight
|
||||
//! [this crate's examples directory]: https://github.com/serenity-rs/songbird/tree/current/examples
|
||||
//! ["Black-Capped Chickadee"]: https://www.oldbookillustrations.com/illustrations/black-capped-chickadee/
|
||||
//! [`ConnectionInfo`]: struct.ConnectionInfo.html
|
||||
//! [`ConnectionInfo`]: struct@ConnectionInfo
|
||||
//! [lavalink]: https://github.com/Frederikam/Lavalink
|
||||
|
||||
pub mod constants;
|
||||
|
||||
@@ -41,7 +41,7 @@ struct ClientData {
|
||||
/// This manager transparently maps guild state and a source of shard information
|
||||
/// into individual calls, and forwards state updates which affect call state.
|
||||
///
|
||||
/// [`Call`]: struct.Call.html
|
||||
/// [`Call`]: Call
|
||||
#[derive(Debug)]
|
||||
pub struct Songbird {
|
||||
client_data: PRwLock<ClientData>,
|
||||
@@ -58,7 +58,7 @@ impl Songbird {
|
||||
///
|
||||
/// This must be [registered] after creation.
|
||||
///
|
||||
/// [registered]: serenity/fn.register_with.html
|
||||
/// [registered]: crate::serenity::register_with
|
||||
pub fn serenity() -> Arc<Self> {
|
||||
Arc::new(Self {
|
||||
client_data: Default::default(),
|
||||
@@ -77,7 +77,7 @@ impl Songbird {
|
||||
/// users are responsible for passing in any events using
|
||||
/// [`process`].
|
||||
///
|
||||
/// [`process`]: #method.process
|
||||
/// [`process`]: Songbird::process
|
||||
pub fn twilight<U>(cluster: Cluster, shard_count: u64, user_id: U) -> Arc<Self>
|
||||
where
|
||||
U: Into<UserId>,
|
||||
@@ -101,7 +101,7 @@ impl Songbird {
|
||||
/// If this struct is already initialised (e.g., from [`::twilight`]),
|
||||
/// or a previous call, then this function is a no-op.
|
||||
///
|
||||
/// [`::twilight`]: #method.twilight
|
||||
/// [`::twilight`]: Songbird::twilight
|
||||
pub fn initialise_client_data<U: Into<UserId>>(&self, shard_count: u64, user_id: U) {
|
||||
let mut client_data = self.client_data.write();
|
||||
|
||||
@@ -116,7 +116,7 @@ impl Songbird {
|
||||
|
||||
/// Retreives a [`Call`] for the given guild, if one already exists.
|
||||
///
|
||||
/// [`Call`]: struct.Call.html
|
||||
/// [`Call`]: Call
|
||||
pub fn get<G: Into<GuildId>>(&self, guild_id: G) -> Option<Arc<Mutex<Call>>> {
|
||||
let map_read = self.calls.read();
|
||||
map_read.get(&guild_id.into()).cloned()
|
||||
@@ -127,7 +127,7 @@ impl Songbird {
|
||||
///
|
||||
/// This will not join any calls, or cause connection state to change.
|
||||
///
|
||||
/// [`Call`]: struct.Call.html
|
||||
/// [`Call`]: Call
|
||||
pub fn get_or_insert(&self, guild_id: GuildId) -> Arc<Mutex<Call>> {
|
||||
self.get(guild_id).unwrap_or_else(|| {
|
||||
let mut map_read = self.calls.write();
|
||||
@@ -183,8 +183,8 @@ impl Songbird {
|
||||
/// If you _only_ need to retrieve the handler for a target, then use
|
||||
/// [`get`].
|
||||
///
|
||||
/// [`Call`]: struct.Call.html
|
||||
/// [`get`]: #method.get
|
||||
/// [`Call`]: Call
|
||||
/// [`get`]: Songbird::get
|
||||
#[inline]
|
||||
pub async fn join<C, G>(
|
||||
&self,
|
||||
@@ -220,7 +220,7 @@ impl Songbird {
|
||||
/// This method returns the handle and the connection info needed for other libraries
|
||||
/// or drivers, such as lavalink, and does not actually start or run a voice call.
|
||||
///
|
||||
/// [`Call`]: struct.Call.html
|
||||
/// [`Call`]: Call
|
||||
#[inline]
|
||||
pub async fn join_gateway<C, G>(
|
||||
&self,
|
||||
@@ -257,9 +257,9 @@ impl Songbird {
|
||||
/// This is a wrapper around [getting][`get`] a handler and calling
|
||||
/// [`leave`] on it.
|
||||
///
|
||||
/// [`Call`]: struct.Call.html
|
||||
/// [`get`]: #method.get
|
||||
/// [`leave`]: struct.Call.html#method.leave
|
||||
/// [`Call`]: Call
|
||||
/// [`get`]: Songbird::get
|
||||
/// [`leave`]: Call::leave
|
||||
#[inline]
|
||||
pub async fn leave<G: Into<GuildId>>(&self, guild_id: G) -> JoinResult<()> {
|
||||
self._leave(guild_id.into()).await
|
||||
@@ -282,7 +282,7 @@ impl Songbird {
|
||||
/// An Err(...) value implies that the gateway could not be contacted,
|
||||
/// and that leaving should be attempted again later (i.e., after reconnect).
|
||||
///
|
||||
/// [`Call`]: struct.Call.html
|
||||
/// [`Call`]: Call
|
||||
#[inline]
|
||||
pub async fn remove<G: Into<GuildId>>(&self, guild_id: G) -> JoinResult<()> {
|
||||
self._remove(guild_id.into()).await
|
||||
|
||||
@@ -13,7 +13,7 @@ use std::sync::Arc;
|
||||
/// Zero-size type used to retrieve the registered [`Songbird`] instance
|
||||
/// from serenity's inner TypeMap.
|
||||
///
|
||||
/// [`Songbird`]: ../struct.Songbird.html
|
||||
/// [`Songbird`]: Songbird
|
||||
pub struct SongbirdKey;
|
||||
|
||||
impl TypeMapKey for SongbirdKey {
|
||||
@@ -54,7 +54,7 @@ pub trait SerenityInit {
|
||||
/// Registers a new Songbird voice system with serenity, storing it for easy
|
||||
/// access via [`get`].
|
||||
///
|
||||
/// [`get`]: fn.get.html
|
||||
/// [`get`]: get
|
||||
fn register_songbird(self) -> Self;
|
||||
/// Registers a given Songbird voice system with serenity, as above.
|
||||
fn register_songbird_with(self, voice: Arc<Songbird>) -> Self;
|
||||
|
||||
@@ -6,8 +6,9 @@ use tokio::sync::oneshot::Sender as OneshotSender;
|
||||
/// A request from external code using a [`TrackHandle`] to modify
|
||||
/// or act upon an [`Track`] object.
|
||||
///
|
||||
/// [`Track`]: struct.Track.html
|
||||
/// [`TrackHandle`]: struct.TrackHandle.html
|
||||
/// [`Track`]: Track
|
||||
/// [`TrackHandle`]: TrackHandle
|
||||
#[non_exhaustive]
|
||||
pub enum TrackCommand {
|
||||
/// Set the track's play_mode to play/resume.
|
||||
Play,
|
||||
|
||||
@@ -15,7 +15,7 @@ use uuid::Uuid;
|
||||
/// the underlying [`Track`] object has been discarded. Those which aren't refer
|
||||
/// to immutable properties of the underlying stream.
|
||||
///
|
||||
/// [`Track`]: struct.Track.html
|
||||
/// [`Track`]: Track
|
||||
pub struct TrackHandle {
|
||||
command_channel: UnboundedSender<TrackCommand>,
|
||||
seekable: bool,
|
||||
@@ -26,7 +26,7 @@ impl TrackHandle {
|
||||
/// Creates a new handle, using the given command sink and hint as to whether
|
||||
/// the underlying [`Input`] supports seek operations.
|
||||
///
|
||||
/// [`Input`]: ../input/struct.Input.html
|
||||
/// [`Input`]: crate::input::Input
|
||||
pub fn new(command_channel: UnboundedSender<TrackCommand>, seekable: bool, uuid: Uuid) -> Self {
|
||||
Self {
|
||||
command_channel,
|
||||
@@ -50,7 +50,7 @@ impl TrackHandle {
|
||||
/// This is *final*, and will cause the audio context to fire
|
||||
/// a [`TrackEvent::End`] event.
|
||||
///
|
||||
/// [`TrackEvent::End`]: ../events/enum.TrackEvent.html#variant.End
|
||||
/// [`TrackEvent::End`]: crate::events::TrackEvent::End
|
||||
pub fn stop(&self) -> TrackResult {
|
||||
self.send(TrackCommand::Stop)
|
||||
}
|
||||
@@ -62,11 +62,11 @@ impl TrackHandle {
|
||||
|
||||
/// Denotes whether the underlying [`Input`] stream is compatible with arbitrary seeking.
|
||||
///
|
||||
/// If this returns `false`, all calls to [`seek`] will fail, and the track is
|
||||
/// If this returns `false`, all calls to [`seek_time`] will fail, and the track is
|
||||
/// incapable of looping.
|
||||
///
|
||||
/// [`seek`]: #method.seek
|
||||
/// [`Input`]: ../input/struct.Input.html
|
||||
/// [`seek_time`]: TrackHandle::seek_time
|
||||
/// [`Input`]: crate::input::Input
|
||||
pub fn is_seekable(&self) -> bool {
|
||||
self.seekable
|
||||
}
|
||||
@@ -76,7 +76,7 @@ impl TrackHandle {
|
||||
/// If the underlying [`Input`] does not support this behaviour,
|
||||
/// then all calls will fail.
|
||||
///
|
||||
/// [`Input`]: ../input/struct.Input.html
|
||||
/// [`Input`]: crate::input::Input
|
||||
pub fn seek_time(&self, position: Duration) -> TrackResult {
|
||||
if self.seekable {
|
||||
self.send(TrackCommand::Seek(position))
|
||||
@@ -91,8 +91,8 @@ impl TrackHandle {
|
||||
/// within the supplied function or closure. *Taking excess time could prevent
|
||||
/// timely sending of packets, causing audio glitches and delays*.
|
||||
///
|
||||
/// [`Track`]: struct.Track.html
|
||||
/// [`EventContext::Track`]: ../events/enum.EventContext.html#variant.Track
|
||||
/// [`Track`]: Track
|
||||
/// [`EventContext::Track`]: crate::events::EventContext::Track
|
||||
pub fn add_event<F: EventHandler + 'static>(&self, event: Event, action: F) -> TrackResult {
|
||||
let cmd = TrackCommand::AddEvent(EventData::new(event, action));
|
||||
if event.is_global_only() {
|
||||
@@ -108,7 +108,7 @@ impl TrackHandle {
|
||||
/// within the supplied function or closure. *Taking excess time could prevent
|
||||
/// timely sending of packets, causing audio glitches and delays*.
|
||||
///
|
||||
/// [`Track`]: struct.Track.html
|
||||
/// [`Track`]: Track
|
||||
pub fn action<F>(&self, action: F) -> TrackResult
|
||||
where
|
||||
F: FnOnce(&mut Track) + Send + Sync + 'static,
|
||||
@@ -160,7 +160,7 @@ impl TrackHandle {
|
||||
#[inline]
|
||||
/// Send a raw command to the [`Track`] object.
|
||||
///
|
||||
/// [`Track`]: struct.Track.html
|
||||
/// [`Track`]: Track
|
||||
pub fn send(&self, cmd: TrackCommand) -> TrackResult {
|
||||
self.command_channel.send(cmd)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
/// Looping behaviour for a [`Track`].
|
||||
///
|
||||
/// [`Track`]: struct.Track.html
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum LoopState {
|
||||
/// Track will loop endlessly until loop state is changed or
|
||||
/// manually stopped.
|
||||
@@ -11,7 +11,7 @@ pub enum LoopState {
|
||||
///
|
||||
/// `Finite(0)` is the `Default`, stopping the track once its [`Input`] ends.
|
||||
///
|
||||
/// [`Input`]: ../input/struct.Input.html
|
||||
/// [`Input`]: crate::input::Input
|
||||
Finite(usize),
|
||||
}
|
||||
|
||||
|
||||
@@ -361,8 +361,8 @@ impl Track {
|
||||
/// Typically, this would be used if you wished to directly work on or configure
|
||||
/// the [`Track`] object before it is passed over to the driver.
|
||||
///
|
||||
/// [`Track`]: struct.Track.html
|
||||
/// [`TrackHandle`]: struct.TrackHandle.html
|
||||
/// [`Track`]: Track
|
||||
/// [`TrackHandle`]: TrackHandle
|
||||
pub fn create_player(source: Input) -> (Track, TrackHandle) {
|
||||
let (tx, rx) = mpsc::unbounded_channel();
|
||||
let can_seek = source.is_seekable();
|
||||
@@ -378,7 +378,7 @@ pub fn create_player(source: Input) -> (Track, TrackHandle) {
|
||||
/// Failure indicates that the accessed audio object has been
|
||||
/// removed or deleted by the audio context.
|
||||
///
|
||||
/// [`TrackHandle`]: struct.TrackHandle.html
|
||||
/// [`TrackHandle`]: TrackHandle
|
||||
pub type TrackResult = Result<(), SendError<TrackCommand>>;
|
||||
|
||||
/// Alias for return value from calls to [`TrackHandle::get_info`].
|
||||
@@ -389,5 +389,5 @@ pub type TrackResult = Result<(), SendError<TrackCommand>>;
|
||||
/// Failure indicates that the accessed audio object has been
|
||||
/// removed or deleted by the audio context.
|
||||
///
|
||||
/// [`TrackHandle::get_info`]: struct.TrackHandle.html#method.get_info
|
||||
/// [`TrackHandle::get_info`]: TrackHandle::get_info
|
||||
pub type TrackQueryResult = Result<OneshotReceiver<Box<TrackState>>, SendError<TrackCommand>>;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
/// Playback status of a track.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
#[non_exhaustive]
|
||||
pub enum PlayMode {
|
||||
/// The track is currently playing.
|
||||
Play,
|
||||
|
||||
@@ -53,8 +53,8 @@ use tracing::{info, warn};
|
||||
/// # };
|
||||
/// ```
|
||||
///
|
||||
/// [`TrackEvent`]: ../events/enum.TrackEvent.html
|
||||
/// [`Driver::queue`]: ../driver/struct.Driver.html#method.queue
|
||||
/// [`TrackEvent`]: crate::events::TrackEvent
|
||||
/// [`Driver::queue`]: crate::driver::Driver::queue
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct TrackQueue {
|
||||
// NOTE: the choice of a parking lot mutex is quite deliberate
|
||||
@@ -88,7 +88,7 @@ impl Queued {
|
||||
/// This abstracts away thread-safety from the user,
|
||||
/// and offers a convenient location to store further state if required.
|
||||
///
|
||||
/// [`TrackQueue`]: struct.TrackQueue.html
|
||||
/// [`TrackQueue`]: TrackQueue
|
||||
struct TrackQueueCore {
|
||||
tracks: VecDeque<Queued>,
|
||||
}
|
||||
@@ -163,11 +163,11 @@ impl TrackQueue {
|
||||
|
||||
/// Adds a [`Track`] object to the queue, to be played in the channel managed by `handler`.
|
||||
///
|
||||
/// This is used with [`voice::create_player`] if additional configuration or event handlers
|
||||
/// This is used with [`create_player`] if additional configuration or event handlers
|
||||
/// are required before enqueueing the audio track.
|
||||
///
|
||||
/// [`Track`]: struct.Track.html
|
||||
/// [`voice::create_player`]: fn.create_player.html
|
||||
/// [`Track`]: Track
|
||||
/// [`create_player`]: super::create_player
|
||||
pub fn add(&self, mut track: Track, handler: &mut Driver) {
|
||||
self.add_raw(&mut track);
|
||||
handler.play(track);
|
||||
@@ -208,7 +208,7 @@ impl TrackQueue {
|
||||
///
|
||||
/// The returned entry can be readded to *this* queue via [`modify_queue`].
|
||||
///
|
||||
/// [`modify_queue`]: #method.modify_queue
|
||||
/// [`modify_queue`]: TrackQueue::modify_queue
|
||||
pub fn dequeue(&self, index: usize) -> Option<Queued> {
|
||||
self.modify_queue(|vq| vq.remove(index))
|
||||
}
|
||||
@@ -285,7 +285,7 @@ impl TrackQueue {
|
||||
///
|
||||
/// Use [`modify_queue`] for direct modification of the queue.
|
||||
///
|
||||
/// [`modify_queue`]: #method.modify_queue
|
||||
/// [`modify_queue`]: TrackQueue::modify_queue
|
||||
pub fn current_queue(&self) -> Vec<TrackHandle> {
|
||||
let inner = self.inner.lock();
|
||||
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
use super::*;
|
||||
|
||||
/// State of an [`Track`] object, designed to be passed to event handlers
|
||||
/// and retrieved remotely via [`TrackHandle::get_info`] or
|
||||
/// [`TrackHandle::get_info_blocking`].
|
||||
/// and retrieved remotely via [`TrackHandle::get_info`].
|
||||
///
|
||||
/// [`Track`]: struct.Track.html
|
||||
/// [`TrackHandle::get_info`]: struct.TrackHandle.html#method.get_info
|
||||
/// [`TrackHandle::get_info_blocking`]: struct.TrackHandle.html#method.get_info_blocking
|
||||
/// [`Track`]: Track
|
||||
/// [`TrackHandle::get_info`]: TrackHandle::get_info
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq)]
|
||||
pub struct TrackState {
|
||||
/// Play status (e.g., active, paused, stopped) of this track.
|
||||
@@ -15,7 +13,8 @@ pub struct TrackState {
|
||||
pub volume: f32,
|
||||
/// Current playback position in the source.
|
||||
///
|
||||
/// This is altered by loops and seeks
|
||||
/// This is altered by loops and seeks, and represents this track's
|
||||
/// position in its underlying input stream.
|
||||
pub position: Duration,
|
||||
/// Total playback time, increasing monotonically.
|
||||
pub play_time: Duration,
|
||||
|
||||
Reference in New Issue
Block a user