首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【Rust GUI开发入门】编写一个本地音乐播放器(2. Rodio播放库的使用)

【Rust GUI开发入门】编写一个本地音乐播放器(2. Rodio播放库的使用)

原创
作者头像
用户11855011
发布2025-09-27 23:41:52
发布2025-09-27 23:41:52
250
举报

本系列教程对应的代码已开源在 Github zeedle

添加依赖

在Cargo.toml添加:

代码语言:toml
复制
[dependencies]
rodio = "0.21.1"

添加/播放/暂停音频

代码语言:rust
复制
use std::{thread, time::Duration};

use rodio::Decoder;
fn main() {
    // create an output stream
    let stream_handle = rodio::OutputStreamBuilder::from_default_device()
        .expect("no output device available")
        .open_stream()
        .expect("failed to open output stream");
    // create a sink to play audio
    let sink = rodio::Sink::connect_new(&stream_handle.mixer());
    // open an audio file
    let file = std::fs::File::open("audios/爱情转移.flac").expect("failed to open audio file");
    // decode the audio file
    let source = Decoder::try_from(file).expect("failed to decode audio file");
    // append the audio source to the sink & auto play
    sink.append(source);
    // sleep for a while to let the audio play
    thread::sleep(Duration::from_secs(20));
    // pause the audio playback explicitly
    sink.pause();
    // sleep for a while
    thread::sleep(Duration::from_secs(20));
    // resume the audio playback explicitly
    sink.play();
    // keep the main thread alive while the audio is playing
    thread::sleep(Duration::from_secs(20));
}

代码及主要API解读

  • stream_handle 是音频流句柄,直接跟硬件相关
  • rodio::Sink::connect_new 连接到音频流,返回一个Sink对象,是输出到stream_handle对应device的“音频管理器”
  • Decoder::try_from(file) 尝试解码音频文件
  • sink.append 向音频管理器中添加source并立刻自动启动播放
  • sink.pause 显式停止音频播放
  • sink.play 显式恢复音频播放
  • sink.clear 清除sink中存储的所有source,释放资源(这里并未用到)

注意

执行上述代码,会:

  1. 播放20秒音频
  2. 停止20秒
  3. 再播放20秒音频
  4. 程序退出

如果sink.append之后没有thread::sleep,程序会立刻结束,任何声音都不会被播放,这是因为,根据Rust变量的生命周期,stream_handle变量会在main函数右括号}处立刻释放,由于stream_handle管理了计算机音频输出设备硬件资源,当它超出生命周期被释放时,与之关联的任何音频播放(也就是sink中存在的所有source)都会被强制停止,这是Rodio库为了保护硬件资源做出的一个设计,大大减小了硬件不可控事件的出现。

还有一些额外的事情需要注意:

  • stream_handle直接持有了硬件资源,因此它不是线程安全的,无法在线程之间安全传递
  • sink借助stream_handle操控音频播放,因此stream_handle的生命周期一定长于sink
  • sink是线程安全的,可以在线程之间安全传递,后面制作音乐播放器时会大量用到这个特性,它能同时存在于UI线程与后台线程中,只要确保stream_handle的生命周期长于sink

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 添加依赖
  • 添加/播放/暂停音频
  • 代码及主要API解读
  • 注意
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档