Audio sink seek adopted (#18971)
Adopted #13869 # Objective Fixes #9076 ## Solution Using `rodio`'s `try_seek` ## Testing @ivanstepanovftw added a `seek` system using `AudioSink` to the `audio_control.rs` example. I got it working with .mp3 files, but rodio doesn't support seeking for .ogg and .flac files, so I removed it from the commit (since the assets folder only has .ogg files). Another thing to note is that `try_seek` fails when using `PlaybackMode::Loop`, as `rodio::source::buffered::Buffered` doesn't support `try_seek`. I haven't tested `SpatialAudioSink`. ## Notes I copied the docs for `try_seek` verbatim from `rodio`, and re-exported `rodio::source::SeekError`. I'm not completely confident in those decisions, please let me know if I'm doing anything wrong. </details> --------- Co-authored-by: Ivan Stepanov <ivanstepanovftw@gmail.com> Co-authored-by: François Mockers <francois.mockers@vleue.com> Co-authored-by: Jan Hohenheim <jan@hohenheim.ch> Co-authored-by: François Mockers <mockersf@gmail.com>
This commit is contained in:
parent
cd67bac544
commit
2affecdb07
@ -1,10 +1,11 @@
|
||||
use crate::Volume;
|
||||
use bevy_ecs::component::Component;
|
||||
use bevy_math::Vec3;
|
||||
use bevy_transform::prelude::Transform;
|
||||
use core::time::Duration;
|
||||
pub use rodio::source::SeekError;
|
||||
use rodio::{Sink, SpatialSink};
|
||||
|
||||
use crate::Volume;
|
||||
|
||||
/// Common interactions with an audio sink.
|
||||
pub trait AudioSinkPlayback {
|
||||
/// Gets the volume of the sound as a [`Volume`].
|
||||
@ -41,6 +42,26 @@ pub trait AudioSinkPlayback {
|
||||
/// No effect if not paused.
|
||||
fn play(&self);
|
||||
|
||||
/// Attempts to seek to a given position in the current source.
|
||||
///
|
||||
/// This blocks between 0 and ~5 milliseconds.
|
||||
///
|
||||
/// As long as the duration of the source is known, seek is guaranteed to saturate
|
||||
/// at the end of the source. For example given a source that reports a total duration
|
||||
/// of 42 seconds calling `try_seek()` with 60 seconds as argument will seek to
|
||||
/// 42 seconds.
|
||||
///
|
||||
/// # Errors
|
||||
/// This function will return [`SeekError::NotSupported`] if one of the underlying
|
||||
/// sources does not support seeking.
|
||||
///
|
||||
/// It will return an error if an implementation ran
|
||||
/// into one during the seek.
|
||||
///
|
||||
/// When seeking beyond the end of a source, this
|
||||
/// function might return an error if the duration of the source is not known.
|
||||
fn try_seek(&self, pos: Duration) -> Result<(), SeekError>;
|
||||
|
||||
/// Pauses playback of this sink.
|
||||
///
|
||||
/// No effect if already paused.
|
||||
@ -160,6 +181,10 @@ impl AudioSinkPlayback for AudioSink {
|
||||
self.sink.play();
|
||||
}
|
||||
|
||||
fn try_seek(&self, pos: Duration) -> Result<(), SeekError> {
|
||||
self.sink.try_seek(pos)
|
||||
}
|
||||
|
||||
fn pause(&self) {
|
||||
self.sink.pause();
|
||||
}
|
||||
@ -256,6 +281,10 @@ impl AudioSinkPlayback for SpatialAudioSink {
|
||||
self.sink.play();
|
||||
}
|
||||
|
||||
fn try_seek(&self, pos: Duration) -> Result<(), SeekError> {
|
||||
self.sink.try_seek(pos)
|
||||
}
|
||||
|
||||
fn pause(&self) {
|
||||
self.sink.pause();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user