Blazor Server音频列表:如何实现播放与删除功能?
Blazor Server音频列表功能实现方案
核心功能实现思路
针对点击文件名触发播放/删除操作的需求,采用模态框选择操作 + JSInterop控制音频播放 + 后端文件操作刷新列表的方案,具体实现如下:
1. 前端代码修改(含模态框与音频元素优化)
替换原前端代码,添加操作选择模态框,并为每个音频元素设置唯一ID:
<div class="table-wrapper-scroll-y my-custom-scrollbar"> <table class="table table-bordered table-striped mb-0"> <tbody> @if (filesList != null && filesList.Count > 0) { int auF = 0; @foreach (string file in filesList) { auF++; <tr> <td> <span>@auF.</span> <span @onclick="() => ShowFileActionModal(file)" style="cursor:pointer; text-decoration: underline; color: blue;">@file</span> </td> <td> <audio controls="controls" id="@($"audio-{file}")"> <source src="@GetAudioFileUrl(file)"> </audio> </td> </tr> } } else { <tr> <td colspan="2">No Files</td> </tr> } </tbody> </table> </div> <!-- 操作选择模态框 --> <div class="modal fade" id="fileActionModal" tabindex="-1" aria-labelledby="fileActionModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="fileActionModalLabel">操作选择</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> 请选择对 <strong>@currentFileName</strong> 的操作: </div> <div class="modal-footer"> <button type="button" class="btn btn-primary" @onclick="PlaySelectedAudio" data-bs-dismiss="modal">播放音频</button> <button type="button" class="btn btn-danger" @onclick="DeleteSelectedFile" data-bs-dismiss="modal">删除文件</button> </div> </div> </div> </div>
2. 后端代码修改(含文件操作与JSInterop调用)
注入必要服务,实现模态框控制、音频播放、文件删除与列表刷新:
@inject IJSRuntime JSRuntime @inject IWebHostEnvironment WebHostEnv @code{ List<string> filesList = new List<string>(); string audioFolderPath; string currentFileName; protected override void OnInitialized() { // 推荐将音频文件夹放在wwwroot下,简化前端访问 audioFolderPath = Path.Combine(WebHostEnv.WebRootPath, "audio"); // 若需保留原路径,替换为: // audioFolderPath = Path.Combine(Directory.GetCurrentDirectory(), "path"); LoadAudioFiles(); } // 加载音频文件列表 void LoadAudioFiles() { filesList.Clear(); if (Directory.Exists(audioFolderPath)) { var files = Directory.GetFiles(audioFolderPath) .Select(Path.GetFileName) .ToList(); filesList.AddRange(files); } } // 显示操作选择模态框 async Task ShowFileActionModal(string fileName) { currentFileName = fileName; await JSRuntime.InvokeVoidAsync("bootstrap.Modal.getOrCreateElement", "#fileActionModal").InvokeVoidAsync("show"); } // 获取音频文件的前端访问URL string GetAudioFileUrl(string fileName) { // 音频在wwwroot/audio下的情况 return $"/audio/{Uri.EscapeDataString(fileName)}"; // 音频不在wwwroot时,需配合API控制器使用: // return $"/api/audio/{Uri.EscapeDataString(fileName)}"; } // 播放选中的音频 async Task PlaySelectedAudio() { if (!string.IsNullOrEmpty(currentFileName)) { var audioElementId = $"audio-{currentFileName}"; await JSRuntime.InvokeVoidAsync("playAudio", audioElementId); } } // 删除选中的文件并刷新列表 async Task DeleteSelectedFile() { if (!string.IsNullOrEmpty(currentFileName)) { var fullFilePath = Path.Combine(audioFolderPath, currentFileName); try { if (File.Exists(fullFilePath)) { File.Delete(fullFilePath); LoadAudioFiles(); StateHasChanged(); // 通知UI更新 } } catch (Exception ex) { await JSRuntime.InvokeVoidAsync("alert", $"删除失败:{ex.Message}"); } } } }
3. 补充JS代码(控制音频播放)
在_Host.cshtml或组件底部添加以下脚本:
<script> function playAudio(elementId) { const audioElement = document.getElementById(elementId); if (audioElement) { audioElement.play().catch(err => console.error('播放失败:', err)); } } </script>
关键注意事项
- 音频路径处理:
- 优先将音频文件夹放在
wwwroot/audio下,前端可直接通过相对路径访问。 - 若必须使用非wwwroot路径,需创建API控制器返回文件流(示例代码如下):
[ApiController] [Route("api/[controller]")] public class AudioController : ControllerBase { private readonly string _audioPath = Path.Combine(Directory.GetCurrentDirectory(), "path"); [HttpGet("{fileName}")] public IActionResult GetAudio(string fileName) { var filePath = Path.Combine(_audioPath, fileName); if (!File.Exists(filePath)) return NotFound(); var contentType = Path.GetExtension(fileName).ToLowerInvariant() switch { ".mp3" => "audio/mpeg", ".wav" => "audio/wav", ".ogg" => "audio/ogg", _ => "application/octet-stream" }; return File(System.IO.File.OpenRead(filePath), contentType); } }
- 优先将音频文件夹放在
- Bootstrap依赖:确保项目已引入Bootstrap 5的CSS与JS文件,以支持模态框功能。
内容的提问来源于stack exchange,提问作者Addlon
相关产品推荐
相关产品推荐

