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

# 借助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 (opens new window)

# 创建项目

我们创建一个基于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>("#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内容来尝试解决