【问题标题】:subclassing QIODevice for QAudioDecoder为 QAudioDecoder 子类化 QIODevice
【发布时间】:2016-08-21 05:12:20
【问题描述】:

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();

【问题讨论】:

  • 我不明白,你为什么要继承 QIODevice?您可以使用 QIODevice 的现成子类。例如,在您的情况下,您可以使用 QFIle。

标签: c++ qt audio


【解决方案1】:

您的isSequential()、bytesAvailable() 和size() 方法都不会覆盖QIODevice 中的相应方法,因为签名不匹配。他们都缺少const 限定符。在覆盖虚方法时使用 C++11 override 关键字会有所帮助。

【讨论】:

  • 感到很尴尬...我怎么能忽略这一点?谢谢,现在可以正常使用了。
  • 为了那些想要实现这个或类似的东西的人。在进一步玩之后,我发现:1.不必覆盖size,这对流媒体非常有用,但是2.必须覆盖pos否则解码器将不同步并且声音会失速或将太快。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多