it is possible to stream video with SignalR?

后端 未结 3 927
难免孤独
难免孤独 2020-12-13 10:06

Well I\'m trying to perform a proof about video streaming, I\'m working with asp.net c#. I\'m kind of lost, you have any idea or suggestion?

3条回答
  •  借酒劲吻你
    2020-12-13 10:46

    I do not know if SignalR is intentioned for working with video stream or not but SignalR is a Hub container between client-to-client client-to-server and server-to-client. If I want a Video-chat why I can not use it as my hub? Anyway SignalR can handle array of bytes too and not only Strings then let try by sending each frame as a byte[] (Stream). At least when I using only .Net I can hub byte[]. When I put in Python then I need to serialize to string with base64 and it is working from my PI too. Put an eye on my lab-solution I push into my GIT. https://github.com/Guille1878/VideoChat

    SignalR Hub (Default, not serverless)

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

    Video-Sender: (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);
    }
    

    Video-receiver: (UWP)

    private async void StreamVideo_Click(object sender, RoutedEventArgs e)
    {
          isStreamingIn = StreamVideo.IsChecked ?? false;
          if (isStreamingIn)
          {
                hubConnection.On("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);
                 }
           }
    }
    

    I am using "SignalR Core"

提交回复
热议问题