Been trying to create a struct to do some music operations and I found that if you have a struct with a rodio::sink as a field, it will not play music.
Here is my code:
use rodio::{OutputStream, Source, Sink, Decoder};
use std::fs::File;
use std::io::{BufReader, Seek, SeekFrom};
pub struct MusicStruct {
sink: Sink
}
fn main() {
// this will not play (using my struct type)
let mut music = MusicStruct::new();
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
let my_sink = Sink::try_new(&stream_handle).unwrap();
// will sit here and hang forever (i guess bcs of how the sleep_until_end() is written..)
MusicStruct::test_play(music);
// this does play (doing it how the docs suggest)
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
let sink = Sink::try_new(&stream_handle).unwrap();
sink.append(read_file_from_beginning("my_mp3.mp3".to_string()));
sink.play();
sink.sleep_until_end()
}
// makes a Decoder<BufReader<File>> from String
fn read_file_from_beginning(file: String) -> Decoder<BufReader<File>> {
let reader = BufReader::new(File::open(file).unwrap());
let decoder = Decoder::new(reader).unwrap();
decoder
}
impl MusicStruct {
// creates a Decoder<BufReader<File>> and appends it to the sink in our struct and plays it
pub fn test_play(our_sink: MusicStruct) {
let file = read_file_from_beginning("my_mp3.mp3".to_string());
our_sink.sink.append(file);
our_sink.sink.play();
our_sink.sink.sleep_until_end()
}
pub fn new() -> MusicStruct {
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
MusicStruct {
sink: Sink::try_new(&stream_handle).unwrap()
}
}
}
I didn't see anything mention this in the docs / other resources. Am I doing something wrong here? I looked into the source code but didn't really see much in sink that would cause this behavior (albeit I'm not great at rust, so..)
Would appreciate any thoughts or answers !
Need to have the
OutputStreamlive for as long as the sink. Simple fix was adding it to the struct:and changing the
newfunction to include it:Edit: The much better way to do this (and to have this work easier with threading) is to use
Which is used officially in the bevy game engine.
This is fine so long as you are not constructing multiple of these