Partilhar via


MediaElement

MediaElement é um controle para reproduzir vídeo e áudio. A mídia que tem suporte da plataforma subjacente pode ser reproduzida das seguintes fontes:

  • A Web, por meio um URI (HTTP ou HTTPS).
  • Um recurso inserido no aplicativo da plataforma, por meio do esquema de URI embed://.
  • Arquivos provenientes do sistema de arquivos local do aplicativo, por meio do esquema de URI filesystem://.

MediaElement pode usar os controles de reprodução da plataforma, que são conhecidos como controles de transporte. No entanto, eles estão desabilitados por padrão e podem ser substituídos por controles de transporte próprios. As seguintes capturas de tela mostram MediaElement reproduzindo um vídeo com os controles de transporte da plataforma:

Captura de tela de um MediaElement reproduzindo um vídeo no Android e no iOS.

Observação

MediaElement está disponível no iOS, no Android, no Windows, no macOS e no Tizen.

O MediaElement usa as implementações de plataforma a seguir.

Plataforma Implementação do player de mídia da plataforma
Android ExoPlayer, agradecemos aos mantenedores do ExoPlayerXamarin!
iOS/macOS AVPlayer
Windows MediaPlayer

Introdução

Para você usar o recurso MediaElement do Kit de Ferramentas da Comunidade do .NET MAUI, as etapas a seguir são necessárias.

Instalar pacote NuGet

Para usar MediaElement dentro do aplicativo, instale o pacote NuGet CommunityToolkit.Maui.MediaElement e adicione uma linha de inicialização a MauiProgram.cs. Desta forma:

Nome do pacote: CommunityToolkit.Maui.MediaElement

URL do pacote: https://www.nuget.org/packages/CommunityToolkit.Maui.MediaElement

Como inicializar o pacote

Primeiro, a instrução using precisa ser adicionada ao início do seu arquivo MauiProgram.cs

using CommunityToolkit.Maui.MediaElement;

Para você usar o MediaElement corretamente, o método UseMauiCommunityToolkitMediaElement precisará ser chamado na classe MauiAppBuilder quando um aplicativo for inicializado no arquivo MauiProgram.cs. O exemplo a seguir mostra como fazer isso.

var builder = MauiApp.CreateBuilder();
builder
    .UseMauiApp<App>()
    .UseMauiCommunityToolkitMediaElement()

Para obter mais informações sobre como fazer isso, veja a página Introdução.

Inicialização específica da plataforma

Para acessar a funcionalidade MediaElement, a configuração específica da plataforma a seguir é necessária.

Ao utilizar MediaElement é imprescindível realizar os seguintes etapas:

1. Adicionar ResizableActivity e Launchmode à atividade

[Activity(Theme = "@style/Maui.SplashTheme", ResizeableActivity = true, MainLauncher = true, LaunchMode = LaunchMode.SingleTask)]
public class MainActivity : MauiAppCompatActivity
{
}

2. Adicione o seguinte AndroidManifest.xml dentro da <application> marca.

 <service android:name="communityToolkit.maui.media.services" android:exported="false" android:enabled="true" android:foregroundServiceType="mediaPlayback">
   <intent-filter>
     <action android:name="android.intent.action.MEDIA_BUTTON" />
   </intent-filter>
   <intent-filter>
     <action android:name="androidx.media3.session.MediaSessionService"/>
   </intent-filter>
 </service>

3. Adicione as seguintes permissões ao AndroidManifest.xml

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL" />

Aqui está um exemplo de configurações necessárias em AndroidManifest.xml

<application android:allowBackup="true" android:icon="@mipmap/appicon" android:enableOnBackInvokedCallback="true" android:supportsRtl="true">
<service android:name="communityToolkit.maui.media.services" android:exported="false" android:enabled="true" android:foregroundServiceType="mediaPlayback">
    <intent-filter>
    <action android:name="android.intent.action.MEDIA_BUTTON" />
    </intent-filter>
    <intent-filter>
    <action android:name="androidx.media3.session.MediaSessionService"/>
    </intent-filter>
</service>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL" />

Observação

Essa modificação no manifesto do Android permite a exibição de metadados durante a reprodução de um vídeo. Ele fornece suporte para notificações e é essencial para que as notificações funcionem em todas as APIs relevantes. A mudança introduz um serviço e concede as permissões necessárias.

Para ver um exemplo completo desse método incluído em um aplicativo, veja o Aplicativo de exemplo do Kit de Ferramentas da Comunidade do .NET MAUI

Formatos com suporte

Os formatos de multimídia com suporte podem variar conforme a plataforma. Em alguns casos, eles podem até depender de quais decodificadores estão disponíveis ou instalados no sistema operacional usado durante a execução do aplicativo. Para obter informações mais detalhadas sobre os formatos para os quais há suporte em cada plataforma, veja os links abaixo.

Plataforma Link Observações
Android Formatos com suporte do ExoPlayer
iOS/macOS Formatos com suporte no iOS/no macOS Não há nenhuma documentação a respeito
Windows Formatos com suporte do Windows No Windows, os formatos com suporte dependem muito dos codecs instalados no computador do usuário
Tizen Formatos com suporte do Tizen

Importante

Se o usuário estiver usando uma edição do Windows N, por padrão, nenhuma reprodução de vídeo terá suporte. As edições do Windows N não têm formatos de reprodução de vídeo instalados por design.

Cenários comuns

As seções a seguir abordam cenários comuns de uso do MediaElement.

Reproduzir uma mídia remota

Um MediaElement pode reproduzir arquivos de mídia remota usando os esquemas de URI HTTP e HTTPS. Isso é feito com a definição da propriedade Source como o URI do arquivo de mídia:

<toolkit:MediaElement Source="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
              ShouldShowPlaybackControls="True" />

Importante

Quando você reproduzir fontes remotas de pontos de extremidade HTTP, será provável que precisará desabilitar as medidas de segurança do sistema operacional que impedem o acesso a pontos de extremidade da Web não seguros. Isso é, no mínimo, aplicável ao iOS e ao Android.

Por padrão, a mídia definida pela propriedade Source não começa a ser reproduzida imediatamente depois que a mídia é aberta. Para habilitar a reprodução automática de mídia, defina a propriedade ShouldAutoPlay como true.

Os controles de reprodução de mídia fornecidos pela plataforma estão habilitados por padrão e podem ser desabilitados com a definição da propriedade ShouldShowPlaybackControls como false.

Utilizando metadados

Um MediaElement pode usar metadados para MediaElement.MetadataTitle, MediaElement.MetadataArtist e MediaElement.MetadataArtworkUrl. Você pode definir o título ou artista para mostrar o que está sendo reproduzido atualmente nos controles da tela de bloqueio do Windows, Mac Catalyst, iOS e Android. Você pode definir um URL local ou remoto com arte para a tela de bloqueio. Deve ser pelo menos 1080P para que a melhor qualidade seja exibida. Deve ser um URL e ser .jpg ou .png

<toolkit:MediaElement 
    MetadataTitle="Title"
    MetadataArtist="Artist"
    MetadataArtworkUrl="http://www.myownpersonaldomain.com/image.jpg" />
    MediaElement.MetadataTitle="Title";
    MediaElement.MetadataArtist="Artist";
    MediaElement.MetadataArtworkUrl="http://www.myownpersonaldomain.com/image.jpg";

Importante

Você pode definir os metadados em XAML ou code-behind. Se você estiver configurando no code-behind, precisará definir a fonte no code-behind. A fonte deve ser definida por último. Se você definir os metadados em XAML ou no construtor, essa nota poderá ser ignorada com segurança.

Reproduzir uma mídia local

Uma mídia local pode ser reproduzida das seguintes fontes:

  • Um recurso inserido no aplicativo da plataforma, por meio do esquema de URI embed://.
  • Arquivos provenientes do sistema de arquivos local do aplicativo, por meio do esquema de URI filesystem://.

Observação

As abreviações embed:// e filesystem:// só funcionam no XAML. No código, use MediaSource.FromResource() e MediaSource.FromFile(), respectivamente. Usando esses métodos, você pode omitir os prefixos embed:// e filesystem://. O restante do caminho será o mesmo.

Reproduzir uma mídia inserida no pacote do aplicativo

Um MediaElement pode reproduzir arquivos de mídia inseridos no pacote do aplicativo usando o esquema de URI embed://. Os arquivos de mídia são inseridos no pacote do aplicativo ao colocá-los no projeto da plataforma.

Para habilitar um arquivo de mídia para reprodução por meio dos recursos locais, adicione o arquivo Resources/Raw à pasta do projeto .NET MAUI. Quando um arquivo é adicionado na raiz, o URI é embed://MyFile.mp4.

Você também pode colocar arquivos em subpastas. Se MyFile.mp4 estiver em Resources/Raw/MyVideos, o URI a ser usado com MediaElement será embed://MyVideos/MyFile.mp4.

Veja abaixo um exemplo de como usar essa sintaxe no XAML.

<toolkit:MediaElement Source="embed://MyFile.mp4"
              ShouldShowPlaybackControls="True" />

Noções básicas sobre os tipos de MediaSource

Um MediaElement pode reproduzir uma mídia com a definição da propriedade Source como um arquivo de mídia local ou remoto. A propriedade Source é do tipo MediaSource, e essa classe define três métodos estáticos:

  • FromFile, retorna uma instância de FileMediaSource de um argumento string.
  • FromUri, retorna uma instância de UriMediaSource de um argumento Uri.
  • FromResource, retorna uma instância de ResourceMediaSource de um argumento string.

Além disso, a classe MediaSource também tem operadores implícitos que retornam instâncias de MediaSource dos argumentos string e Uri.

Observação

Quando a propriedade Source é definida em XAML, um conversor de tipo é invocado para retornar uma instância de MediaSource de uma string ou um Uri.

A classe MediaSource também contém estas classes derivadas:

  • FileMediaSource, que é usada para especificar um arquivo de mídia local de um string. Essa classe tem uma propriedade Path que pode ser definida como uma string. Além disso, essa classe tem operadores implícitos para converter uma string em um objeto FileMediaSource e um objeto FileMediaSource em uma string.
  • UriMediaSource, que é usada para especificar um arquivo de mídia remota de um URI. Essa classe tem uma propriedade Uri que pode ser definida como um Uri.
  • ResourceMediaSource, que é usada para especificar um arquivo inserido fornecido por meio dos arquivos de recurso do aplicativo. Essa classe tem uma propriedade Path que pode ser definida como uma string.

Observação

Quando um objeto FileMediaSource é criado em XAML, um conversor de tipo é invocado para retornar uma instância de FileMediaSource de uma string.

Alterar a taxa de proporção de um vídeo

A propriedade Aspect determina como a mídia de vídeo será dimensionada para se ajustar à área de exibição. Por padrão, essa propriedade é definida como o membro de enumeração AspectFit, mas pode ser definida como qualquer um dos membros de enumeração Aspect:

  • AspectFit indica que o vídeo terá o formato letterbox, para se ajustar à área de exibição, preservando a taxa de proporção.
  • AspectFill indica que o vídeo será recortado para que ele preencha a área de exibição, preservando a taxa de proporção.
  • Fill indica que o vídeo será alongado para preencher a área de exibição.

Determinar o status de MediaElement

A classe MediaElement define uma propriedade associável somente leitura chamada CurrentState, do tipo MediaElementState. Essa propriedade indica o status atual do controle, por exemplo, se a mídia está sendo reproduzida ou em pausa ou se ele ainda não está pronto para reproduzir a mídia.

A enumeração MediaElementState define os seguintes membros:

  • None indica que MediaElement não contém nenhuma mídia.
  • Opening indica que o MediaElement está validando e tentando carregar a fonte especificada.
  • Buffering indica que o MediaElement está carregando a mídia para reprodução. A respectiva propriedade Position não avança durante esse estado. Se o MediaElement estava reproduzindo um vídeo, ele continua mostrando o último quadro exibido.
  • Playing indica que o MediaElement está reproduzindo a origem de mídia.
  • Paused indica que o MediaElement não avança a propriedade Position. Se o MediaElement estava reproduzindo um vídeo, ele continua mostrando o quadro atual.
  • Stopped indica que o MediaElement contém uma mídia, mas não está sendo reproduzida nem colocada em pausa. A respectiva propriedade Position é redefinida para 0 e não avança.
  • Failed indica que ocorreu uma falha do MediaElement ao carregar ou reproduzir a mídia. Isso pode ocorrer durante a tentativa de carregar um novo item de mídia ao tentar reproduzir o item de mídia ou quando a reprodução de mídia é interrompida devido a uma falha. Use o evento MediaFailed para recuperar mais detalhes.

Geralmente, não é necessário examinar a propriedade CurrentState ao usar os controles de transporte MediaElement. No entanto, essa propriedade passa a ser importante quando controles de transporte próprios são implementados.

Implementar controles de transporte personalizados

Os controles de transporte de um player de mídia incluem os botões que executam as funções Reproduzir, Pausar e Parar. Em geral, esses botões são identificados com ícones conhecidos, em vez de um texto, e as funções Reproduzir e Pausar geralmente são combinadas em um botão.

Por padrão, os controles de reprodução do MediaElement ficam desabilitados. Isso permite que você controle o MediaElement por meio de programação ou pelo fornecimento de controles de transporte próprios. Para dar suporte a esse recurso, o MediaElement inclui os métodos Play, Pause e Stop.

O seguinte exemplo de XAML mostra uma página que contém um MediaElement e controles de transporte personalizados:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
             x:Class="MediaElementDemos.CustomTransportPage"
             Title="Custom transport">
    <Grid>
        ...
        <toolkit:MediaElement x:Name="mediaElement"
                      ShouldAutoPlay="False"
                      ... />
        <HorizontalStackLayout BindingContext="{x:Reference mediaElement}"
                     ...>
            <Button Text="Play"
                    HorizontalOptions="Center"
                    Clicked="OnPlayPauseButtonClicked">
                <Button.Triggers>
                    <DataTrigger TargetType="Button"
                                 Binding="{Binding CurrentState}"
                                 Value="{x:Static toolkit:MediaElementState.Playing}">
                        <Setter Property="Text"
                                Value="Pause" />
                    </DataTrigger>
                    <DataTrigger TargetType="Button"
                                 Binding="{Binding CurrentState}"
                                 Value="{x:Static toolkit:MediaElementState.Buffering}">
                        <Setter Property="IsEnabled"
                                Value="False" />
                    </DataTrigger>
                </Button.Triggers>
            </Button>
            <Button Text="Stop"
                    HorizontalOptions="Center"
                    Clicked="OnStopButtonClicked">
                <Button.Triggers>
                    <DataTrigger TargetType="Button"
                                 Binding="{Binding CurrentState}"
                                 Value="{x:Static toolkit:MediaElementState.Stopped}">
                        <Setter Property="IsEnabled"
                                Value="False" />
                    </DataTrigger>
                </Button.Triggers>
            </Button>
        </HorizontalStackLayout>
    </Grid>
</ContentPage>

Neste exemplo, os controles de transporte personalizados são definidos como objetos Button. No entanto, há apenas dois objetos Button, com o primeiro Button representando Reproduzir e Pausar e o segundo Button representando Parar. Os objetos DataTrigger são usados para habilitar e desabilitar os botões, bem como para alternar o primeiro botão entre Reproduzir e Pausar. Para obter mais informações sobre gatilhos de dados, confira Gatilhos do .NET MAUI.

O arquivo code-behind traz os manipuladores para os eventos Clicked:

void OnPlayPauseButtonClicked(object sender, EventArgs args)
{
    if (mediaElement.CurrentState == MediaElementState.Stopped ||
        mediaElement.CurrentState == MediaElementState.Paused)
    {
        mediaElement.Play();
    }
    else if (mediaElement.CurrentState == MediaElementState.Playing)
    {
        mediaElement.Pause();
    }
}

void OnStopButtonClicked(object sender, EventArgs args)
{
    mediaElement.Stop();
}

O botão Reproduzir pode ser pressionado, depois de habilitado, para iniciar a reprodução. Pressionar o botão Pausar resulta na pausa da reprodução. Pressionar o botão Parar interrompe a reprodução e retorna a posição do arquivo de mídia para o início.

Implementar um controle de volume personalizado

Os controles de reprodução de mídia implementados pelas plataformas incluem uma barra de volume. Essa barra é semelhante a um controle deslizante e mostra o volume da mídia. Além disso, você pode manipular a barra de volume para aumentar ou diminuir o volume.

Uma barra de volume personalizada pode ser implementada com um Slider, conforme mostrado no seguinte exemplo:

<StackLayout>
    <toolkit:MediaElement ShouldAutoPlay="False"
                          Source="{StaticResource AdvancedAsync}" />
    <Slider Maximum="1.0"
            Minimum="0.0"
            Value="{Binding Volume}"
            Rotation="270"
            WidthRequest="100" />
</StackLayout>

Neste exemplo, o Slider associa os dados da propriedade Value à propriedade Volume do MediaElement. Isso é possível porque a propriedade Volume usa uma associação TwoWay. Portanto, alterar a propriedade Value resultará na alteração da propriedade Volume.

Observação

A propriedade Volume tem um retorno de chamada de validação que garante que o valor seja superior ou igual a 0,0 e inferior ou igual a 1,0.

Para obter mais informações sobre como usar um Slider, confira Controle deslizante do .NET MAUI

Limpar os recursos do MediaElement

Para evitar perdas de memória, você precisará liberar os recursos do MediaElement. Faça isso desconectando o manipulador. O local em que você precisa fazer isso depende de onde e como você usa MediaElement no seu aplicativo, mas normalmente, se você tiver um MediaElement em uma só página e não estiver reproduzindo uma mídia em segundo plano, o ideal é liberar os recursos quando o usuário sair da página.

Abaixo, encontre um snippet de código de exemplo que mostra como fazer isso. Primeiro, lembre-se de conectar o evento Unloaded na página.

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
             x:Class="MediaElementDemos.FreeResourcesPage"
             Title="Free Resources"
             Unloaded="ContentPage_Unloaded">
    
    <toolkit:MediaElement x:Name="mediaElement"
                          ShouldAutoPlay="False"
                          ... />
</ContentPage>

Em seguida, no code-behind, chame o método para desconectar o manipulador.

public partial class FreeResourcesPage : ContentPage
{
    void ContentPage_Unloaded(object? sender, EventArgs e)
    {
        // Stop and cleanup MediaElement when we navigate away
        mediaElement.Handler?.DisconnectHandler();
    }
}

Para ler mais sobre manipuladores, confira a documentação do .NET MAUI sobre manipuladores.

Propriedades

Propriedade Type Descrição Valor Padrão
Aspecto Aspecto Determina o modo de escala para a mídia (visual) que está carregada no momento. Esta é uma propriedade associável. Aspect.AspectFit
CurrentState MediaElementState Indica o status atual do controle. Esta é uma propriedade associável somente leitura. MediaElementState.None
Duration TimeSpan Indica a duração da mídia aberta no momento. Esta é uma propriedade associável somente leitura. TimeSpan.Zero
Cargo TimeSpan Descreve o progresso atual por meio do tempo de reprodução da mídia. Esta é uma propriedade associável somente leitura. Se você quiser definir a Position, use o método SeekTo(). TimeSpan.Zero
ShouldAutoPlay bool Indica se a reprodução de mídia será iniciada automaticamente quando a propriedade Source for definida. Esta é uma propriedade associável. false
ShouldLoopPlayback bool Descreve se a origem de mídia atualmente carregada deve retomar a reprodução desde o início depois de chegar ao final dela. Esta é uma propriedade associável. false
ShouldKeepScreenOn bool Determina se a tela do dispositivo deve permanecer ativada durante a reprodução de mídia. Esta é uma propriedade associável. false
ShouldMute bool Determina se o áudio está ativado no momento. Esta é uma propriedade associável. false
ShouldShowPlaybackControls bool Determina se os controles de reprodução das plataformas são exibidos. Esta é uma propriedade associável. Observe que, no iOS e no Windows, os controles só são mostrados por um breve período após a interação com a tela. Não há nenhuma forma de manter os controles visíveis o tempo todo. true
Origem MediaSource? A origem da mídia carregada no controle. null
Velocidade double Determina a velocidade de reprodução da mídia. Esta é uma propriedade associável 1
MediaHeight int A altura da mídia carregada em pixels. Esta é uma propriedade associável somente leitura. Não relatado para mídia não visual e pode nem sempre ser preenchido no iOS/macOS para conteúdo transmitido ao vivo. 0
MediaWidth int A largura da mídia carregada em pixels. Esta é uma propriedade associável somente leitura. Não relatado para mídia não visual e pode nem sempre ser preenchido no iOS/macOS para conteúdo transmitido ao vivo. 0
Volume double Determina o volume da mídia, que é representado em uma escala linear entre 0 e 1. Esta é uma propriedade associável. 1

Eventos

Evento Descrição
MediaOpened Ocorre quando o fluxo de mídia foi validado e aberto.
MediaEnded Ocorre quando o MediaElement conclui a reprodução da mídia.
MediaFailed Ocorre quando há um erro associado à origem de mídia.
PositionChanged Ocorre quando o valor da propriedade Position é alterado.
SeekCompleted Ocorre quando o ponto de busca de uma operação de busca solicitada está pronto para reprodução.

Métodos

Evento Descrição
Reproduzir Começa a reproduzir a mídia carregada.
Pausar Pausa a reprodução da mídia atual.
Parar Interrompe a reprodução e redefine a posição da mídia atual.
SeekTo Usa um valor de TimeSpan para definir a propriedade Position e usa um CancellationToken para cancelar a Task.

Exemplos

Você pode encontrar exemplos desse controle na prática no Aplicativo de exemplo do Kit de Ferramentas da Comunidade do .NET MAUI.

API

O código-fonte do MediaElement pode ser encontrado no repositório GitHub do .NET MAUI Community Toolkit.