How to call a javascript function from Blazor and get data back (webcam-App videostream and save screenshot)?
Hi, I looked into working with Blazor and webcam (goal -> videostream from Cam in browser // take a screenshot of stream // save screenshot to Hd). My Source to start was this tutorial
I go the stream to work and I added the code to take a screenshot from the videostream, that works too, but only if called via a 'js'-button. From inside the used Javascript:
startbutton.addEventListener('click', function (ev) {
takePic();
ev.preventDefault();
}, false);
The points I can't figure out is:
1. I want to call the js-function via JS-Interop from Blazor and not via Eventlistener from inside the JavaScript. But I cant get the code right for that call!? Maybe the answere is super simple and a oneliner. I have Zero knowledge of Javascript (that is why I (have to) use Blazor :) )
2. How to get the imagedata from js send back to Blazor into a byte[].
My Code Blazor/RazorPage:
@page "/"
@*https://www.youtube.com/watch?v=5Uth1wXRil4*@
@using Data
@inject IJSRuntime JSRuntime
<h1>Fun Blazor Web Camera Application</h1>
<div>
<canvas id="@options.CanvasID"
style="background-color:lightgray;"
width="@options.Width"
height="360">
</canvas>
</div>
<div>
<button @onclick="Start">Start</button>
</div>
<div>
<video id="@options.VideoID"
style="background-color:white ; visibility:hidden;"
width="@options.Width">
Video stream not available.
</video>
</div>
<div class="output">
<img id="photo" alt="The screen capture will appear in this box.">
</div>
<canvas id="canvasPic"></canvas>
@*JS Button*@
<button id="startbutton" class="btn btn-primary">TakePic JS Event</button>
@*Blazor Button*@
<button class="btn btn-primary" @onclick="TakePicBzBtn">TakePic BZ Btn</button>
@code{
WebCamOptions options = new WebCamOptions()
{
CanvasID = "canvas",
VideoID = "video"
};
protected override void OnInitialized()
{
options.Filter = "contrast(1.4) sepia(0.2) blur(0px) saturate(100%) hue-
rotate(0deg)";
options.Width = 480;
}
public async Task Start()
{
await JSRuntime.InvokeVoidAsync("WebCamFunctions.start", options);
}
public async Task TakePicBzBtn()
{
await JSRuntime.InvokeVoidAsync("takePic");
}
}
The error I get from the
public async Task TakePicBzBtn()
In browser Console:
blazor.server.js:21 [2021-06-04T15:44:42.954Z] Error: Microsoft.JSInterop.JSException: Could not find 'takePic' ('takePic' was undefined). Error: Could not find 'takePic' ('takePic' was undefined).
My nearly copy/paste Code JS:
let video = null;
let canvas = null;
let context = null;
let streaming = false;
let width = 100; // We will scale the photo width to this.
let height = 0; // This will be computed based on the input stream
let filter = 'sepia(1)';
let photo = null;
let startbutton = null;
function onStart(options) {
video = document.getElementById(options.videoID);
canvas = document.getElementById(options.canvasID);
startbutton = document.getElementById('startbutton');
photo = document.getElementById('photo');
context = canvas.getContext('2d');
width = options.width;
filter = options.filter;
navigator.mediaDevices.getUserMedia({ video: true, audio: false })
.then(function (stream) {
video.srcObject = stream;
video.play();
})
.catch(function (err) {
console.log("An error occurred: " + err);
});
video.addEventListener('canplay', function () {
if (!streaming) {
height = video.videoHeight / (video.videoWidth / width);
if (isNaN(height)) {
height = width / (4 / 3);
}
video.setAttribute('width', width);
video.setAttribute('height', height);
canvas.setAttribute('width', width);
canvas.setAttribute('height', height);
streaming = true;
}
}, false);
video.addEventListener("play", function () {
console.log('play');
timercallback();
}, false);
startbutton.addEventListener('click', function (ev) {
takePic();
ev.preventDefault();
}, false);
clearphoto();
}
function timercallback() {
if (video.paused || video.ended) {
return;
}
computeFrame();
setTimeout(function () {
timercallback();
}, 0);
}
function computeFrame() {
context.drawImage(video, 0, 0, width, height);
context.filter = filter;
}
function takePic() {
var context = canvas.getContext('2d');
if (width && height) {
canvas.width = width;
canvas.height = height;
context.drawImage(video, 0, 0, width, height);
var data = canvas.toDataURL('image/png');
photo.setAttribute('src', data);
} else {
clearphoto();
}
}
function clearphoto() {
var context = canvas.getContext('2d');
context.fillStyle = "#AAA";
context.fillRect(0, 0, canvas.width, canvas.height);
var data = canvas.toDataURL('image/png');
photo.setAttribute('src', data);
}
window.WebCamFunctions = {
start: (options) => { onStart(options); }
};
Sorry for the wall of Code
Try this:
In your Project
In your index.html file
Remember: your script file before tag
<script src="_framework/blazor.webassembly.js"></script>