如何从 Blazor 调用 javascript 函数并取回数据(网络摄像头应用视频流并保存屏幕截图)?
嗨,我研究了使用 Blazor 和网络摄像头(目标 -> 浏览器中来自 Cam 的视频流//截取流的屏幕截图//将屏幕截图保存到高清)。 我开始的来源是本教程
我让流开始工作,并添加了代码以从视频流中截取屏幕截图,这也可以,但前提是通过“js”按钮调用。从使用的 Javascript 内部:
startbutton.addEventListener('click', function (ev) {
takePic();
ev.preventDefault();
}, false);
我无法弄清楚的要点是:
1. 我想通过 Blazor 的 JS-Interop 调用 js 函数,而不是通过 JavaScript 内部的 Eventlistener。但是我无法为该调用获取正确的代码!?也许答案非常简单,而且是单行的。我对 Javascript 的了解为零(这就是为什么我(必须)使用 Blazor :) )
2.如何将js中的imagedata发回Blazor成byte[]。
我的代码 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");
}
}
我从中得到的错误
公共异步任务 TakePicBzBtn()
在浏览器控制台中:
blazor.server.js:21 [2021-06-04T15:44:42.954Z] 错误:Microsoft.JSInterop.JSException:找不到“takePic”(“takePic”未定义)。错误:找不到“takePic”(“takePic”未定义)。
我几乎复制/粘贴代码 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); }
};
对不起代码墙