subclassing QIODevice for QAudioDecoder

subclassing QIODevice for QAudioDecoder

本文关键字:QAudioDecoder for QIODevice subclassing      更新时间:2023-10-16

Qt 5.7

根据文档,QAudioDecoder不支持流媒体。但是它接受文件名或QIODevice作为源。"好主意"来了:让我们子类QIODevice创建流媒体支持。

但是我总是得到一个错误:

无法启动解码过程。流中没有数据

我已经检查,再次检查和调试。我想不出是什么问题。

我只是在测试它,所以下面的代码绝不是最终的。

头:

class InputBuffer : public QIODevice
{
public:
    InputBuffer(QString fileName);
    ~InputBuffer();
    qint64 readData(char *data, qint64 maxlen);
    qint64 writeData(const char *data, qint64 len);
    bool   isSequential();
    qint64 bytesAvailable();
    qint64 size();

private:
    char*  bufferRef;
    qint64 length;
    qint64 position;
};
实现:

#include "inputbuffer.h"
InputBuffer::InputBuffer(QString fileName)
{
    QFileInfo fileInfo(fileName);
    length   = fileInfo.size();
    position = 0;
    bufferRef = (char*)malloc(length);
    QFile file(fileName);
    file.open(QFile::ReadOnly);
    file.read(bufferRef, length);
    file.close();
    emit readyRead();
}

InputBuffer::~InputBuffer()
{
    free(bufferRef);
}

qint64 InputBuffer::readData(char *data, qint64 maxlen)
{
    if (position >= length) {
        return -1;
    }
    qint64 readSize = qMin(maxlen, length - position);
    memcpy(data, bufferRef + position, readSize);
    position += readSize;
    return readSize;
}

qint64 InputBuffer::writeData(const char *data, qint64 len)
{
    return -1;
}

bool InputBuffer::isSequential()
{
    return true;
}

qint64 InputBuffer::bytesAvailable()
{
    return length - position;
}

qint64 InputBuffer::size()
{
    return length;
}

用法:

inputBufferRef = new InputBuffer("/home/pp/Zenék/Test.mp3");
inputBufferRef->open(QIODevice::ReadOnly);
audioDecoderRef = new QAudioDecoder();
audioDecoderRef->setAudioFormat(audioFormat);
audioDecoderRef->setSourceDevice(inputBufferRef);
connect(audioDecoderRef, SIGNAL(bufferReady()),               this, SLOT(decoderBufferReady()));
connect(audioDecoderRef, SIGNAL(finished()),                  this, SLOT(decoderFinished()));
connect(audioDecoderRef, SIGNAL(error(QAudioDecoder::Error)), this, SLOT(decoderError(QAudioDecoder::Error)));
audioDecoderRef->start();

您的isSequential(), bytesAvailable()size()方法都没有覆盖QIODevice中各自的方法,因为签名不匹配。他们都缺少一个const限定符。在重写虚方法时使用c++ 11 override关键字有帮助。