Blazor - Executando arquivos de áudio mp3

Hoje veremos como executar arquivos de áudio mp3 em uma aplicação Blazor Server.

Se você esta chegando agora e não sabe o que é o Blazor leia o artigo ASP .NET Core - Iniciando com o Blazor - Macoratti; se você já conhece e quer saber mais pode fazer o curso de Blazor Essencial.  

Com um pouco de interoperabilidade de JavaScript, podemos reproduzir arquivos mp3 em um aplicativo Blazor.

Sim, uma aplicação Blazor pode chamar funções JavaScript a partir dos métodos C#, e também podemos invocar métodos C# a partir do JavaScript.

Para mais detalhes leia o meu artigo: Blazor - Interoperabilidade com JavaScript - I

Hoje, vamos criar um projeto Blazor Server e executar arquivos mp3 usando a interoperabilidade JavaScript.

Recursos usados:

Criando o projeto no VS Community 2019

Abra o VS 2019 Community (versão mínima 16.4) e selecione a opção Create a New Project;

A seguir selecione a opção Blazor app e clique em next;

Informe o nome do projeto :  Blog_Mp3, a localização e clique em Create;

Selecione a opção - Blazor Server App. Não vamos usar autenticação e vamos habilitar o https.

Clique no botão Create para criar o projeto.

Com o projeto criado vamos limpar o projeto excluindo os arquivos abaixo e suas referências:

A seguir crie uma pasta musicas dentro da pasta wwwroot do projeto criado, e nesta pasta inclua os arquivos mp3 que deseja executar.

Para o exemplo eu baixei da web dois arquivos : hip-hop-beat.mp3 e thunder.mp3 que irei usar.

A recomendação é que para cada arquivo mp3 a propriedade Build Action deve estar definida como  Content e a propriedade Copy to Output Directory deve estar definida para Copy if newer. (Mas testei sem fazer isso e funcionou).

Neste projeto iremos mostrar como executar um arquivo por vez, executar arquivos simultâneos e realizar a execução automática.

Assim vamos ajustar o arquivo  NavMenu que esta na pasta Shared, e já vamos definir as opções para chamar os respectivos arquivos que irão executar cada uma das implementações que iremos fazer:

<div class="top-row pl-4 navbar navbar-dark">
    <a class="navbar-brand" href="">Blazor_Mp3</a>
    <button class="navbar-toggler" @onclick="ToggleNavMenu">
        <span class="navbar-toggler-icon"></span>
    </button>
</div>
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
    <ul class="nav flex-column">
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
                <span class="oi oi-home" aria-hidden="true"></span> Tocar Mp3
            </NavLink>
        </li>
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="multiplos">
                <span class="oi oi-plus" aria-hidden="true"></span> Múltiplos Sons
            </NavLink>
        </li>
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="automatico">
                <span class="oi oi-list-rich" aria-hidden="true"></span> Automático
            </NavLink>
        </li>
    </ul>
</div>

...

1- Executando um arquivo mp3 por vez

Vamos abrir o arquivo Index.razor e incluir o código abaixo neste arquivo:

@page "/"
@inject IJSRuntime js;
<h1>Toca MP3</h1>
<button class="btn btn-primary" @onclick="PlayAudioFile1">Hip-hop</button>
<span>&nbsp;</span>
<button class="btn btn-primary" @onclick="PlayAudioFile2">Tempestade</button>
<audio id="player">
    <source id="playerSource" src="" />
</audio>
@code
{
    async Task PlayAudioFile1()
    {
        await js.InvokeVoidAsync("PlayAudioFile1", "/musicas/hip-hop-beat.mp3");
    }
    async Task PlayAudioFile2()
    {
        await js.InvokeVoidAsync("PlayAudioFile1", "/musicas/thunder.mp3");
    }
}

No código estamos invocando a partir do código C# a função Javascript PlayAudioFile1 informando o caminho do arquivo mp3.

Precisamos incluir no arquivo Pages/_Host.cshtml o script JavaScript abaixo:

  • ...
     <script>
            window.PlayAudioFile1 = (src) => {
                var audio = document.getElementById('player');
                if (audio != null) {
                    var audioSource = document.getElementById('playerSource');
                    if (audioSource != null) {
                        audioSource.src = src;
                        audio.load();
                        audio.play();
                    }
                }
            }
     </script>
    ...

    Agora é só executar e testar a primeira opção...

    Executando arquivos mp3 simultâneos

    Vamos agora executar mais de um arquivo mp3 ao mesmo tempo. No nosso exemplo vamos executar os dois arquivos mp3 que temos na pasta musicas.

    Para isso vamos criar na pasta Pages o componente: MultiploSons.razor com o código a seguir:

    @page "/multiplos"
    @inject IJSRuntime js;
    <h1>Toca múltiplos MP3</h1>
    <button class="btn btn-primary" @onclick="PlayAudioFile1">Hip-Hop</button>
    <span>&nbsp;</span>
    <button class="btn btn-primary" @onclick="PlayAudioFile2">Tempestade</button>
    <audio id="player1">
        <source id="playerSource1" src="" />
    </audio>
    <audio id="player2">
        <source id="playerSource2" src="" />
    </audio>
    @code
    {
        async Task PlayAudioFile1()
        {
            await js.InvokeVoidAsync("PlayAudioFile2", "1", "/musicas/hip-hop-beat.mp3");
        }
        async Task PlayAudioFile2()
        {
            await js.InvokeVoidAsync("PlayAudioFile2", "2", "/musicas/thunder.mp3");
        }
    }

    Adicionamos uma segunda tag de áudio e a nomeamos “player1” e “player2”. Também atualizamos os nomes dos elementos de origem para “playerSource1” e “playerSource2”.

    Também modificamos nossas chamadas JavaScript para passar o número do player como uma string.

    A seguir inclua o script JavaScript no arquivo _Host.cshtml:

    ...
    
     <script>
            window.PlayAudioFile2 = (playerNumber, src) => {
                var audio = document.getElementById('player' + playerNumber);
                if (audio != null) {
                    var audioSource = document.getElementById('playerSource' + playerNumber);
                    if (audioSource != null) {
                        audioSource.src = src;
                        audio.load();
                        audio.play();
                    }
                }
            }
        </script>
    ...

    Agora podemos executar os dois arquivos mp3 ao mesmo tempo...

    Carregando e Executando arquivos mp3 de forma dinâmica

    Não seria legal se não tivéssemos que provisionar esses controles de áudio antes de usá-los ?

    Com um pouco mais de JavaScript, podemos criá-los rapidamente, carregar o arquivo de áudio e reproduzi-los.

    Assim, os arquivos de áudio serão reproduzidos de forma totalmente assíncrona.

    Vamos então criar o componente PlayDinamico.razor com o seguinte código:

    @page "/automatico"
    @inject IJSRuntime js;
    <h1>Toca MP3 Dinâmico</h1>
    <button class="btn btn-primary" @onclick="PlayAudioFile1">Hip-hop</button>
    <span>&nbsp;</span>
    <button class="btn btn-primary" @onclick="PlayAudioFile2">Tempestade</button>
    @code
    {
        async Task PlayAudioFile1()
        {
            await js.InvokeVoidAsync("PlayAudioFile3", "/musicas/hip-hop-beat.mp3");
        }
        async Task PlayAudioFile2()
        {
            await js.InvokeVoidAsync("PlayAudioFile3", "/musicas/thunder.mp3");
        }
    }

    O código é igual ao do componente Index.razor somente não usa as tags <audio>.

    Agora vamos incluir no arquivo _Host.cshtml o código a seguir:

    ...
     <script>
            window.PlayAudioFile3 = (src) => {
                var sound = document.createElement('audio');
                sound.src = src;
                sound.type = 'audio/mpeg';
                document.body.appendChild(sound);
                sound.load();
                sound.play();
            }
        </script>
    ...

    Agora você já pode testar as 3 opções para tocar arquivos mp3 implementadas..

    Pegue o projeto aqui: Blazor_Mp3.zip

    "Porque o Filho do homem (Jesus) veio buscar e salvar o que se havia perdido."
    Lucas 19:10

     


    Referências:


    José Carlos Macoratti