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

2

8

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?

Renshaw answered 24/5, 2020 at 3:12 Comment(7)
You can forget about using System.Drawing, I'm surprised that even compiles. Is this really Blazor WebAssembly?Goodbye
Yes, its Blazor Web Assembly.Renshaw
Just a guess, but maybe you can hand over the video element with a @ref instead of gettng it again with getElementById(). Although both ought to work.Goodbye
No luck. If I inspect the page in chrome dev tools, it shows the video src as empty. I must not be able to assign the video src directly from the javascript in Blazor.Renshaw
Still weird. All the relevant parts are in JS, Blazor only handles the button click. To be sure, create a pure JS mockup and test in >1 Browsers.Goodbye
Well slap me in the face with a wet fish. Its Chrome! It works in Edge. I guess the final issue is what setting I have to change in Chrome. Javascript is enabled. Ask before access in the camera is set.Renshaw
Thanks soo much for all your help Henk Holterman!!!!!Renshaw
R
1

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.

Renshaw answered 24/5, 2020 at 22:52 Comment(1)
Which version of MS Edge were you using? The new chromium version or the older version of Edge?Allurement
A
5

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();
        });
    }
}
Allurement answered 10/8, 2020 at 14:1 Comment(0)
R
1

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.

Renshaw answered 24/5, 2020 at 22:52 Comment(1)
Which version of MS Edge were you using? The new chromium version or the older version of Edge?Allurement

© 2022 - 2024 — McMap. All rights reserved.