gpt4 book ai didi

c++ - 如何使用 QAudioOutput 和 QAudioDecoder 播放 mp3 文件?

转载 作者:搜寻专家 更新时间:2023-10-31 02:13:32 26 4
gpt4 key购买 nike

我想使用 QAudioOutput 将音频文件播放到指定的设备。 .wav 文件没问题。但是播放.mp3文件时有嗡嗡声(我知道.mp3文件是压缩文件,所以QAudioOutput不能直接播放)。
我正在尝试在播放 QAudioOutput 之前解码 .mp3 文件,但我不知道如何解码。
你能给我一个示例代码,以便我们可以使用 QAudioOutput 和 QAudioDecoder 播放 mp3 文件吗?

最佳答案

有解决办法:

音频文件流

#pragma once

#include <QIODevice>
#include <QBuffer>
#include <QAudioDecoder>
#include <QAudioFormat>
#include <QFile>

// Class for decode audio files like MP3 and push decoded audio data to QOutputDevice (like speaker) and also signal newData().
// For decoding it uses QAudioDecoder which uses QAudioFormat for decode audio file for desire format, then put decoded data to buffer.
// based on: https://github.com/Znurre/QtMixer
class AudioFileStream : public QIODevice
{
Q_OBJECT

public:
AudioFileStream();
bool init(const QAudioFormat& format);

enum State { Playing, Stopped };

void play(const QString &filePath);
void stop();

bool atEnd() const override;

protected:
qint64 readData(char* data, qint64 maxlen) override;
qint64 writeData(const char* data, qint64 len) override;

private:
QFile m_file;
QBuffer m_input;
QBuffer m_output;
QByteArray m_data;
QAudioDecoder m_decoder;
QAudioFormat m_format;

State m_state;

bool isInited;
bool isDecodingFinished;

void clear();

private slots:
void bufferReady();
void finished();

signals:
void stateChanged(AudioFileStream::State state);
void newData(const QByteArray& data);
};

音频文件流.cpp

#include "AudioFileStream.h"

AudioFileStream::AudioFileStream() :
m_input(&m_data),
m_output(&m_data),
m_state(State::Stopped)
{
setOpenMode(QIODevice::ReadOnly);

isInited = false;
isDecodingFinished = false;
}

// format - it is audio format to which we whant decode audio data
bool AudioFileStream::init(const QAudioFormat& format)
{
m_format = format;
m_decoder.setAudioFormat(m_format);

connect(&m_decoder, SIGNAL(bufferReady()), this, SLOT(bufferReady()));
connect(&m_decoder, SIGNAL(finished()), this, SLOT(finished()));

// Initialize buffers
if (!m_output.open(QIODevice::ReadOnly) || !m_input.open(QIODevice::WriteOnly))
{
return false;
}

isInited = true;

return true;
}

// AudioOutput device (like speaker) call this function for get new audio data
qint64 AudioFileStream::readData(char* data, qint64 maxlen)
{
memset(data, 0, maxlen);

if (m_state == State::Playing)
{
m_output.read(data, maxlen);

// There is we send readed audio data via signal, for ability get audio signal for the who listen this signal.
// Other word this emulate QAudioProbe behaviour for retrieve audio data which of sent to output device (speaker).
if (maxlen > 0)
{
QByteArray buff(data, maxlen);
emit newData(buff);
}

// Is finish of file
if (atEnd())
{
stop();
}
}

return maxlen;
}

qint64 AudioFileStream::writeData(const char* data, qint64 len)
{
Q_UNUSED(data);
Q_UNUSED(len);

return 0;
}

// Start play audio file
void AudioFileStream::play(const QString &filePath)
{
clear();

m_file.setFileName(filePath);

if (!m_file.open(QIODevice::ReadOnly))
{
return;
}

m_decoder.setSourceDevice(&m_file);
m_decoder.start();

m_state = State::Playing;
emit stateChanged(m_state);
}

// Stop play audio file
void AudioFileStream::stop()
{
clear();
m_state = State::Stopped;
emit stateChanged(m_state);
}


void AudioFileStream::clear()
{
m_decoder.stop();
m_data.clear();
isDecodingFinished = false;
}

// Is finish of file
bool AudioFileStream::atEnd() const
{
return m_output.size()
&& m_output.atEnd()
&& isDecodingFinished;
}



/////////////////////////////////////////////////////////////////////
// QAudioDecoder logic this methods responsible for decode audio file and put audio data to stream buffer

// Run when decode decoded some audio data
void AudioFileStream::bufferReady() // SLOT
{
const QAudioBuffer &buffer = m_decoder.read();

const int length = buffer.byteCount();
const char *data = buffer.constData<char>();

m_input.write(data, length);
}

// Run when decode finished decoding
void AudioFileStream::finished() // SLOT
{
isDecodingFinished = true;
}


/////////////////////////////////////////////////////////////////////

使用方法:

void init()
{
QAudioDeviceInfo device = QAudioDeviceInfo::defaultOutputDevice();
QAudioFormat desire_audio_romat = device.preferredFormat();

m_audioFileStream = new AudioFileStream;
if (!m_audioFileStream->init(desire_audio_romat))
{
return false;
}

QAudioOutput* m_audioOutput = new QAudioOutput(desire_audio_romat);
m_audioOutput->start(m_audioFileStream);
}

void play()
{
m_audioFileStream->play("C:/file.mp3");
}

void stop()
{
m_audioFileStream->stop;
}

关于c++ - 如何使用 QAudioOutput 和 QAudioDecoder 播放 mp3 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41197576/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com