How to Create a HTTP MJPEG Streaming Server With QTcp-Server Sockets?



  • I want to create a Http Server to send an MJPEG Stream. I'm Already able to send an Image but no Live-Stream.

    What I did: Created an TCP-Server. When a client Connects a TCP-Socket is created. Then I implemented a ReadyRead SLOT which gots executed when the Browser sends the "GET" Request to the Server.

    GET / HTTP/1.1
    Host: 127.0.0.1:8889
    User-Agent: Mozilla/5.0...
    

    Then I run following Code

    QString inbound = m_Client->readAll();
    
    QByteArray header = "HTTP/1.1 200 OK\r\n";
    m_Client->write(header);
    
    QByteArray ContentType = "Content-Type: image/jpeg\r\n\n";
    m_Client->write(ContentType);
    
    Mat first_img; //OPENCV Material
    m_Stream->read(first_img); // Read Image from Webcam
    QImage img = Mat2QImage(first_img); // Convert to QImage
    QByteArray ba; // QByteArray as Buffer for JPG Envoded QImage
    QBuffer buffer(&ba);
    buffer.open(QIODevice::WriteOnly);
    img.save(&buffer, "JPG");
    m_Client->write(ba); // Write The Encoded Image
    
    m_Client->close();
    

    I thought about creating a loop to repeat the Image Streaming Part
    but this doesn't work. The Browser Just keeps loading and nothing happens....

    while(1){
        Mat first_img; //OPENCV Material
        m_Stream->read(first_img); // Read Image from Webcam
        
        QImage img = Mat2QImage(first_img); // Convert to QImage
        QByteArray ba; // QByteArray as Buffer for JPG Envoded QImage
        QBuffer buffer(&ba);
        buffer.open(QIODevice::WriteOnly);
        img.save(&buffer, "JPG");
        
        m_Client->write(ba); // Write The Encoded Image
    
        QThread::usleep(500);
    }
    

    What am I missing? Is the Coding wrong or the way i Handle The Request? Perhaps mime-types?


    Update
    I had a look at
    http://www.damonkohler.com/2010/10/mjpeg-streaming-protocol.html
    and
    https://en.wikipedia.org/wiki/Motion_JPEG
    and tried to implement theses Methods but without any Results....

    QString inbound = m_Client->readAll();
    
    QByteArray ContentType = ("HTTP/1.0 200 OK\r\n" \
            "Server: YourServerName\r\n" \
            "Connection: close\r\n" \
            "Max-Age: 0\r\n" \
            "Expires: 0\r\n" \
            "Cache-Control: no-cache, private\r\n" \
            "Pragma: no-cache\r\n" \
            "Content-Type: multipart/x-mixed-replace; " \
            "boundary=--BoundaryString\r\n\r\n");
    m_Client->write(ContentType);
    
    while(1){
        Mat first_img; //OPENCV Material
        m_Stream->read(first_img); // Read Image from Webcam
    
        QImage img = Mat2QImage(first_img); // Convert to QImage
        QByteArray ba; // QByteArray as Buffer for JPG Envoded QImage
        QBuffer buffer(&ba);
        buffer.open(QIODevice::WriteOnly);
        img.save(&buffer, "JPG");
    
        QByteArray BoundaryString = ("--BoundaryString\r\n" \
                                     "Content-type: image/jpg\r\n\r\n");
    
        m_Client->write(BoundaryString);
        m_Client->write(ba); // Write The Encoded Image
    
        QThread::usleep(500);
    }
    
    m_Client->close();

  • Qt Champions 2016

    Hi
    You should go and select Edit and Purge on the other post so it get fully deleted.


  • Lifetime Qt Champion

    Hi,

    If I may, did you consider using a proven technology like gstreamer for that ? You even have the QtGstreamer module that helps make that kind of task pretty easy



  • I solved it myself....
    I just had to adjust some Protocol releated things....

    m_TcpHttpClient->readAll(); // Discard "Get Request String"
    
    QByteArray ContentType = ("HTTP/1.0 200 OK\r\n" \
                              "Server: en.code-bude.net example server\r\n" \
                              "Cache-Control: no-cache\r\n" \
                              "Cache-Control: private\r\n" \
                              "Content-Type: multipart/x-mixed-replace;boundary=--boundary\r\n\r\n");
    
    m_TcpHttpClient->write(ContentType);
    
    
    while(1){
    
        // Image to Byte Array via OPENCV Method
        std::vector<uchar> buff;
        imencode(".jpg",m_VisualEngine->GetActualFrame(),buff);
        std::string content(buff.begin(), buff.end());
        QByteArray CurrentImg(QByteArray::fromStdString(content));
    
    
        QByteArray BoundaryString = ("--boundary\r\n" \
                                     "Content-Type: image/jpeg\r\n" \
                                     "Content-Length: ");
    
        BoundaryString.append(QString::number(CurrentImg.length()));
        BoundaryString.append("\r\n\r\n");
    
        m_TcpHttpClient->write(BoundaryString);
        m_TcpHttpClient->write(CurrentImg); // Write The Encoded Image
    
        m_TcpHttpClient->flush();
    }

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.