我如何使用 Rodio crate 制作 Rust,在 Vec 中加载多个源,这样我可以稍后根据需要播放它们,而不必每次都加载它们?

问题描述 投票:0回答:0

我将 Rust 与 Rodio crate 一起使用,我想制作一个

Vec
的加载源以在需要时使用,这样程序就不需要每次都加载它。我做了一个
SoundHandler
类,其中包含一个
OutputStream
、一个
OutputStreamHandle
和一个
Vec<Decoder<BufReader<File>>>
。前两个是使用
OutputStream::try_default()
实例化的,它在一个元组中返回两者。
Vec
是加载源的向量。据我了解,它的内容是在以下
SoundHandler
方法中加载然后推送的:

pub fn load_source(&mut self, file_path: PathBuf) -> SoundId {
    let id = self.sources.len();
        
    self.sources.push(
        Decoder::new(
            BufReader::new(
                File::open(file_path).expect("file not found")
            )
        ).expect("could not load source")
    );

    SoundId(id)
}

接下来,应该通过调用

play_sound()
方法来播放源。

之前是直接加载播放声音:

pub fn play_sound(file_path: PathBuf) {
    self.stream_handle.play_raw(
        Decoder::new(
            BufReader::new(
                File::open(file_path).expect("file not found")
            )
        ).expect("could not load source")
    );
}

但现在它必须处理来自

Vec
的资源。我在尝试这样做时遇到了麻烦。我需要帮助。我对这门语言还很陌生,所以知道如何以不止一种方式解决这个问题会更好,但我的首要任务是我选择的路径,因为知道如何解决这个问题无疑会增加我的 Rust解决问题的能力。请记住,我在这里的主要目标是学习语言,下面的片段根本不是公司需要解决的紧迫问题。

好的,所以我尝试了最直接的方法。我直接改变了旧方法来做同样的事情但是用

Vec

pub fn play_sound(&self, sound_id: SoundId) {
    self.stream_handle
        .play_raw(self.sources.get(sound_id.0).unwrap().convert_samples()).unwrap();
}

但是编译器不会编译那个方法,因为,根据它,

error[E0507]: cannot move out of a shared reference
        self.stream_handle.play_raw(self.sources.get(sound_id.0).unwrap().convert_samples()).unwrap();
                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------
                                    |                                     |
                                    |                                     value moved due to this method call
                                     move occurs because value has type `rodio::Decoder<std::io::BufReader<std::fs::File>>`, which does not implement the `Copy` trait
note: this function takes ownership of the receiver `self`, which moves value

我明白编译器在说什么。这当然不可能。

convert_samples()
试图使
Vec
中的值无效,因此它可能使 Vec 不安全。所以我天真地尝试克隆
Decoder
,但是结构没有实现
Clone
特性,而且显然没有任何方法可以这样做。最后,我通过
Vec::remove()
方法找到了获取价值并拥有它的方法,但我不想删除它,我希望它是错误的。

所以我的问题是:在这种情况下,我怎样才能制作

Vec
的加载源?也许我什至可以用
SamplesConverter
制作一个 Vec。但是随后类型的名称变得很大,所以这可能不是预期的方式:
Vec<SamplesConverter<Decoder<BufReader<File>>, f32>>
。但它与其他实现有同样的问题。

audio rust borrow-checker vec rodio
© www.soinside.com 2019 - 2024. All rights reserved.