免责声明:我熟悉网络技术,但仍然是新手。
场景:我希望用户从本地文件系统中选择一个音频文件。然后我希望在网页上显示一个小的音频控件来播放选择并将音频发送回服务器(单击按钮后)。
问题:使用 MatBlazor FileUpload,我可以获取本地音频文件的流,但我不知道如何将它与 htmlaudio
元素一起使用。具体来说,如何将音频流传递到src
元素中?
在 javascript 中执行此操作的一种明确方法是使用<input type="file"/>
element 然后使用Filereader()
来播放音频。此处显示的内容如下:使用 Filereader.readAsDataURL(),使用 URL.createObjectURL()
如何在 Blazor 中执行此操作,即以正确的方式在浏览器中使用流播放本地音频文件?
当前解决方法:目前,我正在读取流并将音频转换为 base64 字符串,然后将其传递给audio
element。
这种方法的缺点是,对于大约 18 MB 的大型音频文件,转换时间约为 30 秒,并且 UI 一直卡在此之前。如果我在 Interops 中使用 javascript 方式,那么加载时间几乎是瞬时的,但是我必须使用input
元素而不是MatFileUpload
组件。拥有本地文件流的另一个原因是因为我想将此音频文件发送到服务器以进行进一步处理,并且发现使用流可以轻松完成。
我用来将音频流转换为 base64 字符串的代码:
async Task FilesReadyForContent(IMatFileUploadEntry[] files)
{
string base64Audio; // variable defined outside the function to update DOM
bool loadingAudio; // defined outside
try
{
file = files.FirstOrDefault();
if (file == null)
{
base64Audio = "Error! Could not load file";
}
else
{
using (MemoryStream ms = new MemoryStream())
{
loadingAudio = true;
await InvokeAsync(() => this.StateHasChanged());
await file.WriteToStreamAsync(ms);
base64Audio = System.Convert.ToBase64String(ms.ToArray());
loadingAudio = false;
await InvokeAsync(() => this.StateHasChanged());
}
}
}
catch (Exception ex)
{
base64Audio = $"Error! Exception:\r\n{ex.Message}\r\n{ex.StackTrace}";
}
finally
{
await InvokeAsync(() => { this.StateHasChanged(); });
}
}