Home > Blockchain >  How to select an audio file from a table by the name of the file , such that only one main audio ele
How to select an audio file from a table by the name of the file , such that only one main audio ele

Time:11-11

I'm making a table where files are loaded on in the browser. I want to select a file from the table by clicking on its file name, so that the audio element plays the selected files audio.

Right now I have a loop that goes through all files within a dirtectory, and shows the file names in the table cells on the left side. In the cells on the right side of the table there are multiple playable audio elements that correspond to the files whom have the name of the cells on the left side.

Here is the table:

<div >
<table >
    <tbody>  
        @if (filesList != null && filesList.Count > 0)
            {
                int auF = 0;
                @foreach (string file in filesList)
                {    auF  ;
                     <tr> 
                         <td>
                             <span>@auF.</span>
                             <span @onclick="@(e=>readFile(file))" style="cursor:pointer;">@file</span>
                             </td> <td>
                             <audio controls="controls">
                                 <source src="@file">
                             </audio>
                        </td> 
                     </tr>
                }
            }
        else
        {
            <tr>
                <td>No files</td>
            </tr>
        }
    </tbody>
</table>

code:

@code{
List<string> filesList = new List<string>();
string path = $"{Directory.GetCurrentDirectory()}{@"\path"}";

protected override void OnInitialized()
{
    var files = Directory.GetFiles(path);
    foreach (var file in files)
    {
        filesList.Add(Path.GetFileName(file));
    }
}

public void readFile(string fileName)
{
}
}

How would I be able to have only one main audio element outside the table, such that when I select a file name,the audio element can play that selected audio?

CodePudding user response:

To be able to use only one HTML audio player, you will need to create a custom component to include the audio element and perform the necessary logic whenever an audio file is selected from the table which include the following:

  1. Resetting the audio player
  2. Updating the audio src with the current URL of the selected audio
  3. Autoplay the audio file

MyAudioPlayer Component:

<audio @key="@(audioId)" controls autoplay>
    <source src="@Url">
    Your browser does not support the html audio tag.
</audio>

@code {
    private string Url { get; set; }
    private Guid audioId = Guid.NewGuid();

    public void Reload(string url)
    {
        audioId = Guid.NewGuid(); // reload the player
        Url = url;
        InvokeAsync(StateHasChanged);
    }
}

Note:

  • Don't forget to include the namespace of the component in the page.
  • Store the audio files in wwwroot folder as web assets eg. inside wwwroot\audio\ so that the audio player can access them by their url.
  • Create a class eg. AudioFile to store the audio file properties such as the last modified date and file size to display in table.

Implementation:

@page "/"
@using BlazorApp1.Components
@inject IWebHostEnvironment env

<MyAudioPlayer @ref="myAudioPlayer"/>

<table >
    <thead>
    <tr>
        <th scope="col">#</th>
        <th scope="col">Name</th>
        <th scope="col">Last Modified</th>
        <th scope="col">Size</th>
    </tr>
    </thead>
    <tbody>
    @if (audioList.Count > 0)
    {
        @foreach (var file in audioList)
        {
            <tr>
                <td>@(audioList.IndexOf(file)   1)</td>
                <td>
                    <a @onclick="@(() => myAudioPlayer.Reload(file.Url))"
                       
                       role="button">
                        @file.Name
                    </a>
                </td>
                <td>@file.LastModified.ToString("dd-MMM-yyyy HH:mm")</td>
                <td>@FileSizeFormatter.FormatSize(file.Length)</td>
            </tr>
        }
    }
    else
    {
        <tr>
            <td>No files</td>
        </tr>
    }
    </tbody>
</table>
@code{
    MyAudioPlayer myAudioPlayer;
    readonly List<AudioFile> audioList = new();
    readonly string audioFolderName = "audio";

    protected override void OnInitialized()
    {
        var path = $"{env.WebRootPath}\\{audioFolderName}\\";
        var d = new DirectoryInfo(path);
        var files = d.GetFiles();

        foreach (var file in files)
        {
            audioList.Add(new AudioFile
            {
                Name = file.Name,
                Url = $"/audio/{file.Name}",
                Length = file.Length,
                LastModified = file.LastWriteTime
            });
        }
    }

    public class AudioFile
    {
        public string Name { get; set; }
        public string Url { get; set; }
        public long Length { get; set; }
        public DateTime LastModified { get; set; }
    }

    public static class FileSizeFormatter
    {
        static readonly string[] suffixes = { "Bytes", "KB", "MB", "GB", "TB", "PB" };

        public static string FormatSize(long bytes)
        {
            var counter = 0;
            decimal number = bytes;
            while (Math.Round(number / 1024) >= 1)
            {
                number = number / 1024;
                counter  ;
            }
            return $"{number:n1}{suffixes[counter]}";
        }
    }
}

Demo: Blazor audio element demo

  • Related