QMediaPlayer 实现频谱
时间: 2024-05-06 07:20:30 浏览: 99
与频谱有关的Player
5星 · 资源好评率100%
QMediaPlayer是Qt提供的一个多媒体播放器类,可以播放音频和视频文件。要实现频谱,需要使用QAudioProbe类来监听音频输出并获取音频数据,然后使用QAudioSpectrumAnalyzer类来分析音频数据并计算频谱。
具体实现步骤如下:
1. 创建QMediaPlayer对象并设置音频文件路径:
```cpp
QMediaPlayer *player = new QMediaPlayer;
player->setMedia(QUrl::fromLocalFile("audio.mp3"));
```
2. 创建QAudioProbe对象并连接到QMediaPlayer的音频输出:
```cpp
QAudioProbe *probe = new QAudioProbe;
probe->setSource(player);
connect(probe, &QAudioProbe::audioBufferProbed, this, &MyWidget::processBuffer);
```
3. 实现processBuffer槽函数,用于处理音频数据:
```cpp
void MyWidget::processBuffer(const QAudioBuffer &buffer)
{
if (buffer.format().channelCount() != 1) {
qDebug() << "Only support mono audio";
return;
}
const quint32 numSamples = buffer.frameCount();
const quint32 sampleRate = buffer.format().sampleRate();
const quint32 qbytesPerSample = buffer.format().bytesPerFrame();
const char *data = static_cast<const char *>(buffer.constData());
QVector<float> samples(numSamples);
for (quint32 i = 0; i < numSamples; ++i) {
const char *sample = data + i * qbytesPerSample;
int value = 0;
if (qbytesPerSample == 2) {
value = *reinterpret_cast<const qint16 *>(sample);
} else if (qbytesPerSample == 4) {
value = *reinterpret_cast<const qint32 *>(sample) >> 8;
}
samples[i] = value / 32768.0;
}
QAudioSpectrumAnalyzer spectrum;
spectrum.setSampleRate(sampleRate);
spectrum.setChannel(0);
spectrum.setWindowFunction(QVector<float>(numSamples, 1.0));
spectrum.setInputData(samples.constData(), numSamples);
QVector<float> levels = spectrum.calculateLevels();
// 处理频谱数据
}
```
4. 在处理频谱数据的代码中,可以使用QPainter绘制出频谱图:
```cpp
void MyWidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.fillRect(rect(), Qt::black);
painter.setBrush(Qt::red);
painter.setPen(Qt::NoPen);
const int numBars = 50;
const int barWidth = width() / numBars;
const int heightScale = height() / 100;
for (int i = 0; i < numBars; ++i) {
const int level = levels[i * levels.size() / numBars];
painter.drawRect(i * barWidth, height() - level * heightScale, barWidth, level * heightScale);
}
}
```
完整代码示例:
```cpp
#include <QtWidgets>
#include <QtMultimedia>
class MyWidget : public QWidget
{
Q_OBJECT
public:
MyWidget(QWidget *parent = nullptr) : QWidget(parent)
{
QMediaPlayer *player = new QMediaPlayer;
player->setMedia(QUrl::fromLocalFile("audio.mp3"));
QAudioProbe *probe = new QAudioProbe;
probe->setSource(player);
connect(probe, &QAudioProbe::audioBufferProbed, this, &MyWidget::processBuffer);
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(new QLabel("Press Play to start playing audio"));
QPushButton *playButton = new QPushButton("Play");
layout->addWidget(playButton);
connect(playButton, &QPushButton::clicked, player, &QMediaPlayer::play);
setFixedSize(400, 400);
}
protected:
void paintEvent(QPaintEvent *event) override
{
QPainter painter(this);
painter.fillRect(rect(), Qt::black);
painter.setBrush(Qt::red);
painter.setPen(Qt::NoPen);
const int numBars = 50;
const int barWidth = width() / numBars;
const int heightScale = height() / 100;
for (int i = 0; i < numBars; ++i) {
const int level = levels[i * levels.size() / numBars];
painter.drawRect(i * barWidth, height() - level * heightScale, barWidth, level * heightScale);
}
}
private slots:
void processBuffer(const QAudioBuffer &buffer)
{
if (buffer.format().channelCount() != 1) {
qDebug() << "Only support mono audio";
return;
}
const quint32 numSamples = buffer.frameCount();
const quint32 sampleRate = buffer.format().sampleRate();
const quint32 qbytesPerSample = buffer.format().bytesPerFrame();
const char *data = static_cast<const char *>(buffer.constData());
QVector<float> samples(numSamples);
for (quint32 i = 0; i < numSamples; ++i) {
const char *sample = data + i * qbytesPerSample;
int value = 0;
if (qbytesPerSample == 2) {
value = *reinterpret_cast<const qint16 *>(sample);
} else if (qbytesPerSample == 4) {
value = *reinterpret_cast<const qint32 *>(sample) >> 8;
}
samples[i] = value / 32768.0;
}
QAudioSpectrumAnalyzer spectrum;
spectrum.setSampleRate(sampleRate);
spectrum.setChannel(0);
spectrum.setWindowFunction(QVector<float>(numSamples, 1.0));
spectrum.setInputData(samples.constData(), numSamples);
levels = spectrum.calculateLevels();
update();
}
private:
QVector<float> levels;
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyWidget widget;
widget.show();
return app.exec();
}
#include "main.moc"
```
阅读全文