如何使用QTcp-Server套接字创建HTTP MJPEG流媒体服务器

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

本文关键字:MJPEG 流媒体 服务器 HTTP 创建 何使用 QTcp-Server 套接字      更新时间:2023-10-16

我想创建一个Http服务器来发送MJPEG流。我已经能够发送图像,但没有Live-Stream.

我做了什么:创建一个TCP-Server。客户端连接时,创建TCP-Socket。然后我实现了一个ReadyRead插槽,当浏览器向服务器发送"GET"请求时执行。

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

然后我运行以下代码

QString inbound = m_Client->readAll();
QByteArray header = "HTTP/1.1 200 OKrn";
m_Client->write(header);
QByteArray ContentType = "Content-Type: image/jpegrnn";
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();

我想创建一个循环来重复图像流部分但这行不通。浏览器只是继续加载,什么也没发生....

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

我错过了什么?是编码错误还是我处理请求的方式?也许mime类型?


更新我看了看
http://www.damonkohler.com/2010/10/mjpeg-streaming-protocol.html和https://en.wikipedia.org/wiki/Motion_JPEG并尝试实现这些方法,但没有任何结果....

QString inbound = m_Client->readAll();
QByteArray ContentType = ("HTTP/1.0 200 OKrn" 
        "Server: YourServerNamern" 
        "Connection: closern" 
        "Max-Age: 0rn" 
        "Expires: 0rn" 
        "Cache-Control: no-cache, privatern" 
        "Pragma: no-cachern" 
        "Content-Type: multipart/x-mixed-replace; " 
        "boundary=--BoundaryStringrnrn");
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 = ("--BoundaryStringrn" 
                                 "Content-type: image/jpgrnrn");
    m_Client->write(BoundaryString);
    m_Client->write(ba); // Write The Encoded Image
    QThread::usleep(500);
}
m_Client->close();

我自己解决了....我只是需要调整一些协议相关的东西....

m_TcpHttpClient->readAll(); // Discard "Get Request String"
QByteArray ContentType = ("HTTP/1.0 200 OKrn" 
                          "Server: en.code-bude.net example serverrn" 
                          "Cache-Control: no-cachern" 
                          "Cache-Control: privatern" 
                          "Content-Type: multipart/x-mixed-replace;boundary=--boundaryrnrn");
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 = ("--boundaryrn" 
                                 "Content-Type: image/jpegrn" 
                                 "Content-Length: ");
    BoundaryString.append(QString::number(CurrentImg.length()));
    BoundaryString.append("rnrn");
    m_TcpHttpClient->write(BoundaryString);
    m_TcpHttpClient->write(CurrentImg); // Write The Encoded Image
    m_TcpHttpClient->flush();
}