bevy/examples/audio/audio_control.rs
François b21c69c60e Audio control - play, pause, volume, speed, loop (#3948)
# Objective

- Add ways to control how audio is played

## Solution

- playing a sound will return a (weak) handle to an asset that can be used to control playback
- if the asset is dropped, it will detach the sink (same behaviour as now)
2022-03-01 01:12:11 +00:00

65 lines
1.8 KiB
Rust

use bevy::{audio::AudioSink, prelude::*};
/// This example illustrates how to load and play an audio file, and control how it's played
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_startup_system(setup)
.add_system(update_speed)
.add_system(pause)
.add_system(volume)
.run();
}
fn setup(
mut commands: Commands,
asset_server: Res<AssetServer>,
audio: Res<Audio>,
audio_sinks: Res<Assets<AudioSink>>,
) {
let music = asset_server.load("sounds/Windless Slopes.ogg");
let handle = audio_sinks.get_handle(audio.play(music));
commands.insert_resource(MusicController(handle));
}
struct MusicController(Handle<AudioSink>);
fn update_speed(
audio_sinks: Res<Assets<AudioSink>>,
music_controller: Res<MusicController>,
time: Res<Time>,
) {
if let Some(sink) = audio_sinks.get(&music_controller.0) {
sink.set_speed(((time.seconds_since_startup() / 5.0).sin() as f32 + 1.0).max(0.1));
}
}
fn pause(
keyboard_input: Res<Input<KeyCode>>,
audio_sinks: Res<Assets<AudioSink>>,
music_controller: Res<MusicController>,
) {
if keyboard_input.just_pressed(KeyCode::Space) {
if let Some(sink) = audio_sinks.get(&music_controller.0) {
if sink.is_paused() {
sink.play()
} else {
sink.pause()
}
}
}
}
fn volume(
keyboard_input: Res<Input<KeyCode>>,
audio_sinks: Res<Assets<AudioSink>>,
music_controller: Res<MusicController>,
) {
if let Some(sink) = audio_sinks.get(&music_controller.0) {
if keyboard_input.just_pressed(KeyCode::Plus) {
sink.set_volume(sink.volume() + 0.1);
} else if keyboard_input.just_pressed(KeyCode::Minus) {
sink.set_volume(sink.volume() - 0.1);
}
}
}