diff --git a/crates/bevy_audio/src/sinks.rs b/crates/bevy_audio/src/sinks.rs index 68fa1e99c4543..a23e2c3ec6afe 100644 --- a/crates/bevy_audio/src/sinks.rs +++ b/crates/bevy_audio/src/sinks.rs @@ -1,7 +1,9 @@ +use std::time::Duration; use bevy_ecs::component::Component; use bevy_math::Vec3; use bevy_transform::prelude::Transform; use rodio::{Sink, SpatialSink}; +use rodio::source::SeekError; /// Common interactions with an audio sink. pub trait AudioSinkPlayback { @@ -71,6 +73,9 @@ pub trait AudioSinkPlayback { /// Returns true if this sink has no more sounds to play. fn empty(&self) -> bool; + + /// Seeks to a specific position in the audio. + fn try_seek(&self, pos: Duration) -> Result<(), SeekError>; } /// Used to control audio during playback. @@ -124,6 +129,10 @@ impl AudioSinkPlayback for AudioSink { fn empty(&self) -> bool { self.sink.empty() } + + fn try_seek(&self, pos: Duration) -> Result<(), SeekError> { + self.sink.try_seek(pos) + } } /// Used to control spatial audio during playback. @@ -177,6 +186,10 @@ impl AudioSinkPlayback for SpatialAudioSink { fn empty(&self) -> bool { self.sink.empty() } + + fn try_seek(&self, pos: Duration) -> Result<(), SeekError> { + self.sink.try_seek(pos) + } } impl SpatialAudioSink { diff --git a/examples/audio/audio_control.rs b/examples/audio/audio_control.rs index 9e882cc012a2e..af42cd00cf7ca 100644 --- a/examples/audio/audio_control.rs +++ b/examples/audio/audio_control.rs @@ -6,7 +6,7 @@ fn main() { App::new() .add_plugins(DefaultPlugins) .add_systems(Startup, setup) - .add_systems(Update, (update_speed, pause, volume)) + .add_systems(Update, (update_speed, pause, volume, seek)) .run(); } @@ -52,3 +52,14 @@ fn volume( } } } + +fn seek( + keyboard_input: Res>, + music_controller: Query<&AudioSink, With>, +) { + if let Ok(sink) = music_controller.get_single() { + if keyboard_input.just_pressed(KeyCode::Digit0) { + sink.try_seek(std::time::Duration::from_secs_f64(0.0)).unwrap(); + } + } +}