Возможно ли потоковое видео с SignalR?
Ну, я пытаюсь выполнить доказательство потокового видео, я работаю с asp.net C#. Я отчасти заблудился, у вас есть идея или предложение?
4 ответа
Нет, SignalR основан на стандартах (WebSockets, LongPolling, ForeverFrame и т. Д.), Которые транслируют только текстовые сообщения JSON. Возможно, вам лучше изучить спецификацию WebRTC. Теперь вы можете объединить эти две технологии, отправив управляющие сообщения с помощью SignalR, который запускает некоторый JavaScript, который изменяет ленту WebRTC, которую в настоящее время показывает браузер.
Я реализовал потоковое видео поверх SignalR. Вы можете найти мой пример по адресу http://weblogs.asp.net/ricardoperes/archive/2014/04/24/video-streaming-with-asp-net-signalr-and-html5.aspx.
Да, последние версии ядра SignalR поддерживают потоковую передачу .
Некоторые образцы предоставлены корпорацией Майкрософт.
Я не знаю, предназначен ли SignalR для работы с видеопотоком или нет, но SignalR - это контейнер-концентратор между клиент-клиентом, клиент-сервер и сервер-клиент. Если я хочу видеочат, почему я не могу использовать его как хаб? В любом случае SignalR может обрабатывать массив байтов, а не только строки, тогда пусть попробует, отправив каждый кадр как byte[] (Stream). По крайней мере, когда я использую только.Net, я могу концентрировать byte[]. Когда я вставляю Python, мне нужно сериализовать его в строку с помощью base64, и он также работает с моим PI. Обратите внимание на свой лабораторный раствор, который я ввожу в ЖКТ. 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 Core"