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?
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"