Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
333 views
in Technique[技术] by (71.8m points)

c++ - 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
";
m_Client->write(header);

QByteArray ContentType = "Content-Type: image/jpeg

";
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
" 
        "Server: YourServerName
" 
        "Connection: close
" 
        "Max-Age: 0
" 
        "Expires: 0
" 
        "Cache-Control: no-cache, private
" 
        "Pragma: no-cache
" 
        "Content-Type: multipart/x-mixed-replace; " 
        "boundary=--BoundaryString

");
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
" 
                                 "Content-type: image/jpg

");

    m_Client->write(BoundaryString);
    m_Client->write(ba); // Write The Encoded Image

    QThread::usleep(500);
}

m_Client->close();
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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
" 
                          "Server: en.code-bude.net example server
" 
                          "Cache-Control: no-cache
" 
                          "Cache-Control: private
" 
                          "Content-Type: multipart/x-mixed-replace;boundary=--boundary

");

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
" 
                                 "Content-Type: image/jpeg
" 
                                 "Content-Length: ");

    BoundaryString.append(QString::number(CurrentImg.length()));
    BoundaryString.append("

");

    m_TcpHttpClient->write(BoundaryString);
    m_TcpHttpClient->write(CurrentImg); // Write The Encoded Image

    m_TcpHttpClient->flush();
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...