如何使用CGI流式传输运动jpeg

How to stream motion jpeg using CGI?

本文关键字:传输 运动 jpeg 何使用 CGI      更新时间:2023-10-16

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

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

我已经尝试了以下代码,但它不起作用...

#include <iostream>
#include <cstdio>
int main()
{
    std::cout << "Cache-Control: no-cachenn";
    std::cout << "Cache-Control: privatenn";
    std::cout << "Pragma: no-cachenn";
    std::cout << "Content-type: multipart/x-mixed-replace; boundary=spidermannn";
    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 << "--spidermann";
        std::cout << "Content-type: image/jpegnn";
    }
}

经过非常困难的二进制调试,我能够提出一个简单的解决方案:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
int main()
{
    printf("Content-Type: multipart/x-mixed-replace; boundary=--jpgboundaryrnrn");
    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/jpegrn");
        printf("Content-length: %ldrnrn", fileSize);
        fwrite(buffer, 1, fileSize, stdout);
        printf("rnrnrn");
        usleep(1000);
    }
}

这实际上加载了一系列图像并将它们刷新到浏览器。我用谷歌浏览器测试了输出,它按预期工作。