You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中基于byte[]生成MJPEG流的HTTP服务器实现咨询

MJPEG流实现方案推荐

核心实现逻辑

MJPEG的本质是HTTP长连接+多部分消息(multipart/x-mixed-replace),核心逻辑很直接:

  1. 客户端发起HTTP请求后,服务器不立即关闭连接,持续返回带固定分界符的JPEG数据块
  2. 每个JPEG块前必须附带Content-Type: image/jpeg和Content-Length: [字节数]字段,用分界符区分不同帧

推荐的HTTP服务器库及核心实现

1. Python:Flask + 生成器

Flask的路由支持返回生成器,天然适配流式响应,核心代码示例:

from flask import Flask, Response

app = Flask(__name__)

# 替换为你的摄像头帧接收逻辑
def get_camera_frames():
    while True:
        frame_bytes = get_new_frame_from_camera()  # 你的byte[]帧获取函数
        # 按MJPEG格式封装帧数据
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame_bytes + b'\r\n')

@app.route('/video_feed')
def video_feed():
    return Response(get_camera_frames(),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

2. Java:Spring Boot + StreamingResponseBody

Spring Boot的StreamingResponseBody专门用于流式输出,适合Java项目:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;

@RestController
public class MJpegController {

    @GetMapping("/video_feed")
    public StreamingResponseBody streamVideo(HttpServletResponse response) {
        response.setContentType("multipart/x-mixed-replace; boundary=frame");
        return outputStream -> {
            while (!Thread.currentThread().isInterrupted()) {
                byte[] frameBytes = getNewFrameFromCamera(); // 你的帧获取逻辑
                writeFrame(outputStream, frameBytes);
                outputStream.flush();
                Thread.sleep(33); // 控制帧率,30帧/秒示例
            }
        };
    }

    private void writeFrame(OutputStream os, byte[] frameBytes) throws IOException {
        os.write("--frame\r\n".getBytes());
        os.write(("Content-Length: " + frameBytes.length + "\r\n").getBytes());
        os.write("Content-Type: image/jpeg\r\n\r\n".getBytes());
        os.write(frameBytes);
        os.write("\r\n".getBytes());
    }
}

3. C#:ASP.NET Core + IAsyncEnumerable

ASP.NET Core通过IAsyncEnumerable实现流式响应,代码简洁:

using Microsoft.AspNetCore.Mvc;
using System.Text;
using System.Threading.Tasks;

[ApiController]
[Route("[controller]")]
public class VideoController : ControllerBase
{
    [HttpGet("feed")]
    public async IAsyncEnumerable<byte[]> GetVideoFeed()
    {
        Response.ContentType = "multipart/x-mixed-replace; boundary=frame";
        while (true)
        {
            byte[] frameBytes = GetNewFrameFromCamera(); // 你的帧获取逻辑
            // 封装分界符和帧头
            var boundaryBytes = Encoding.UTF8.GetBytes("--frame\r\nContent-Type: image/jpeg\r\nContent-Length: " + frameBytes.Length + "\r\n\r\n");
            yield return boundaryBytes;
            yield return frameBytes;
            yield return Encoding.UTF8.GetBytes("\r\n");
            await Task.Delay(33); // 控制帧率
        }
    }
}

关键注意事项

  • 必须基于HTTP 1.1协议,依赖默认的Connection: keep-alive维持长连接
  • 分界符要全局固定,客户端依靠它识别新帧的开始
  • 不要省略Content-Length字段,部分浏览器/客户端需要它才能正确解析帧
  • 按需控制帧率,避免服务器和客户端因数据量过大过载

内容的提问来源于stack exchange,提问作者Steve Bates

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 20:55:20