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

C# WPF中实现WebSocket协议MJPEG流解码及替代库咨询

解决方案:在C# WPF中通过WebSocket获取并显示MJPEG流

方案一:扩展AForge.Video以支持WebSocket

AForge的MJPEGStream仅支持HTTP协议,要适配WebSocket,需要自行封装WebSocket客户端获取流数据,再对接AForge的解码逻辑,步骤如下:

    1. 用.NET原生ClientWebSocket建立连接并接收二进制流
      先创建WebSocket连接,循环接收服务器推送的帧数据。注意MJPEG流通常以--boundary作为帧分隔符,需要将收到的字节流按该分隔符拆分出单帧图像数据。
    1. 对接AForge的解码管道
      直接实例化AForge内部的MJPEGDecoder类,将拆分后的帧数据传入解码方法,订阅其NewFrame事件获取解码后的Bitmap,最后在WPF的UI线程中更新图像(需处理跨线程调用)。

示例代码片段:

// 初始化WebSocket客户端
var webSocket = new ClientWebSocket();
await webSocket.ConnectAsync(new Uri("ws://your-node-red-server/mjpeg-stream"), CancellationToken.None);

// 初始化MJPEG解码器
var decoder = new MJPEGDecoder();
decoder.NewFrame += (s, e) =>
{
    // 跨线程更新WPF Image控件
    Dispatcher.Invoke(() =>
    {
        YourImageControl.Source = BitmapToImageSource(e.Frame);
    });
};

// 接收并处理WebSocket数据
var buffer = new byte[4096];
var ms = new MemoryStream();
while (webSocket.State == WebSocketState.Open)
{
    var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
    if (result.MessageType == WebSocketMessageType.Close)
    {
        await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
        break;
    }

    ms.Write(buffer, 0, result.Count);
    // 检查并拆分MJPEG帧(需替换为实际的边界符)
    ms.Position = 0;
    var content = new StreamReader(ms).ReadToEnd();
    var boundaryMarker = "--your-actual-boundary";
    var boundaryIndex = content.IndexOf(boundaryMarker, StringComparison.Ordinal);
    
    if (boundaryIndex > 0)
    {
        var frameBytes = Encoding.ASCII.GetBytes(content.Substring(0, boundaryIndex));
        decoder.Decode(frameBytes, 0, frameBytes.Length);
        
        // 保留剩余数据用于下一帧拼接
        ms.SetLength(0);
        ms.Write(Encoding.ASCII.GetBytes(content.Substring(boundaryIndex)), 0, content.Length - boundaryIndex);
    }
}

// Bitmap转WPF ImageSource的辅助方法
private ImageSource BitmapToImageSource(Bitmap bitmap)
{
    using (var memory = new MemoryStream())
    {
        bitmap.Save(memory, ImageFormat.Png);
        memory.Position = 0;
        var bitmapImage = new BitmapImage();
        bitmapImage.BeginInit();
        bitmapImage.StreamSource = memory;
        bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
        bitmapImage.EndInit();
        return bitmapImage;
    }
}

注意:需将代码中的边界符替换为Node-RED服务器实际返回的值,同时要补充异常处理和断开重连逻辑。

方案二:使用原生支持WebSocket的MJPEG替代库

如果不想扩展AForge,可选择以下现成库:

  • Emgu CV:虽主打计算机视觉,但可通过WebSocket获取流后,直接解码MJPEG帧并转换为WPF支持的图像格式,处理能力较强。
  • FFmpeg.AutoGen:直接调用FFmpeg原生API,FFmpeg本身支持WebSocket协议(直接传入ws://地址即可),能灵活解码各类流格式,适配性最高。
  • Ozeki Camera SDK:封装完善,原生支持WebSocket MJPEG流的解码与显示,适合快速开发,不过属于商业库。

额外提示

需确认Node-RED返回的WebSocket流格式:如果是带HTTP-style边界头的标准MJPEG流,按上述逻辑处理;如果是裸JPEG帧序列,则无需处理边界头,直接解析每帧JPEG数据即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 08:55:19