Crate playback_rs

source ·
Expand description

playback-rs is a very, very simple library to handle playing audio files using symphonia and cpal, as well as rubato for sample rate conversion.

How to use

To decode a song you can call Song::new() or Song::from_file() to get a Song, which contains the uncompressed audio data stored in an Arc for lightweight cloning.

To play a song you can create a Player, which will allow you to play Songs, as well as queueing a second songs to allow true gapless playback. Once you have created the player you can play a song using Player::play_song_next, but be sure to call Player::has_next_song or else you will overwrite that song in the queue.

After calling either method with a song that song may be discarded as the player retains an internal copy of the song data.

The Player’s state

The Player struct contains an actively playing song as well as a single queued song that allows gapless playback. Additionally, the player only ever loads songs into the queued song slot, never the actively playing song (though it can be cleared). Because of this, you’ll always want to call Player::has_next_song before calling Player::play_song_next, to make sure you aren’t overwriting another song you already queued.

The player also maintains a pause state, however this state is persistent outside any playing song, so calling Player::set_playing is the only way to modify this state. While paused, the Player struct will output silence regardless of whether there is a song in the queue or not.

Example

This example plays two songs and showcases quite a few of the utility functions provided by the Player struct.

use playback_rs::{Player, Song};

fn main() {
    let player = Player::new(None).expect("Failed to open an audio output."); // Create a player to play audio with cpal.
    let song = Song::from_file("song.mp3", None).expect("Failed to load or decode the song."); // Decode a song from a file
    player.play_song_next(&song, Some(std::time::Duration::from_secs(30))).expect("Failed to play the song starting at 0:30");
    let song2 = Song::from_file("song2.flac", None).expect("Failed to load or decode the other song.");
    player.play_song_next(&song, None).expect("Failed to play the other song");

    std::thread::sleep(std::time::Duration::from_secs(5));
    // Query playback position
    println!("Playback position: {:?}", player.get_playback_position());

    // Pause the song for a second
    player.set_playing(false);
    std::thread::sleep(std::time::Duration::from_secs(1));
    player.set_playing(true);
    std::thread::sleep(std::time::Duration::from_secs(5));
    // Seek forward to 30 seconds
    player.seek(std::time::Duration::from_secs(30));
    std::thread::sleep(std::time::Duration::from_secs(10));
    // Skip to the second song
    player.skip();

    // Wait until the song has ended to exit
    while player.has_current_song() {
        std::thread::sleep(std::time::Duration::from_secs(1));
    }
    // Playback will automatically stop when the Player is dropped
}

Structs

  • A Hint provides additional information and context when probing a media source stream.
  • Manages playback of Songs through cpal and sample conversion through rubato.
  • Represents a single song that has been decoded into memory, can be played in a struct.