Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Displaying the local machine camera feed in a Blazor Web Assembly app

I've distilled my issue down to a boilerplate Blazor Web Assembly app.

The project is straight out of the wizard, with the below code added.

  1. I've changed the Index.razor page to this:
@page "/"
@inject IJSRuntime JSRuntime;
@using System.Drawing;
@using System.IO;

<div>
    <h1>Video Test</h1>
</div>

<video id="video" width="640" height="480" autoplay></video>

<div>
    <button type="button" class="btn btn-primary" @onclick="StartVideo">Click Me</button>
</div>


@code {

    async Task StartVideo()
    {
        await JSRuntime.InvokeVoidAsync("startVideo");
    }

}

I have a JavaScript page attached like this:

function startVideo() {
    alert("Test Alert!");

    var video = document.getElementById('video');

    if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices.getUserMedia({ video: true }).then(function (stream) {
            video.src = window.URL.createObjectURL(stream);
            video.srcObject = stream;
            video.play();
        });
    }
}

The app compiles without issue. When I run it and click the button I get the alert. I added to alert to confirm the Java Script was actually being run.

The Chrome browser asks for permission to use my webcam, which I grant.

My webcam activates, (my computer has an indicator light to display when the cam is active).

However, nothing shows up on the page. I'm guessing its something straightforward with binding my camera stream to the tag. In my next iteration, I will be taking snapshots of the video feed. For the moment, I only want the feed displayed on the page.

Do I have to route the binding through the C# code block, or can I, as I have done here? Bind the Javascript directly to the HTML element?

like image 359
Newbee Avatar asked May 24 '20 03:05

Newbee


2 Answers

I believe you are having problems in chromium based browsers because createObjectURL was deprecated. All you need for Chrome and the new MS Edge browser (that uses chromium) are the lines containing the srcObject and play. I tested the below code in Chrome, Firefox, and the new Edge.

function startVideo() {
    alert("Test Alert!");

    var video = document.getElementById('video');

    if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices.getUserMedia({ video: true }).then(function (stream) {
            try {
                video.srcObject = stream;
            } catch (error) {
                video.src = window.URL.createObjectURL(stream);
            }
            video.play();
        });
    }
}
like image 128
TheBinaryCPA Avatar answered Nov 15 '22 03:11

TheBinaryCPA


The problem was using Chrome.

It worked without issue in MS Edge.

I tried the same code on a plain HTML page, with no Blazor elements included and got the same result. It is being caused by a setting in my Chrome browser, or on my laptop system settings.

To answer the question. No, the binding doesn't have to go through the c# code. The javascript can directly connect to the HTML.

like image 22
Newbee Avatar answered Nov 15 '22 03:11

Newbee