需要实现一个mjpeg流

时间:2013-03-12 14:52:49

标签: http mjpeg mongoose-web-server

我想使用mongoose轻量级Web服务器实现MJPEG流。有人能给我一些关于我如何有效地做到这一点的指示吗?我已经拥有了我需要流式传输的jpeg文件,并且我理解了MJPEG概念。我只需要知道如何从协议级别实现MJPEG流。

1 个答案:

答案 0 :(得分:1)

几乎所有ip摄像机实现的mjpeg over http都是multipart mime消息的子类型。 http://en.wikipedia.org/wiki/MIME#Mixed-Replace

你必须用填充jbuf的实现替换cvloop()。

#include <vector>
#include "mongoose.h"

#ifdef _WIN32 
#include <windows.h>
#define SLEEP(ms) Sleep(ms)
#endif
#ifdef __linux__ 
#define SLEEP(ms) usleep(ms*1000)
#endif

std::vector<unsigned char> jbuf;//fill this with a single jpeg image data

#include "opencv2/highgui/highgui.hpp"
void cvloop()
{
    cv::VideoCapture cap("c:/toprocess/frame_%004d.jpg");
    cv::Mat frame;
    for(;;)
    {
        cap>>frame;
        std::vector<unsigned char> buffer;
        std::vector<int> param(2);
        param[0]=CV_IMWRITE_JPEG_QUALITY;
        param[1]=40;
        imencode(".jpg",frame,buffer,param);
        jbuf.swap(buffer);
        SLEEP(50);
    }
}

// This function will be called by mongoose on every new request.
static int begin_request_handler(struct mg_connection *conn) {
    mg_printf(conn,
        "HTTP/1.1 200 OK\r\n"
        "Content-Type: multipart/x-mixed-replace;boundary=b\r\n"
        "Cache-Control: no-store\r\n"
        "Pragma: no-cache\r\n"
        "Connection: close\r\n"
        "\r\n");
    for(;;)
    {
        if( jbuf.size()<4 || 
            (jbuf[0]!=0xff && jbuf[0]!=0xd8) ||
            (jbuf[jbuf.size()-2]!=0xff && jbuf[jbuf.size()-1]!=0xd9))
        {
            SLEEP(10);
            continue;
        }
        mg_printf(conn,
            "--b\r\n"
            "Content-Type: image/jpeg\r\n"
            "Content-length: %d\r\n"
            "\r\n",jbuf.size());
        int ret=mg_write(conn,&jbuf[0], jbuf.size());
        if(ret==0||ret==-1) return 1;
        SLEEP(50);
    }
    return 1;
}

int main(void) {
    struct mg_context *ctx;
    struct mg_callbacks callbacks;

    // List of options. Last element must be NULL.
    const char *options[] = {"listening_ports", "8080",NULL};

    // Prepare callbacks structure. We have only one callback, the rest are NULL.
    memset(&callbacks, 0, sizeof(callbacks));
    callbacks.begin_request = begin_request_handler;

    // Start the web server.
    ctx = mg_start(&callbacks, NULL, options);
    cvloop();

    // Wait until user hits "enter". Server is running in separate thread.
    // Navigating to http://localhost:8080 will invoke begin_request_handler().
    getchar();

    // Stop the server.
    mg_stop(ctx);

    return 0;
}