Skip to content
Document DB v7.1: Temporal Support, Telemetry Collection, & Orleans Storage Providers! Feed The Machine Here

CameraView on Blazor

Shiny.Blazor.Controls.Camera brings the CameraView to Blazor WebAssembly using the browser’s getUserMedia / MediaRecorder / BarcodeDetector APIs. All frame analysis runs in JavaScript — only flat, named DTOs (CameraBarcode, CameraOverlayBox) cross the interop boundary — so the camera stays fast and trim-safe.

  • NuGet downloads for Shiny.Blazor.Controls.Camera
Terminal window
dotnet add package Shiny.Blazor.Controls.Camera
@using Shiny.Blazor.Controls.Camera
@using Shiny.Controls.Camera

getUserMedia requires a secure context — HTTPS, or localhost during development.

<div style="position:relative;width:100%;max-width:480px;aspect-ratio:3/4;">
<CameraView @ref="camera"
Facing="CameraFacing.Back"
EnableBarcode="true"
ShowOverlay="true"
Filter="filter"
BarcodeDetected="OnBarcode"
OnError="msg => status = msg"
Style="width:100%;height:100%;" />
</div>
<button @onclick="Capture">Photo</button>
<button @onclick="ToggleRecording">@(recording ? "Stop" : "Record")</button>
<select @bind="filter">
@foreach (var f in Enum.GetValues<CameraFilter>())
{
<option value="@f">@f</option>
}
</select>
@code {
CameraView? camera;
CameraFilter filter = CameraFilter.None;
bool recording;
string? status;
void OnBarcode(CameraBarcode code)
=> status = $"{code.Format}: {code.Value}"; // code.X/Y/W/H are normalized 0..1
async Task Capture()
{
var jpeg = await camera!.CapturePhotoAsync(); // byte[]
// ... use the JPEG bytes ...
}
async Task ToggleRecording()
{
if (!recording) { await camera!.StartRecordingAsync(); recording = true; }
else { var webm = await camera!.StopRecordingAsync(); recording = false; } // byte[] (WebM)
}
}
ParameterTypeDefaultDescription
FacingCameraFacingBackFront maps to the browser "user" facing mode
EnableBarcodebooltrueRun the in-browser barcode detector
ShowOverlaybooltrueDraw overlay boxes on the overlay canvas
AutoStartbooltrueStart the preview on first render
FilterCameraFilterNoneLive CSS filter on the <video> element
CssClass / Stylestring?nullHost element styling
BarcodeDetectedEventCallback<CameraBarcode>A barcode was decoded (Format, Value, normalized box)
OverlaysChangedEventCallback<IReadOnlyList<OverlayBox>>Latest styled overlay boxes (presentation only)
OnErrorEventCallback<string>Camera could not start (permission, no device, insecure context)

StartAsync() · StopAsync() · CapturePhotoAsync() → JPEG byte[] · StartRecordingAsync(includeAudio = true) · StopRecordingAsync() → WebM byte[].

  • Barcode scanning uses the native BarcodeDetector — available in Chromium browsers (Chrome / Edge). On unsupported browsers (Firefox / Safari) the component raises OnError once and the preview keeps running; slot in a ZXing-js fallback if you need universal coverage.
  • Filters map to CSS filter strings, so they work in every browser (temperature filters are approximate — CSS has no true white balance).
  • Recording uses MediaRecorder; output is typically WebM.

For barcode generation/rendering (as opposed to scanning), see Barcodes & QR Codes.