BlazorCameraStreamer 4.0.0

📷 BlazorCameraStreamer

Nuget BlazorCameraStreamer Build Status

A Blazor Component library that adds a simple to use camera-streaming functionality which you can use with C#.

Features

  • Stream cameras in a html <video> element
  • Retrieve each frame of the stream on a callback (as data-url or bytes, in png, jpeg or webp format, with an optional frame rate limit)
  • Get a list of all avaliable cameras (including whether it's a front or rear camera, if the browser reports it)
  • Prefer the front or rear camera (e.g. on phones)
  • Ask the user for access to cameras
  • Get the currently streamed frame

The library works only with video-devices, there's no support for audio devices (at least for now)

💡 Want a new feature to be implemented, or you found/have any issues? Create a new Issue.

Examples

Implementations of the library can be found in the following projects:

Browser Support

The component works both on Serverside and WASM Blazor.

It requires .NET 8 or newer. For .NET 6 and .NET 7, use version 3.x of the package (dotnet add package BlazorCameraStreamer --version 3.0.1).

Installation Guide

Download and install the nuget package

Open the command line and go into the directoy where your .csproj file is located, then execute this command:

dotnet add package BlazorCameraStreamer

Or add it in the GUI of Visual Studio 20XX:
Tools -> Nuget Package Manager -> Manage Nuget Packages for Solution...

Reference the script in your project

Then add the following <script> tag in your project:

<script src="_content/BlazorCameraStreamer/js/CameraStreamer.js"></script>

Depending on your type of project, the file you have to add this is either

  • wwwroot\index.html - Webassembly
  • Pages\_Host.cshtml - Serverside

It doesn't really matter if you add the tag in the <head> or <body> block.

If you're unsure on where to put it, look it up in the Examples listed above.

Serverside Image-Size Restriction

⚠️ This step is crucial if you want to use the CameraStreamer on ServerSide Blazor ⚠️

The data from the JavaScript-Interop is sent through SignalR to the Server, where your C# Code handles the received data. SignalR has a image cap of 32KB (which is tiny, smaller than 150x150 pixels).

This restriction can be bypassed though. In your [ProjectName].Startup.ConfigureServices method, change the following line:

services.AddServerSideBlazor()
        .AddHubOptions(o => o.MaximumReceiveMessageSize = 100_000_000); // add this

The MaximumReceiveMessageSize value indicates the maximum allowed number of bytes that can be sent through SignalR. It could also be set to long.MaxValue, to entirely max out the restriction.

100'000'000 has no significant meaning, it's just a general cap. As an example, a 3-Channel 8-Bit 1920x1080 image has the following size: 3 * 1920 * 1080 = 6'220'800 Bytes (this calculation does not take image-compression into account).

⚠️ BlazorCameraStreamer can be used in ServerSide Blazor. In general though, it is not recommended to use on ServerSide, since a lot of data is sent through SignalR which can cause network delays. There is a reason, why Microsoft set the default limit to only 32KB. ⚠️

How to use

There are lots of ways to use the CameraStreamer component. All features should be well-documented in the code, so you should have no issues with finding out what each features does.

A implementation of the component can be as simple as this:

<CameraStreamer Autostart />

The component automatically selects the first avaliable camera and uses it for the stream. The Autostart parameter lets the stream start every time the component is loaded.


If you want a to use most of the features of the component, it would look more like this:

Code

<CameraStreamer @ref="CameraStreamerReference"
                Width="1920"
                Height="1080"
                OnRendered="OnRenderedHandler"
                OnFrame="OnFrameHandler"
                Style="width: 480px; height: 270px;"
                CameraID="@cameraId"
                FacingMode="CameraFacingMode.Environment"
                Autostart />

And here's the C# code:

CameraStreamer CameraStreamerReference;

string cameraId = null;

private async Task OnRenderedHandler()
{
    // With Autostart, the stream is already started at this point
    // (the browser asked the user for the camera access if needed)
    MediaDeviceInfoModel[] cameras = await CameraStreamerReference.GetCameraDevicesAsync();

    // Without Autostart, ask for the camera access and start the stream manually
    /* if (await CameraStreamerReference.GetCameraAccessAsync())
        await CameraStreamerReference.StartAsync(); */
}

private void OnFrameHandler(string data)
{
    // Remove the suffix added by javascript
    data = data[(data.IndexOf(',') + 1)..];

    // Convert the base64 string to a System.Drawing.Bitmap
    Bitmap bmp = new(new MemoryStream(Convert.FromBase64String(data)));

    // Do something with the bitmap
}

Explanation

Width and Height

These two parameters specify the resolution of the stream - NOT the display size on the site. The standard size is set to 360p/nHD (640x360).

OnRendered

As soon as the component is completely rendered, this callback is invoked - although only on the first render of the instance. If Autostart is set, it's invoked after the stream is started.

Note: In versions before 4.0, the camera access had to be checked and the component reloaded (ReloadAsync()) in this callback. This is no longer needed, Autostart asks for the access itself.

OnFrame

This is one of the key features of the component that other similar components lack. On each Frame of the stream, this callback is invoked with the base64 string of the image. You can easily convert this data to a System.Drawing.Bitmap by using the following code (keep in my that you need to have the System.Drawing.Common package install):

Bitmap bmp = new(new MemoryStream(Convert.FromBase64String(data)));

You can then do anything with this Bitmap object. E.g. use the object to decode barcodes.

The data is a data-url (e.g. data:image/png;base64,...), so it can also be used directly as src of an <img> element. A new frame is only captured after the callback of the previous one completed, so if your callback takes longer than a frame, frames are skipped instead of piling up.

OnFrameData

Works like OnFrame, but the callback receives the image as bytes instead of a base64 string, which is faster (especially on ServerSide Blazor, as less data is sent through SignalR). The CameraFrame also contains the ContentType and the size of the image:

private void OnFrameDataHandler(CameraFrame frame)
{
    Bitmap bmp = new(new MemoryStream(frame.Data));
}

FrameRate

The maximum number of frames per second for the OnFrame and OnFrameData callbacks. If it's not set, every frame of the stream is captured (as long as your callback keeps up).

FrameFormat and FrameQuality

The image format of the captured frames: CameraFrameFormat.Png (default, lossless), CameraFrameFormat.Jpeg or CameraFrameFormat.Webp. Jpeg and Webp are a lot smaller and faster to encode, and their quality can be set with FrameQuality (between 0 and 1). Browsers that don't support a format fall back to png, the actual format is always part of the frame (the data-url prefix or CameraFrame.ContentType).

Style (Id & Class)

The component also supports the standard Style, Id and Class parameters. They are applied directly on the <video> element in the component (the only element the component has) so they should function very well.

In the code above I use the Style parameter to set the display size of the stream.

CameraID

This is the deviceId that is used by default if no other id is specified (otherwise the deviceId is given as a parameter with the StartAsync() method.

FacingMode

The preferred direction of the camera, e.g. CameraFacingMode.Environment for the rear camera or CameraFacingMode.User for the front camera of a phone. It's only used if no camera-id is specified, and if the device has no camera facing this direction (e.g. a laptop), another camera is used. Changes to this parameter are applied on reload.

Autostart

This parameter starts the stream on Reload automatically. This is either triggered when the component is rendered or the ReloadAsync() method is called.


If you dont want to use the OnFrame-Callback, you can receive frames individually by calling the GetCurrentFrameAsync-Method:

string imageData = await CameraStreamerReference.GetCurrentFrameAsync();

To let the user choose a camera, you can get a list of all cameras with the GetCameraDevicesAsync-Method and switch to one with ChangeCameraAsync:

MediaDeviceInfoModel[] cameras = await CameraStreamerReference.GetCameraDevicesAsync();

await CameraStreamerReference.ChangeCameraAsync(cameras[0].DeviceId);

Each camera has a DeviceId, a Label (its name) and a FacingMode. Keep in mind that browsers only provide the names and ids after the user granted access to the camera (see GetCameraAccessAsync). The FacingMode is null if the browser doesn't report it, which is usually the case for desktop webcams and in browsers that don't support it (e.g. Firefox).

No packages depend on BlazorCameraStreamer.

Breaking:

  • Requires .NET 8 or newer (.NET 9 uses the .NET 8 build). .NET 6 and .NET 7 are no longer supported, use version 3.x for those.

New:

  • FacingMode parameter to prefer the front or rear camera, and the facing mode of each camera in GetCameraDevicesAsync (if the browser reports it).
  • Frames are captured on every frame of the video instead of about 4 times per second.
  • OnFrameData callback, which receives the frames as bytes (faster than the base64 string of OnFrame).
  • FrameRate, FrameFormat (png, jpeg, webp) and FrameQuality parameters.

Changed:

  • Autostart asks for the camera access itself. Checking the access and calling ReloadAsync in OnRendered is no longer needed.
  • StartAsync and ChangeCameraAsync complete when the stream is started.
  • OnFrame is invoked up to the frame rate of the camera (use FrameRate to limit it). A new frame is only captured after the previous callback completed.
  • GetCurrentFrameAsync always captures a new frame, in the format set by FrameFormat.

Fixed:

  • Captured frames were cropped in portrait mode on mobile devices (#42).
  • The camera stayed in use for several seconds after stopping (#43).
  • OverconstrainedError when starting without a camera id before the access was granted (#37, #34).
  • ChangeCameraAsync restarted the stream even if the camera didn't change.
  • Errors when closing the tab on Blazor Server.

Version Downloads Last updated
4.0.0 2 09/28/2026
3.0.1 17 02/17/2026
3.0.0 15 02/17/2026
2.2.0 14 02/17/2026
2.1.2 15 02/17/2026
2.1.1 14 02/17/2026
2.1.0 14 02/17/2026
2.0.3 15 02/13/2026
2.0.1 14 02/17/2026
2.0.0 14 02/17/2026
1.3.0 14 02/17/2026
1.2.0 14 02/17/2026
1.1.0 15 02/17/2026
1.0.0 14 02/17/2026