借助Blazor在浏览器运行dotnet代码

本文重点,想看步骤的请直接移步正文

  • 如何精简Blazor的代码,移除界面部分

  • 如何和c#部分交互

  • 如何访问FS部分

  • 打包构建

因为工作上的需要,需要在网页上进行usm格式的视频,但是usm的视频格式并没有相关的说明,导致也没办法和之前一样直接通过读取二进制流的方式解码然后转mp4流喂给<video>

不过业内也都是使用CriDemuxer来对usm视频格式进行解交织的,而且CriDemuxer有开源,只不过代码是基于C#的,所以最后问题变成了,怎么在网页中运行C#代码

碎碎念结束

BLAZOR

目前将c#运行在浏览器端主要靠编译成wasm运行,在net5之前,想让dotnet多端运行就得借助mono进行编译,然后mono有推出过一个mono-wasm0.1的包,可以将编译为wasm可以因为维护的原因,已经下不到了

不过好在微软官方有一个借助mono-wasm的项目 Blazor 来实现用 C# 来构建网页,虽然用不上他的页面功能,但是四舍五入一下,却可以用它来实现在浏览器端运行 C# 代码

实现步骤

安装环境

根据官方教程即可

https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor

创建项目

我们创建一个基于wasmapp


dotnet new blazorwasm -o BlazorApp --no-https

然后项目就创建完了,记住和官方教程不一样,是blazorwasm

dev


cd BlazorApp

dotnet watch run

一个基础项目就起来了,之后开始进行改造

移除页面相关文件

目录

  • pages

  • Shared

文件

  • App.razor

  • _Imports.razor

修改

Program.cs移除` builder.RootComponents.Add("#app");

`这行

这个时候运行,页面上应该就只有一个Loading...了,如果觉得难受,可以修改wwwroot下的index.html文件

编写代码

之后整个项目其实就是一个标准的dotnet项目了,可以直接将编写的代码移动进来,比如我这里就直接把CriDemuxerCore的代码直接移动进来

编写调用代码

Program.cs内注入相关的js入口即可

这样的话,在浏览器内就能调用c#的代码了


using Microsoft.JSInterop;

  

[JSInvokable]

public static async Task<string> Demux(string filePath)

{

if (File.Exists(filePath))

{

MpegStream.DemuxOptionsStruct demuxOptions = new MpegStream.DemuxOptionsStruct();

demuxOptions.ExtractVideo = true;

return await Task.Run(() =>

{

Console.WriteLine("Start");

CriUsmStream criUsmStream = new CriUsmStream(filePath);

return criUsmStream.DemultiplexStreams(demuxOptions)[0];

});

}

else

{

throw new Exception(filePath + " Not exists");

}

}

  

在浏览器中的调用方法


DotNet.invokeMethodAsync('BlazorApp', 'Demux', '具体文件地址'))

参数解释一下

  • DotNet, 全局对象, 会自动注入

  • BlazorApp 创建应用的时候取得名字,主要应该和NameSpace相关

  • Demux 刚刚定义的方法名

文件系统

当然,FS系统也是Blazor内置的


FS.writeFile(file.name, new Uint8Array(fileReader.result)) // 写入

FS.readFile(filePath) // 读取

打包

dotnet publish --configuration Release

之后可以在bin/Release/net5.0/publish/wwwroot/_framework内拿到打包的文件,之后只要将该文件夹copy进项目,加载其中的./_framework/blazor.webassembly.js文件就可以了

几个问题

  1. 打出来的包很大

  2. _framework必须在网站根目录下

第二点可以尝试通过修改blazor.webassembly.js内容来尝试解决