如何使用Juce C++在不播放音频文件的前提下获取其时长
获取音频文件时长(无需播放)的JUCE实现方法
刚接触JUCE和C++确实容易被文档绕晕,其实你的思路方向是对的,但没必要用到AudioTransportSource这种和播放绑定的组件——我们只需要读取音频文件的元数据就能拿到时长,完全不需要碰播放相关的逻辑。
先说说你现有代码的问题
最关键的一点:你没有给AudioFormatManager注册任何音频格式!JUCE的AudioFormatManager默认是空的,不认识MP3、WAV这些格式,所以createReaderFor大概率会返回nullptr,直接进入错误分支。另外,AudioTransportSource是用来控制播放的,这里完全是多余的,反而增加了复杂度。
正确的实现方法
我们只需要AudioFormatManager和AudioFormatReader两个类就能搞定,直接通过采样总数 ÷ 采样率计算出时长(秒),这是最直接高效的方式。
第一步:修改函数声明(头文件)
在PlaylistComponent的类定义里,把原来的trackStats改成返回时长的函数:
class PlaylistComponent : public juce::Component, public juce::TableListBoxModel, public Button::Listener, public FileDragAndDropTarget { // ... 其他成员 ... double getAudioDuration(juce::URL audioURL); // 新增这个函数声明 };
第二步:实现函数(cpp文件)
double PlaylistComponent::getAudioDuration(juce::URL audioURL) { AudioFormatManager formatManager; // 注册JUCE支持的所有基础音频格式(MP3、WAV、AIFF等),这一步必须有! formatManager.registerBasicFormats(); // 创建输入流:第二个参数设为false,不需要缓存整个文件,只读头部元数据就行 auto inputStream = audioURL.createInputStream(false); if (!inputStream) { DBG("Failed to open input stream from URL"); return 0.0; } // 创建音频读取器,用智能指针自动管理内存,避免泄漏 std::unique_ptr<AudioFormatReader> reader(formatManager.createReaderFor(std::move(inputStream))); if (!reader) { DBG("Unsupported audio format or invalid file"); return 0.0; } // 核心计算:采样总数除以采样率,得到秒级时长 double duration = static_cast<double>(reader->lengthInSamples) / reader->sampleRate; DBG("Audio duration: " << duration << " seconds"); return duration; }
关键细节解释
- 注册音频格式:
formatManager.registerBasicFormats()是重中之重,没有这一步,JUCE根本不知道怎么解析你的音频文件,这应该是你之前尝试失败的主要原因。 - 内存管理:用
std::unique_ptr管理AudioFormatReader和输入流,不需要手动调用delete,RAII机制会自动帮我们释放资源,避免内存泄漏。 - 高效读取:
createInputStream(false)不会下载/读取整个文件,只会读取足够的头部信息来获取元数据(比如采样率、采样总数),所以即使是大文件也能快速返回结果。 - 时长计算逻辑:音频的时长本质就是「总采样数 ÷ 每秒采样数(采样率)」,这是音频领域的基础逻辑,比通过播放组件间接获取更准确高效。
现在你调用这个函数,传入音频URL就能直接拿到时长了,完全不需要涉及任何播放操作~
内容的提问来源于stack exchange,提问作者Amr Ezzat
相关产品推荐
相关产品推荐

