How to Create a HTTP MJPEG Streaming Server With QTcp-Server Sockets?
-
wrote on 11 Oct 2015, 11:28 last edited by Hypno_Maki 10 Nov 2015, 12:26
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();
-
Hi
You should go and select Edit and Purge on the other post so it get fully deleted. -
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
-
wrote on 13 Oct 2015, 07:42 last edited by
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(); }
1/4