2016-08-21 28 views
1

的Qt 5.7繼承了QIODevice的QAudioDecoder

根據該文件,QAudioDecoder不支持流媒體。但接受一個文件名或QIODevice作爲來源。出現了「聰明的想法」:讓我們子類QIODevice創建流媒體支持。

但我總是得到一個錯誤:

Unable to start decoding process. Stream contains no data.

我已經檢查和雙重檢查和調試。無法弄清楚什麼是問題。

我只測試它,所以下面的代碼絕不是最終的。

頭:

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

我不明白,你爲什麼繼承QIODevice?您可以使用QIODevice的ready子類。例如,你的情況你可以使用QFIle。 –

回答

4

isSequential()bytesAvailable(),也不size()方法無覆蓋各自的方法QIODevice,因爲簽名d不匹配。他們都缺少const限定詞。覆蓋虛擬方法時使用C++ 11 override關鍵字有幫助。

+0

感覺尷尬......我怎麼能忽略這個?謝謝,它現在完美。 – Peter

+0

爲了那些想要實現這個或類似的東西。在進一步播放之後,我發現:1.不必重寫'size',這對於流式傳輸非常有用,但是2.必須覆蓋'pos',否則解碼器將不同步,聲音將會失速或將過快。 – Peter