英文:
Why do Rodio's Sink types fail to play when used inside of a struct?
问题
I've translated the code portion as you requested. Here's the translated code:
use rodio::{OutputStream, Sink, Decoder};
use std::fs::File;
use std::io::{BufReader};
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 because of how 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()
}
}
}
Please note that I've removed the HTML escape codes (&
and "
) as they are not necessary in Rust code. If you have any further questions or need assistance with this code, feel free to ask.
英文:
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 !
答案1
得分: 2
需要让 OutputStream
的生命周期与 sink 一样长。简单的修复方法是将其添加到结构体中:
pub struct MusicStruct {
sink: Sink,
stream: OutputStream
}
并且修改 new
函数以包括它:
pub fn new() -> MusicStruct {
let (stream, stream_handle) = OutputStream::try_default().unwrap();
MusicStruct {
sink: Sink::try_new(&stream_handle).unwrap(),
stream
}
编辑:
更好的方法是这样做(并且更容易与线程一起使用):
let (stream, stream_handle) = OutputStream::try_default().unwrap();
std::mem::forget(stream);
这在 bevy 游戏引擎中官方使用。只要您不构建多个这样的结构就可以。
英文:
Need to have the OutputStream
live for as long as the sink. Simple fix was adding it to the struct:
pub struct MusicStruct {
sink: Sink,
stream: OutputStream
}
and changing the new
function to include it:
pub fn new() -> MusicStruct {
let (stream, stream_handle) = OutputStream::try_default().unwrap();
MusicStruct {
sink: Sink::try_new(&stream_handle).unwrap(),
stream
}
Edit:
The much better way to do this (and to have this work easier with threading) is to use
let (stream, stream_handle) = OutputStream::try_default().unwrap();
std::mem::forget(stream);
Which is used officially in the bevy game engine.
This is fine so long as you are not constructing multiple of these
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论