2016-08-21 1 views
1

Qt 5.7QIODevice für QAudioDecoder

Gemäß der Dokumentation Subklassen, QAudioDecoder unterstützt keine Streaming-Medien. Aber akzeptiert entweder einen Dateinamen oder eine QIODevice als Quelle. Kam die "gute Idee": Lassen Sie uns QIODevice Unterklasse, um Streaming Media Support zu erstellen.

Aber ich immer eine Fehlermeldung erhalten:

Unable to start decoding process. Stream contains no data.

Ich habe überprüft und doppelt geprüft und korrigiert. Kann nicht herausfinden, was das Problem sein kann.

Ich teste es nur, also ist der folgende Code keineswegs endgültig.

Header:

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; 

}; 

Umsetzung:

#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; 
} 

Nutzung:

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

Ich verstehe nicht, warum Unterklasse QIODevice? Sie können fertige Unterklassen von QIODevice verwenden. In Ihrem Fall können Sie beispielsweise QFIle verwenden. –

Antwort

4

Keine Ihrer isSequential(), bytesAvailable() noch size() Methoden in QIODevice die jeweilige Methode überschreiben, da die Unterschriften d nicht übereinstimmen. Ihnen fehlt ein const Qualifier. Die Verwendung des Schlüsselworts C++ 11 override beim Überschreiben virtueller Methoden hilft.

+0

Sich peinlich fühlen ... wie könnte ich das übersehen? Danke, es funktioniert jetzt perfekt. – Peter

+0

Für diejenigen, die dies oder etwas ähnliches umsetzen wollen. Nachdem ich damit weitergespielt habe, habe ich folgendes gefunden: 1. muss nicht "size" überschreiben, was großartig für das Streaming ist, aber 2. muss "pos" übersteuern, sonst wird der Decoder nicht mehr synchron sein und der Sound wird Stall oder wird zu schnell sein. – Peter

Verwandte Themen