Rust开发终端音乐播放器

631 阅读1分钟

最终效果图

1.png

2.png

主要技术栈

命令行

第三方库: clap

实现效果:

# 查看帮助
rust-player -h
# 打开D盘下的mp3文件夹,并且将所有周杰伦开头的文件添加到播放列表,并且全屏展示
rust-player D://mp3 周杰伦-* -f

部分代码:

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
    path: Option<PathBuf>,

    name: Option<String>,

    #[arg(short, long)]
    full: bool,

    #[arg(short, long)]
    info: bool,
}

终端UI

第三方库: ratatui,前身是rust中大名鼎鼎的 tui-rs, 不过由于原作者的工作繁忙问题无暇维护, 因此诞生了这个社区版的, 积极维护的fork。而且官方文档很友好,推荐

部分代码:

loop {
    // 初始化脚本
    self.script.init();
    // 绘制UI
    self.draw(terminal)?;
    // 处理事件
    if crossterm::event::poll(Config::REFRESH_RATE)? {
        if let Event::Key(key) = event::read()? {
            match key.code {
                // 关闭应用
                KeyCode::Char('q') | KeyCode::Char('Q') => break,
                // ......
            }
        }
    }
}

音频播放

第三方库: rodio、id3、mp3-duration

  • rodio: 音频播放库
  • id3: 解析mp3等媒体文件自带的id3 tag信息。tag中包含了媒体文件的基本信息和歌词等
  • mp3-duration: rodio支持获取媒体的播放时长,但是不支持获取mp3的,因此用此代替

部分代码:

// 尝试从媒体文件的tag中读取歌词
// 如果失败,则尝试从媒体文件所在目录查找与媒体文件同名的.lrc歌词文件
let tag = Tag::read_from_path(&path).ok();
let lyrics = if let Some(tag) = &tag {
    let mut string = String::default();
    for it in tag.lyrics() {
        string = string + &it.text;
    }
    if string.len() > 0 {
        Lyrics::from_string(string)
    } else {
        Lyrics::from_music_path(&path)
    }
} else {
    Lyrics::from_music_path(&path)
};

代码地址

github.com/forward-ste…