【问题标题】:WebAPI PushStreamContent client read video streamWebAPI PushStreamContent 客户端读取视频流
【发布时间】:2019-06-12 13:14:26
【问题描述】:

我有一个通过 webapi 公开的相机。此相机返回 jpeg 帧。在服务器端,我使用以下方法:

[Route("api/v1/camera/live/stream")]
[HttpGet]
public HttpResponseMessage GetStream()
{
    logger.Trace($"GET api/v1/camera/live/stream called");

    var response = Request.CreateResponse(HttpStatusCode.PartialContent);
    response.Content = new PushStreamContent(new Action<Stream, HttpContent, TransportContext>(async (stream, content, tansportContext) =>
    {
        EventHandler<AcquiredDataEventArgs<CameraFrame>> handler = (_, __) => { };
        try
        {
            MjpegWriter writer = new MjpegWriter(stream);
            handler = (s, e) => writer.Write(e.Data.Image.GetJpegStream());

            camera.DataAcquired += handler;
            while (HttpContext.Current.Response.IsClientConnected)
            {
                await Task.Delay(100);
            }
            camera.DataAcquired -= handler;
        }
        catch (Exception ex)
        {
            logger.Error($"Streaming error", ex);
            throw;
        }
        logger.Trace("streaming ended");

    }));

    response.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/x-mixed-replace; boundary=--boundary");

    return response;
}

我想在 WPF 应用程序中实时显示此视频流。 如果我通过网络浏览器打开视频流,它可以很好地流式传输视频......但是我如何流式传输到 c# 客户端应用程序?

【问题讨论】:

    标签: c# asp.net-web-api video-streaming


    【解决方案1】:

    您可以为此使用 HttpClient。只要确保你没有通过设置HttpCompletionOption.ResponseHeadersRead来缓冲响应。

    using (var httpClient = new HttpClient())
    using (var response = await httpClient.GetAsync("http://...",
        HttpCompletionOption.ResponseHeadersRead))
    using (Stream stream = await response.Content.ReadAsStreamAsync())
    {
        // Do whatever with the resulting stream.
    }
    

    【讨论】:

      【解决方案2】:

      Lib(可通过 nuget 获得)Emgu.CV 是 OpenCV 上的 C# 包装器,可以接收流。

      using Emgu.CV;
      
      ...
      
          private void StartWatching()
          {
              Task.Run(() =>
              {
                  try
                  {
                      capture = new VideoCapture(headConfiguration.CameraStreamingUri.ToString());
                      capture.ImageGrabbed += Capture_ImageGrabbed;
                      capture.Start(ExceptionHandler.AlwaysHandle);
                  }
                  catch (Exception ex)
                  {
                      capture = null;
                      Logger.Error(ex);
                      throw ex;
                  }
              });
          }
      
          private void Capture_ImageGrabbed(object sender, EventArgs e)
          {
              if (capture == null || OnNewCameraFrame == null)
              {
                  return;
              }
      
              try
              {
                  var frame = new Mat();
                  if (capture.Retrieve(frame))
                  {
                      var output = new ByteImage(frame.Width, frame.Height, frame.Step);
      
                      Marshal.Copy(frame.DataPointer, output.Data, 0, output.Height * output.Stride);
      
                      OnNewCameraFrame?.Invoke(this, new ValueChangeArgs<ByteImage>(output));
                  }
              }
              catch (Exception ex)
              {
                  Logger.Error(ex);
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-24
        • 2013-04-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多