如何使用 QTcp-Server 套接字创建 HTTP MJPEG 流媒体服务器?
How to Create a HTTP MJPEG Streaming Server With QTcp-Server Sockets?
我想创建一个 Http 服务器来发送 MJPEG 流。我已经可以发送图片,但不能发送直播。
我做了什么:创建了一个 TCP 服务器。当客户端连接时,会创建一个 TCP-Socket。然后我实现了一个 ReadyRead SLOT,它在浏览器向服务器发送 "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 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();
我想过创建一个循环来重复图像流部分
但这不起作用。浏览器一直在加载,没有任何反应....
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 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();
我自己解决了....
我只需要调整一些协议相关的东西....
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();
}
我想创建一个 Http 服务器来发送 MJPEG 流。我已经可以发送图片,但不能发送直播。
我做了什么:创建了一个 TCP 服务器。当客户端连接时,会创建一个 TCP-Socket。然后我实现了一个 ReadyRead SLOT,它在浏览器向服务器发送 "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 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();
我想过创建一个循环来重复图像流部分 但这不起作用。浏览器一直在加载,没有任何反应....
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 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();
我自己解决了.... 我只需要调整一些协议相关的东西....
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();
}