Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

it is possible to stream video with SignalR?

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?

like image 840
luis_laurent Avatar asked Oct 22 '12 17:10

luis_laurent


People also ask

What can SignalR be used for?

SignalR can be used to add any sort of "real-time" web functionality to your ASP.NET application. While chat is often used as an example, you can do a whole lot more. Any time a user refreshes a web page to see new data, or the page implements long polling to retrieve new data, it is a candidate for using SignalR.

What platform does SignalR client support?

SignalR can be used in the following browsers: Microsoft Internet Explorer versions 11. Windows only. Microsoft Edge(Chromium).

Does WhatsApp use SignalR?

We now have a functioning SignalR app integrated with Twilio API for WhatsApp.


4 Answers

I implemented video streaming on top of SignalR. You can find my example at http://weblogs.asp.net/ricardoperes/archive/2014/04/24/video-streaming-with-asp-net-signalr-and-html5.aspx.

like image 110
Ricardo Peres Avatar answered Sep 22 '22 06:09

Ricardo Peres


No, SignalR is based on standards (WebSockets, LongPolling, ForeverFrame, etc.) which only stream text based JSON messages. You're probably better off looking into the WebRTC specification. Now, you could bring these two technologies together by sending control messages with SignalR that triggers some JavaScript that changes the WebRTC feed that the browser is currently showing.

like image 26
Drew Marsh Avatar answered Sep 18 '22 06:09

Drew Marsh


Yes, recent versions of SignalR core supports streaming.
Some samples provided by Microsoft.

like image 27
sepehr Avatar answered Sep 22 '22 06:09

sepehr


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<IVideoChatClient> 
    {
        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<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);
             }
       }
}

I am using "SignalR Core"

like image 39
Wille Esteche Avatar answered Sep 22 '22 06:09

Wille Esteche