25

好吧,我正在尝试对视频流进行证明,我正在使用 asp.net c#。我有点迷茫,你有什么想法或建议吗?

4

4 回答 4

27

我在 SignalR 之上实现了视频流。您可以在http://weblogs.asp.net/ricardoperes/archive/2014/04/24/video-streaming-with-asp-net-signalr-and-html5.aspx找到我的示例。

于 2014-04-24T16:07:04.387 回答
26

不,SignalR 基于仅流式传输基于文本的 JSON 消息的标准(WebSockets、LongPolling、ForeverFrame 等)。您可能最好查看WebRTC 规范。现在,您可以通过使用 SignalR 发送控制消息来将这两种技术结合在一起,该消息会触发一些 JavaScript,从而更改浏览器当前显示的 WebRTC 提要。

于 2012-10-23T01:12:47.450 回答
2

是的,最新版本的 SignalR 核心支持流式传输。Microsoft 提供的
一些示例。

于 2022-01-20T11:55:42.117 回答
1

我不知道 SignalR 是否旨在处理视频流,但 SignalR 是客户端到客户端客户端到服务器和服务器到客户端之间的集线器容器。如果我想要视频聊天,为什么我不能将它用作我的中心?无论如何,SignalR 也可以处理字节数组,而不仅仅是字符串,然后让我们尝试将每个帧作为字节 [](流)发送。至少当我只使用 .Net 时,我可以集线器字节 []。当我输入 Python 时,我需要使用 base64 序列化为字符串,它也可以从我的 PI 中工作。关注我推入 GIT 的实验室解决方案。https://github.com/Guille1878/VideoChat

SignalR Hub(默认,非无服务器)

namespace ChatHub
{
    public interface IVideoChatClient
    {
        Task DownloadStream(byte[] stream);
    }

    public class VideoChatHub : Hub<IVideoChatClient> 
    {
        public async Task UploadStream(byte[] stream)
        {
            await Clients.All.DownloadStream(stream);
        }
    }
}

视频发送者:(UWP)

while (isStreamingOut)
{
      var previewProperties = mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview) as VideoEncodingProperties;

      VideoFrame videoFrame = new VideoFrame(BitmapPixelFormat.Bgra8, (int)previewProperties.Width, (int)previewProperties.Height);
    
      Var frame = await mediaCapture.GetPreviewFrameAsync(videoFrame)

      if (frame == null)
      {
            await Task.Delay(delayMilliSeconds);
            continue;
      }

      var memoryRandomAccessStream = new InMemoryRandomAccessStream();
      var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, memoryRandomAccessStream);
      encoder.SetSoftwareBitmap(frame.SoftwareBitmap);  
      encoder.IsThumbnailGenerated = false;
      await encoder.FlushAsync();

      try
      {
             var array = new byte[memoryRandomAccessStream.Size];
             await memoryRandomAccessStream.ReadAsync(array.AsBuffer(), (uint)memoryRandomAccessStream.Size, InputStreamOptions.None);

             if (array.Any())
                  await connection.InvokeAsync("UploadStream", array);                   
       }
       catch (Exception ex)
       {
              System.Diagnostics.Debug.WriteLine(ex.Message);
       }

       await Task.Delay(5);
}

视频接收器:(UWP)

private async void StreamVideo_Click(object sender, RoutedEventArgs e)
{
      isStreamingIn = StreamVideo.IsChecked ?? false;
      if (isStreamingIn)
      {
            hubConnection.On<byte[]>("DownloadStream", (stream) =>
            {
                  _ = this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                  {
                       if (isStreamingIn)
                           StreamedArraysQueue.Enqueue(stream);
                  });
             });

             if (hubConnection.State == HubConnectionState.Disconnected)
                  await hubConnection.StartAsync();

              _ = BuildImageFrames();
           }
       }     
}

private async Task BuildImageFrames()
{
      while (isStreamingIn)
      {
            await Task.Delay(5);

            StreamedArraysQueue.TryDequeue(out byte[] buffer);

            if (!(buffer?.Any() ?? false))
                  continue;

            try
            {
                    var randomAccessStream = new InMemoryRandomAccessStream();
                    await randomAccessStream.WriteAsync(buffer.AsBuffer());
                    randomAccessStream.Seek(0); 
                    await randomAccessStream.FlushAsync();

                    var decoder = await BitmapDecoder.CreateAsync(randomAccessStream);

                    var softwareBitmap = await decoder.GetSoftwareBitmapAsync();

                    var imageSource = await ConvertToSoftwareBitmapSource(softwareBitmap);

                    ImageVideo.Source = imageSource;
             }
             catch (Exception ex)
             {
                    System.Diagnostics.Debug.WriteLine(ex.Message);
             }
       }
}

我正在使用“SignalR 核心”

于 2020-07-31T09:52:53.913 回答