You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中rodio Sink在函数作用域变化时停止播放的问题

Rust rodio Sink 无声音问题排查与解决

你遇到的核心问题是rodio的音频播放是异步后台执行的。当new函数返回后,如果主线程没有等待播放完成就直接退出,整个进程会终止,负责音频播放的后台线程也会被强制停止,自然听不到声音。而添加sleep时,主线程处于阻塞状态,后台线程有足够时间完成播放,所以能听到声音。

虽然你在Player结构体中保留了OutputStream、OutputStreamHandle和Sink,避免了对象提前销毁的问题,但这只能保证资源不被提前释放,无法阻止主线程退出导致整个进程结束。


解决方案

方案一:给Player添加等待播放完成的方法

在Player结构体中封装等待逻辑,在合适的时机调用,让主线程等待音频播放结束:

use rodio::{OutputStream, OutputStreamHandle, Sink, Source, SineWave};
use std::time::Duration;

pub struct Player {
    streamhandle: (OutputStream, OutputStreamHandle),
    sink: Sink,
    // playback: PlayBack, // 根据你的实际类型初始化
}

impl Player {
    pub fn new() -> Player {
        let (stream, stream_handle) = OutputStream::try_default().unwrap();

        let sink = Sink::try_new(&stream_handle).unwrap();
        let source = SineWave::new(200.0)
            .take_duration(Duration::from_secs_f32(2.0))
            .amplify(0.10);
        sink.append(source);

        Player {
            sink,
            streamhandle: (stream, stream_handle),
            // playback: PlayBack::new(),
        }
    }

    // 阻塞当前线程,直到所有音频播放完成
    pub fn wait_until_end(&self) {
        self.sink.sleep_until_end();
    }
}

// 调用示例
fn main() {
    let player = Player::new();
    player.wait_until_end(); // 主线程等待音频播放完毕再退出
}

方案二:在new函数中直接等待播放完成(按需选择)

如果你的场景是创建Player后立即播放并等待结束,可以在new函数内部阻塞,直到播放完成再返回Player:

pub fn new() -> Player {
    let (stream, stream_handle) = OutputStream::try_default().unwrap();

    let sink = Sink::try_new(&stream_handle).unwrap();
    let source = SineWave::new(200.0)
        .take_duration(Duration::from_secs_f32(2.0))
        .amplify(0.10);
    sink.append(source);
    
    // 等待播放完成后再返回Player
    sink.sleep_until_end();

    Player {
        sink,
        streamhandle: (stream, stream_handle),
        // playback: PlayBack::new(),
    }
}

说明

  • sink.sleep_until_end()会阻塞当前线程,直到Sink中的所有音频源播放完毕。
  • 如果你的播放器需要支持暂停、切换曲目等动态操作,优先选择方案一,在需要等待的时机调用wait_until_end,避免阻塞Player的初始化流程。

内容的提问来源于stack exchange,提问作者KfK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 16:35:24