如何使用CGI流式传输jpeg?

时间:2019-01-30 13:46:58

标签: c++ http cgi jpeg

我正在创建一个Web应用程序,该应用程序需要显示我从高速摄像机抓取的视频。 为此,我试图创建一个Motion JPEG CGI应用程序,当浏览器访问该CGI应用程序时,该应用程序将这些帧作为JPG序列输出。

所以我的问题是:如何创建一个简单的C ++代码,该代码只读取一系列JPG文件,然后将其输出打印到其他文件中,以供浏览器以JPG序列加载?

我尝试了以下代码,但无法正常工作...

#include <iostream>
#include <cstdio>

int main()
{
    std::cout << "Cache-Control: no-cache\n\n";
    std::cout << "Cache-Control: private\n\n";
    std::cout << "Pragma: no-cache\n\n";
    std::cout << "Content-type: multipart/x-mixed-replace; boundary=spiderman\n\n";

    int i = 0;
    while(true)
    {
        char buffer[1024];
        sprintf(buffer, "/tmp/img_%d.jpg", (i%2));
        FILE* fp = fopen(buffer, "r");
        while(!feof(fp))
        {
            fread(buffer, 1, 1, fp); 
            fwrite(buffer, 1, 1, stdout);
        }
        fclose(fp);
        i++;
        std::cout << "--spiderman\n";
        std::cout << "Content-type: image/jpeg\n\n";
    }
}

1 个答案:

答案 0 :(得分:1)

经过非常艰苦的二进制调试之后,我提出了一个简单的解决方案:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <unistd.h>

int main()
{
    printf("Content-Type: multipart/x-mixed-replace; boundary=--jpgboundary\r\n\r\n");

    int i = 0;
    while(true)
    {
        char fnameBuffer[1024];
        sprintf(fnameBuffer, "/tmp/img_%d.jpg", (i%2));
        FILE* fp = fopen(fnameBuffer, "r");
        fseek(fp, 0, SEEK_END);
        long fileSize = ftell(fp);
        rewind(fp);

        char* buffer = (char*)malloc(sizeof(char)*fileSize);
        fread(buffer, 1, fileSize, fp);
        fclose(fp);
        free(buffer);

        i++;
        printf("--jpgboundary");
        printf("Content-type: image/jpeg\r\n");
        printf("Content-length: %ld\r\n\r\n", fileSize);
        fwrite(buffer, 1, fileSize, stdout);
        printf("\r\n\r\n\r\n");

        usleep(1000);
    }
}

这实际上将加载一系列图像并将其刷新到浏览器。 我使用Google Chrome浏览器测试了输出,并且按预期运行。