首先,为这样一个悬而未决的问题道歉。我认为这个问题源于对WASM和.Net中JSInterop的本质缺乏了解
我只是想联系任何在Blazor中使用过Superpowered Web Audio SDK的人,了解他们是如何使用它的,因为我正在努力使用JSInterop,我觉得我不使用基于Javascript的框架会让事情变得更难。
我已经用C#类设置了一个Blazor客户端web组装项目,它充当了一个非常简单的Javascript文件的接口,用于下载和解码音频文件:
public class AudioTest
{
[Inject]
IJSRuntime js;
DotNetObjectReference<AudioTest> objRef;
protected override void OnInitialized()
{
objRef = DotNetObjectReference.Create(this);
}
public async void DownloadAndDecode(string url)
{
byte[] buffer = await superpoweredModule.InvokeAsync<byte[]>("downloadAndDecode", url, objRef);
Console.WriteLine(buffer.Length);
}
[JSInvokable]
public void ReceiveDecodedBuffer(string url, byte[] buffer)
{
Console.WriteLine(buffer);
}
}
当调用了C#方法DownloadAndDecode((时,它会将自身的引用传递给javascript函数downloadAndDecade((,以便在缓冲区准备好时进行回调:
import { SuperpoweredTrackLoader } from '/superpowered/SuperpoweredTrackLoaderModule.js';
export async function downloadAndDecode(url, dotNetRef) {
SuperpoweredTrackLoader.downloadAndDecode(url, async (message) => {
await dotNetRef.invokeMethodAsync('ReceiveDecodedBuffer', url, message.SuperpoweredLoaded.buffer);
});
}
但是,这会导致在转换base64缓冲区时出现运行时错误。在发送之前,我尝试过从base64转换音频缓冲区(速度太慢(。我也尝试过解组Javascript调用,但它们只支持同步调用。当在C#和JS之间传递时,必须转换缓冲区,反之亦然,这太慢了。
我计划在C#和JS上处理音频缓冲区。但我觉得我应该离开JS,管理那里的缓冲区。有人对此有什么建议吗?或者我应该把它留在Javascript端?或者简单地更改我的设计/方法和框架以支持Superpowered库。
安装.net 6预览6并再次创建我的项目提供了一种在Blazor和JavaScript之间传递大字节[]的快速有效的方法。在没有创建新项目的情况下,返回/发送byte[]时会导致异常行为。
这是我的源代码示例。该代码需要超级强大的Web音频库。ByteArrayTest剃刀
<h3>ByteArrayTest</h3>
<button @onclick="SendNetBytes">Send bytes to javascript</button>
<button @onclick="GetJavaBytes">Get bytes from javascript</button>
<button @onclick="DownloadAndDecode">Download And Decode .mp3</button>
<button @onclick="DownloadAndDecodeUsingCallback">Download And Decode .mp3 Using Callback</button>
@code {
[Inject]
IJSRuntime jsRuntime { get; set; }
IJSObjectReference module;
DotNetObjectReference<ByteArrayTest> objRef;
protected override async Task OnInitializedAsync()
{
objRef = DotNetObjectReference.Create(this);
module = await jsRuntime.InvokeAsync<IJSObjectReference>("import", "/byteArray.js");
}
public async ValueTask DisposeAsync()
{
objRef.Dispose();
await module.DisposeAsync();
}
public async void SendNetBytes()
{
byte[] bytes = new byte[] { 1, 5, 7 };
await module.InvokeVoidAsync("getNetBytes", bytes);
}
public async void GetJavaBytes()
{
byte[] buffer = await module.InvokeAsync<byte[]>("getJavaBytes");
Console.WriteLine(buffer.Length);
foreach (byte b in buffer)
{
Console.WriteLine(b);
}
}
public async void DownloadAndDecode()
{
byte[] buffer = await module.InvokeAsync<byte[]>("downloadAndDecode", "/track.mp3");
Console.WriteLine(buffer.Length);
await module.InvokeVoidAsync("getNetBytes", buffer);
}
public async void DownloadAndDecodeUsingCallback()
{
await module.InvokeVoidAsync("downloadAndDecodeUsingCallback", "/track.mp3", objRef);
}
[JSInvokable]
public async void ReceiveDecodedBuffer(byte[] buffer)
{
Console.WriteLine("Got buffer!");
Console.WriteLine(buffer.Length);
await module.InvokeVoidAsync("getNetBytes", buffer);
}
}
wwwroot/byteArray.js
export function getNetBytes(bytes) {
console.log(bytes);
}
export function getJavaBytes() {
return new Uint8Array([1, 2, 3, 4, 5]);
}
import { SuperpoweredTrackLoader } from '/superpowered/SuperpoweredTrackLoaderModule.js';
export async function downloadAndDecode(url) {
const promise = new Promise((resolve) => {
SuperpoweredTrackLoader.downloadAndDecode(url, async (message) => {
const buffer = new Uint8Array(message.SuperpoweredLoaded.buffer);
resolve(buffer);
});
});
const buffer = await promise;
return buffer;
}
export function downloadAndDecodeUsingCallback(url, dotNetRef) {
SuperpoweredTrackLoader.downloadAndDecode(url, async (message) => {
const buffer = new Uint8Array(message.SuperpoweredLoaded.buffer);
await dotNetRef.invokeMethodAsync('ReceiveDecodedBuffer', buffer);
});
}