如何在Rust中获取MP3、MP4、WAV等音频文件的时长?
获取音频文件时长的方法(Rust环境)
时长获取的两种路径
- 部分主流音频格式(如MP3、FLAC、AAC)的元数据中会直接存储时长信息,这种情况无需编解码器,直接读取元数据就能快速拿到时长。
- 若元数据缺失,或是WAV这类仅存储采样数、不直接写时长的格式,就需要借助编解码器解析音频流,通过「总采样数 ÷ 采样率」的公式计算时长。
你试过的工具为啥不好用?
file::metadata只能读取文件的系统属性(比如大小、修改时间),完全不涉及音频内容的专属元数据,所以肯定拿不到时长。rodio是偏向音频播放的库,虽然具备解码能力,但它的API设计聚焦播放控制,获取时长需要手动处理流逻辑,用起来非常繁琐。
推荐的Rust工具
1. lofty(优先选择,专注元数据读取)
专门处理音频元数据的轻量库,支持几乎所有主流格式,能快速提取元数据中的时长,代码简洁:
use lofty::{read_from_path, AudioFile}; fn main() -> lofty::Result<()> { let file = read_from_path("your_audio_file.mp3")?; let properties = file.properties(); println!("时长:{}秒", properties.duration().as_secs()); Ok(()) }
如果目标文件元数据缺失,它还能自动切换到解码计算模式(需启用对应特性)。
2. symphonia(全能型,适配复杂场景)
功能强大的音频解码框架,支持绝大多数音频格式,既能读取元数据,也能解码流计算时长,适合元数据缺失的情况:
use symphonia::default::get_probe; use symphonia::core::io::MediaSourceStream; use std::fs::File; use std::path::Path; fn main() -> Result<(), Box<dyn std::error::Error>> { let path = Path::new("your_audio_file.wav"); let file = File::open(path)?; let mss = MediaSourceStream::new(Box::new(file), Default::default()); let probe = get_probe().format(&mss, &Default::default(), &Default::default())?; let track = probe.format.tracks().first().unwrap(); // 通过总采样数 ÷ 采样率计算时长 let duration = track.duration.unwrap().as_secs_f64(); println!("时长:{}秒", duration); Ok(()) }
3. hound(仅针对WAV文件)
如果只需要处理WAV格式,这个轻量库针对性强、用法简单:
use hound::WavReader; fn main() -> Result<(), Box<dyn std::error::Error>> { let reader = WavReader::open("your_audio_file.wav")?; let spec = reader.spec(); // 总采样数 ÷ 采样率 = 时长(秒) let duration = reader.len() as f64 / spec.sample_rate as f64; println!("时长:{}秒", duration); Ok(()) }
内容的提问来源于stack exchange,提问作者Trevor Satori
相关产品推荐
相关产品推荐

