【问题标题】:Pass large JS blob to Blazor byte[]将大型 JS blob 传递给 Blazor byte[]
【发布时间】:2021-07-14 03:06:10
【问题描述】:

我需要录制一些音频,甚至可能是视频,在 JS 中使用 Media API,在 Blazor 中使用 example。然后,我想将录制的 Blob 内容从 JS 传递到 Blazor。就音频或视频内容而言,它可能非常大。

到目前为止我已经尝试过什么

  1. 将数据编码为ANSI 字符串或传递整数数组。这导致InvalidDataException,SignalR 断开连接,超时,大约一分钟后 SignalR 恢复正常,C# 接收到null

  2. 将数据编码为base 64 或传递UInt8Array。结果是一样的。

  3. 直接从 JS 传递 BlobArrayBufferFormData。这会在 C# 中产生空对象 ValueKind: {}

JS调用的来源

recorder.stop();
recorder.exportWAV(async blob => {
  const content = await (new Response(blob).arrayBuffer());
  const contentNums = new Uint8Array(content);
  const contentCodes = new TextDecoder('windows-1252').decode(contentNums);
  const data = new FormData();
  data.append('file', blob, 'Demo');
  //success(window.URL.createObjectURL(blob));
  console.log(blob)
  console.log(content)
  console.log(contentNums)
  console.log(contentCodes)
  success(Array.from(contentNums));
})

C#互操作调用的来源

private IJSRuntime _scriptRuntime = null;

public async Task<dynamic> GetMedia<dynamic>()
{
  return await _scriptRuntime.InvokeAsync<dynamic>('AudioFunctions.GetMediaFile');
}

有没有办法将大字节数组或至少是字符串从 JS 传递到 Blazor.NET?

【问题讨论】:

    标签: blazor blazor-server-side


    【解决方案1】:

    看来,使用 ANSI 编码的 hack 工作正常,我只需要增加 SignalR 消息的大小。

    启动

    public void ConfigureServices(IServiceCollection services)
    {
      // ... some other services
    
      services.AddSignalR(o =>
      {
        o.EnableDetailedErrors = true;
        o.MaximumReceiveMessageSize = long.MaxValue;
      });
    }
    

    JS 互操作

    window.InteropFunctions = window.InteropFunctions || {
    
      GetMediaFile: async (classInstance, cssClass) => {
    
        return await new Promise((success, error) => {
    
          const chunks = [];
          const recorder = new MediaRecorder(stream, { mimeType: 'audio/webm' });
    
          // Event handlers for play and stop to detect when data is available
    
          recorder.addEventListener('stop', {
    
            // Encode data as ANSI string - Windows 1252 
    
            const response = new Blob(chunks, { type: 'audio/webm' });
            const content = await (new Response(response).arrayBuffer());
            const contentNums = new Uint8Array(content);
            const contentCodes = new TextDecoder('windows-1252').decode(contentNums);
            const audioControl = document.querySelector('.' + cssClass + ' audio');
    
            // Play audio in HTML 5 control
    
            if (audioControl) {
              audioControl.src = URL.createObjectURL(response);
            }
    
            // Resolve the promise and send data to Blazor.NET
    
            success(contentCodes);
          });
    
          // Grab recorded data
          
          recorder.addEventListener('dataavailable', {
            if (e.data.size > 0) {
              chunks.push(e.data);
            }
          });
          
          // Record for 5 seconds
          
          recorder.start();      
          setTimeout(() => recorder.stop(), 5000);
        });
      }
    }
    

    C# 互操作

    private IJSRuntime _scriptRuntime = null;
    
    public async Task<string> GetMediaFile<string>(params object[] inputs)
    {
      return await _scriptRuntime.InvokeAsync<string>('InteropFunctions.GetMediaFile', inputs);
    }
    

    从 .NET 发起互操作调用

    var instance = DotNetObjectReference.Create(this);
    var source = await _audioCommandInstance.GetMediaFile(instance, 'audio-container');
    
    if (string.IsNullOrEmpty(source) == false)
    {
      var audioBytes = Encoder.GetBytes(source);
      
      await File.WriteAllBytesAsync("audio.wav", audioBytes);
    }
    

    【讨论】:

      猜你喜欢
      • 2017-10-24
      • 2023-03-20
      • 2021-01-13
      • 1970-01-01
      • 2018-08-11
      • 2013-09-12
      • 1970-01-01
      • 2020-09-11
      • 2021-01-18
      相关资源
      最近更新 更多