Why is it that in some mobile device, I can view the camera stream on both front and back but in some other only the front, the back I cannot. Sometimes, on some other devices, I cannot see both the front and rear camera feed. I am using the same browser, for all devices. If the camera stream is not showing, all I see is a black screen.
I know that my both cameras are working. I came across this website called webcamtests.com I can actually see both of my camera streams (kinda awesome actually I don't know how they did it). What I mean by devices is android devices. All of them are either Android 11 or 13.
This is how I implement the JavaScript
let currentFacingMode = "environment"; // Default to rear camera function startVideo(src) { if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { navigator.mediaDevices.getUserMedia( { video: { facingMode: currentFacingMode } }).then(function (stream) { let video = document.getElementById(src); if ("srcObject" in video) { video.srcObject = stream; } else { video.src = window.URL.createObjectURL(stream); } video.onloadedmetadata = function (e) { video.play(); }; //mirror image video.style.webkitTransform = "scaleX(-1)"; video.style.transform = "scaleX(-1)"; }).catch(function (error) { console.error("Error accessing camera: ", error); alert("Camera not accessible. Please check permissions and ensure the device supports the requested facing mode."); });; } } function toggleCamera() { debugger; if (currentFacingMode === "user") { debugger; currentFacingMode = "environment"; } else { debugger; currentFacingMode = "user"; } stopVideo("videoFeed"); startVideo("videoFeed"); } function getFrame(src, dest, dotNetHelper) { let video = document.getElementById(src); let canvas = document.getElementById(dest); canvas.getContext('2d').drawImage(video, 0, 0, 320, 240); let dataUrl = canvas.toDataURL("image/jpeg"); dotNetHelper.invokeMethodAsync('ProcessImage', dataUrl); } function stopVideo(src) { let video = document.getElementById(src); if (video && "srcObject" in video) { const stream = video.srcObject; if (stream) { const tracks = stream.getTracks(); tracks.forEach(track => { track.stop(); track.enabled = false; }); stream.getTracks().forEach(function (track) { if (track.readyState == 'live'&& track.kind === 'video') { track.stop(); } }); } video.srcObject = null; } }This is my component and code behind in Blazor
@using ITMS_Ver_2.Client.Services@using ITMS_Ver_2.Shared._Entities@using SixLabors.Fonts@using SixLabors.ImageSharp@using SixLabors.ImageSharp.Drawing@using SixLabors.ImageSharp.Drawing.Processing@using SixLabors.ImageSharp.Processing;@using SixLabors.ImageSharp.Formats.Jpeg@using SixLabors.Fonts@using System.Net.Http@using System.IO<MudGrid><MudItem xs="12"><MudPaper Class="d-flex justify-center p-3"><video id="videoFeed" width="320" height="240" /><canvas class="d-none" id="currentFrame" width="320" height="240" /></MudPaper></MudItem><MudItem xs="12"><MudPaper Class="d-flex justify-center p-3 align-center"><MudTextField @bind-Value="captionText" Label="Description" Variant="Variant.Outlined" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Image" AdornmentColor="MudBlazor.Color.Default" Margin="Margin.Dense" InputType="InputType.Text" /></MudPaper></MudItem></MudGrid><br /><MudPaper Class="d-flex justify-content-end p-2" Elevation="0"><MudButton Variant="Variant.Outlined" StartIcon="@Icons.Material.Filled.Camera" IconColor="MudBlazor.Color.Default" Color="MudBlazor.Color.Primary" FullWidth="false" OnClick="CaptureFrame">Take Image</MudButton><MudButton Variant="Variant.Outlined" StartIcon="@Icons.Material.Filled.Camera" IconColor="MudBlazor.Color.Default" Color="MudBlazor.Color.Primary" FullWidth="false" OnClick="ToggleCamera">Switch</MudButton></MudPaper><br />@if (ImageList != null && ImageList.Any()){ foreach (var item in ImageList) {<MudImage Src="@item.ImageString" ObjectFit="ObjectFit.Cover" Width="95" Height="88" Alt="image taken" Elevation="25" Class="rounded-lg m-1" /> }}@code { [Inject] private IJSRuntime? JsRuntime { get; set; } [Inject] private HttpClient? Http { get; set; } [Inject] private ICommonService? CommonService { get; set; } [Parameter] public string? IncidentId { get; set; } [Parameter] public List<IncidentImage>? ImageList { get; set; } private string captionText; private string frameUri; FontCollection collection = new FontCollection(); FontFamily sansFamily; Font captionFont; protected override async Task OnInitializedAsync() { await StartCamera(); } private async Task StartCamera() { await JsRuntime!.InvokeVoidAsync("startVideo", "videoFeed"); //Font stored in wwwroot. Fetch it as byte array, and use it var fontBytes = await Http!.GetByteArrayAsync("OpenSans-Regular.ttf"); collection.Install(new MemoryStream(fontBytes)); collection.TryFind("Open Sans", out sansFamily); captionFont = sansFamily.CreateFont(16, FontStyle.Regular); } private async Task ToggleCamera() { await JsRuntime!.InvokeVoidAsync("toggleCamera"); } private async Task CaptureFrame() { await JsRuntime!.InvokeAsync<String>("getFrame", "videoFeed", "currentFrame", DotNetObjectReference.Create(this)); } [JSInvokable] public void ProcessImage(string imageString) { byte[] imageData = Convert.FromBase64String(imageString.Split(',')[1]); DrawingOptions alignCenter = new DrawingOptions() { TextOptions = new TextOptions() { VerticalAlignment = VerticalAlignment.Center, WrapTextWidth = 304, //Image is 320px wide. This centers with 8px margin on left and right HorizontalAlignment = SixLabors.Fonts.HorizontalAlignment.Center } }; using (var image = SixLabors.ImageSharp.Image.Load(imageData)) { image.Mutate(x => x .Flip(FlipMode.Horizontal) //To match mirrored webcam image .Fill(SixLabors.ImageSharp.Color.ParseHex("0008"), new RectangularPolygon(0, 220, 320, 20)) //Setting footer bar for caption .DrawText(alignCenter, captionText, captionFont, SixLabors.ImageSharp.Color.White, new PointF(8, 230)) //Centering in footer bar) ); frameUri = image.ToBase64String(JpegFormat.Instance); var incidentImage = new IncidentImage { IncidentId = IncidentId, Description = captionText, ImageString = frameUri, TimeTaken = DateTime.Now, FileName = DateTime.Now.ToString("yyyyMMddHHmmss") }; if (ImageList == null) { ImageList = new(); ImageList.Add(incidentImage); } else { ImageList.Add(incidentImage); } captionText = String.Empty; StartCamera(); } }}