MediaElement del kit de herramientas de la comunidad de Xamarin

Descargar ejemplo. Descarga del ejemplo

MediaElement es una vista para reproducir vídeo y audio. Los medios compatibles con la plataforma subyacente se pueden reproducir desde los siguientes orígenes:

  • La web, mediante un URI (HTTP o HTTPS).
  • Un recurso insertado en la aplicación de plataforma mediante el ms-appx:/// esquema URI.
  • Archivos que proceden de las carpetas de datos locales y temporales de la aplicación, mediante el ms-appdata:/// esquema de URI.
  • Biblioteca del dispositivo.

MediaElement puede usar los controles de reproducción de la plataforma, a los que se hace referencia como controles de transporte. Sin embargo, están deshabilitados de forma predeterminada y se pueden reemplazar por sus propios controles de transporte. Las capturas de pantalla siguientes muestran MediaElement la reproducción de un vídeo con los controles de transporte de la plataforma:

Captura de pantalla de una clase MediaElement reproduciendo un vídeo en iOS y Android.

Nota

MediaElementestá disponible en iOS, Android, el Plataforma universal de Windows (UWP), macOS, Windows Presentation Foundation y Tizen.

MediaElement define las siguientes propiedades:

  • Aspect, de tipo Aspect, determina cómo se escalará el medio para ajustarse al área de visualización. El valor predeterminado de esta propiedad es AspectFit.
  • AutoPlay, de tipo bool, indica si la reproducción multimedia comenzará automáticamente cuando se establezca la Source propiedad . El valor predeterminado de esta propiedad es true.
  • BufferingProgress, de tipo double, indica el progreso de almacenamiento en búfer actual. El valor predeterminado de esta propiedad es 0,0.
  • CanSeek, de tipo bool, indica si se puede cambiar la posición de los medios estableciendo el valor de la Position propiedad . Se trata de una propiedad de solo lectura.
  • CurrentState, de tipo MediaElementState, indica el estado actual del control. Se trata de una propiedad de solo lectura, cuyo valor predeterminado es MediaElementState.Closed.
  • Duration, de tipo TimeSpan?, indica la duración de los medios abiertos actualmente. Se trata de una propiedad de solo lectura cuyo valor predeterminado es null.
  • IsLooping, de tipo bool, describe si el origen multimedia cargado actualmente debe reanudar la reproducción desde el principio después de llegar a su final. El valor predeterminado de esta propiedad es false.
  • KeepScreenOn, de tipo bool, determina si la pantalla del dispositivo debe permanecer en durante la reproducción multimedia. El valor predeterminado de esta propiedad es false.
  • Position, de tipo TimeSpan, describe el progreso actual a través del tiempo de reproducción del medio. Esta propiedad usa un TwoWay enlace y su valor predeterminado es TimeSpan.Zero.
  • ShowsPlaybackControls, de tipo bool, determina si se muestran los controles de reproducción de plataformas. El valor predeterminado de esta propiedad es false. Tenga en cuenta que en iOS, los controles solo se muestran durante un breve período después de interactuar con la pantalla. No hay ninguna manera de mantener visibles los controles en todo momento. En WPF, no se admite ningún control del sistema, por lo que esta propiedad no tiene ningún efecto.
  • Speed, de tipo double, determina la velocidad de reproducción del medio. El valor predeterminado de esta propiedad es 1.
  • Source, de tipo MediaSource, indica el origen del medio cargado en el control .
  • VideoHeight, de tipo int, indica el alto del control. Se trata de una propiedad de solo lectura.
  • VideoWidth, de tipo int, indica el ancho del control. Se trata de una propiedad de solo lectura.
  • Volume, de tipo double, determina el volumen del medio, que se representa en una escala lineal entre 0 y 1. Esta propiedad usa un TwoWay enlace y su valor predeterminado es 1.

Estas propiedades, a excepción de la CanSeek propiedad, están respaldadas por BindableProperty objetos, lo que significa que pueden ser destinos de enlaces de datos y con estilo.

La MediaElement clase también define cuatro eventos:

  • MediaOpened se desencadena cuando se ha validado y abierto la secuencia multimedia.
  • MediaEnded se desencadena cuando finaliza la MediaElement reproducción de su medio.
  • MediaFailed se desencadena cuando hay un error asociado al origen multimedia.
  • SeekCompleted se desencadena cuando el punto de búsqueda de una operación de búsqueda solicitada está listo para su reproducción.

Además, MediaElement incluye Playlos métodos , Pausey Stop .

Para obtener información sobre los formatos multimedia admitidos en Android, consulte Formatos multimedia admitidos en developer.android.com. Para obtener información sobre los formatos multimedia admitidos en el Plataforma universal de Windows (UWP), consulta Códecs admitidos.

Reproducir medios remotos

MediaElement Puede reproducir archivos multimedia remotos mediante los esquemas de URI HTTP y HTTPS. Esto se logra estableciendo la Source propiedad en el URI del archivo multimedia:

<MediaElement Source="https://sec.ch9.ms/ch9/5d93/a1eab4bf-3288-4faf-81c4-294402a85d93/XamarinShow_mid.mp4"
              ShowsPlaybackControls="True" />

De forma predeterminada, el medio definido por la Source propiedad se reproduce inmediatamente después de abrir el medio. Para suprimir la reproducción automática de medios, establezca la AutoPlay propiedad en false.

Los controles de reproducción multimedia están deshabilitados de forma predeterminada y están habilitados estableciendo la ShowsPlaybackControls propiedad trueen . MediaElement Después, usará los controles de reproducción de la plataforma cuando estén disponibles.

Reproducir medios locales

Los medios locales se pueden reproducir desde los siguientes orígenes:

  • Un recurso insertado en la aplicación de plataforma mediante el ms-appx:/// esquema URI.
  • Archivos que proceden de las carpetas de datos locales y temporales de la aplicación, mediante el ms-appdata:/// esquema de URI.
  • Biblioteca del dispositivo.

Para obtener más información sobre estos esquemas de URI, consulte Esquemas de URI.

Reproducir elementos multimedia insertados en el paquete de la aplicación

MediaElement Puede reproducir archivos multimedia insertados en el paquete de la aplicación mediante el ms-appx:/// esquema de URI. Los archivos multimedia se insertan en el paquete de la aplicación colocándolos en el proyecto de plataforma.

El almacenamiento de un archivo multimedia en el proyecto de plataforma es diferente para cada plataforma:

  • En iOS, los archivos multimedia deben almacenarse en la carpeta Recursos o en una subcarpeta de la carpeta Resources . El archivo multimedia debe tener un Build Action de BundleResource.
  • En Android, los archivos multimedia deben almacenarse en una subcarpeta de Recursosdenominados raw. La carpeta raw no puede contener subcarpetas. El archivo multimedia debe tener un Build Action de AndroidResource.
  • En UWP, los archivos multimedia se pueden almacenar en cualquier carpeta del proyecto. El archivo multimedia debe tener un BuildAction de Content.

Los archivos multimedia que cumplen estos criterios se pueden reproducir mediante el ms-appx:/// esquema de URI:

<MediaElement Source="ms-appx:///XamarinForms101UsingEmbeddedImages.mp4"
              ShowsPlaybackControls="True" />

Al usar el enlace de datos, se puede usar un convertidor de valores para aplicar este esquema de URI:

public class VideoSourceConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
            return null;

        if (string.IsNullOrWhiteSpace(value.ToString()))
            return null;

        if (Device.RuntimePlatform == Device.UWP)
            return new Uri($"ms-appx:///Assets/{value}");
        else
            return new Uri($"ms-appx:///{value}");
    }
    // ...
}

A continuación, se puede usar una instancia de VideoSourceConverter para aplicar el ms-appx:/// esquema URI a un archivo multimedia incrustado:

<MediaElement Source="{Binding MediaSource, Converter={StaticResource VideoSourceConverter}}"
              ShowsPlaybackControls="True" />

Para obtener más información sobre el esquema de URI ms-appx, consulte ms-appx y ms-appx-web.

Reproducir elementos multimedia desde las carpetas locales y temporales de la aplicación

MediaElement Puede reproducir archivos multimedia que se copian en las carpetas de datos locales o temporales de la aplicación mediante el ms-appdata:/// esquema URI.

En el ejemplo siguiente se muestra la Source propiedad establecida en un archivo multimedia almacenado en la carpeta de datos local de la aplicación:

<MediaElement Source="ms-appdata:///local/XamarinVideo.mp4"
              ShowsPlaybackControls="True" />

En el ejemplo siguiente se muestra la Source propiedad en un archivo multimedia almacenado en la carpeta de datos temporales de la aplicación:

<MediaElement Source="ms-appdata:///temp/XamarinVideo.mp4"
              ShowsPlaybackControls="True" />

Importante

Además de reproducir archivos multimedia almacenados en las carpetas de datos locales o temporales de la aplicación, UWP también puede reproducir archivos multimedia que se encuentran en la carpeta móvil de la aplicación. Esto se puede lograr mediante el prefijo del archivo multimedia con ms-appdata:///roaming/.

Al usar el enlace de datos, se puede usar un convertidor de valores para aplicar este esquema de URI:

public class VideoSourceConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
            return null;

        if (string.IsNullOrWhiteSpace(value.ToString()))
            return null;

        return new Uri($"ms-appdata:///{value}");
    }
    // ...
}

Después, se puede usar una instancia de VideoSourceConverter para aplicar el ms-appdata:/// esquema de URI a un archivo multimedia en la carpeta de datos local o temporal de la aplicación:

<MediaElement Source="{Binding MediaSource, Converter={StaticResource VideoSourceConverter}}"
              ShowsPlaybackControls="True" />

Para obtener más información sobre el esquema de URI ms-appdata, consulte ms-appdata.

Copiar un archivo multimedia en la carpeta de datos local o temporal de la aplicación

La reproducción de un archivo multimedia almacenado en la carpeta de datos local o temporal de la aplicación requiere que la aplicación copie el archivo multimedia. Esto se puede lograr, por ejemplo, copiando un archivo multimedia desde el paquete de la aplicación:

// This method copies the video from the app package to the app data
// directory for your app. To copy the video to the temp directory
// for your app, comment out the first line of code, and uncomment
// the second line of code.
public static async Task CopyVideoIfNotExists(string filename)
{
    string folder = FileSystem.AppDataDirectory;
    //string folder = Path.GetTempPath();
    string videoFile = Path.Combine(folder, "XamarinVideo.mp4");

    if (!File.Exists(videoFile))
    {
        using (Stream inputStream = await FileSystem.OpenAppPackageFileAsync(filename))
        {
            using (FileStream outputStream = File.Create(videoFile))
            {
                await inputStream.CopyToAsync(outputStream);
            }
        }
    }
}

Nota

En el ejemplo de código anterior se usa la FileSystem clase incluida en Xamarin.Essentials. Para obtener más información, vea Xamarin.Essentials: Asistentes del sistema de archivos.

Reproducir elementos multimedia desde la biblioteca de dispositivos

La mayoría de los dispositivos móviles y equipos de escritorio modernos tienen la capacidad de grabar vídeos y audio mediante la cámara y el micrófono del dispositivo. A continuación, los medios creados se almacenan como archivos en el dispositivo. Estos archivos se pueden recuperar de la biblioteca y reproducirlos.MediaElement

Cada una de las plataformas incluye una instalación que permite al usuario seleccionar medios de la biblioteca del dispositivo. En Xamarin.Forms, los proyectos de plataforma pueden invocar esta funcionalidad y la clase puede llamar a DependencyService ella.

El servicio de dependencias de selección de vídeo usado en la aplicación de ejemplo es muy similar a uno definido en Seleccionar una foto de la biblioteca de imágenes, salvo que el selector devuelve un nombre de archivo en lugar de un Stream objeto. El proyecto de código compartido define una interfaz denominada IVideoPicker, que define un único método denominado GetVideoFileAsync. A continuación, cada plataforma implementa esta interfaz en una VideoPicker clase .

En el ejemplo de código siguiente se muestra cómo recuperar un archivo multimedia de la biblioteca de dispositivos:

string filename = await DependencyService.Get<IVideoPicker>().GetVideoFileAsync();
if (!string.IsNullOrWhiteSpace(filename))
{
    mediaElement.Source = new FileMediaSource
    {
        File = filename
    };
}

El servicio de dependencias de selección de vídeo se invoca mediante una llamada al DependencyService.Get método para obtener la implementación de una IVideoPicker interfaz en el proyecto de plataforma. A GetVideoFileAsync continuación, se llama al método en esa instancia y el nombre de archivo devuelto se usa para crear un FileMediaSource objeto y para establecerlo en la Source propiedad de MediaElement.

Cambiar la relación de aspecto del vídeo

La Aspect propiedad determina cómo se escalará el medio de vídeo para ajustarse al área de visualización. De forma predeterminada, esta propiedad se establece en el AspectFit miembro de enumeración, pero se puede establecer en cualquiera de los Aspect miembros de la enumeración:

  • AspectFit indica que el vídeo se escribirá, si es necesario, para ajustarse al área de presentación, a la vez que conserva la relación de aspecto.
  • AspectFill indica que el vídeo se recortará para que rellene el área de visualización, a la vez que conserva la relación de aspecto.
  • Fill indica que el vídeo se estirará para rellenar el área de visualización.

Enlace a la propiedad Position

La notificación de cambio de propiedad para la Position propiedad enlazable se activa a intervalos de 200 ms mientras se reproduce. Por lo tanto, la propiedad puede estar enlazada a datos a un Slider control (o similar) para mostrar el progreso a través del medio. CommunityToolkit también proporciona un TimeSpanToDoubleConverter elemento que convierte en TimeSpan un valor de punto flotante que representa el total de segundos transcurridos. De esta manera, puede establecer el control deslizante Maximum en el Duration de los medios y en para PositionValue proporcionar un progreso preciso:

<?xml version="1.0" encoding="UTF-8"?>
<pages:BasePage xmlns="http://xamarin.com/schemas/2014/forms"
                xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
                xmlns:pages="clr-namespace:Xamarin.CommunityToolkit.Sample.Pages"
                x:Class="Xamarin.CommunityToolkit.Sample.Pages.Views.MediaElementPage">
    <pages:BasePage.Resources>
        <xct:TimeSpanToDoubleConverter x:Key="TimeSpanConverter"/>
    </pages:BasePage.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <xct:MediaElement
            x:Name="mediaElement"
            Source="https://sec.ch9.ms/ch9/5d93/a1eab4bf-3288-4faf-81c4-294402a85d93/XamarinShow_mid.mp4"
            ShowsPlaybackControls="True"
            HorizontalOptions="Fill"
            SeekCompleted="OnSeekCompleted" />
        <Slider Grid.Row="1" BindingContext="{x:Reference mediaElement}" Value="{Binding Position, Converter={StaticResource TimeSpanConverter}}" Maximum="{Binding Duration, Converter={StaticResource TimeSpanConverter}}">
            <Slider.Triggers>
                <DataTrigger TargetType="Slider"
                     Binding="{Binding CurrentState}"
                     Value="{x:Static MediaElementState.Buffering}">
                    <Setter Property="IsEnabled" Value="False" />
                </DataTrigger>
            </Slider.Triggers>
        </Slider>
        <Button Grid.Row="2" Text="Reset Source (Set Null)" Clicked="OnResetClicked" />
    </Grid>
</pages:BasePage>

En este ejemplo, la Maximum propiedad de Slider está enlazada a datos a la Duration propiedad de MediaElement y la Value propiedad de Slider es enlazada a datos a la Position propiedad de MediaElement. Por lo tanto, arrastrando los Slider resultados en la posición de reproducción multimedia cambiando:

Captura de pantalla de un objeto MediaElement con una barra de posición, en iOS y Android.

Además, se usa un DataTrigger objeto para deshabilitar cuando Slider el medio se almacena en búfer. Para más información sobre los desencadenadores de datos, consulte Desencadenadores de Xamarin.Forms.

Nota

En Android, el Slider único tiene 1000 pasos discretos, independientemente de la Minimum configuración y Maximum . Si la longitud del medio es mayor que 1000 segundos, dos valores diferentes Position se corresponderían con el mismo Value de Slider. Este es el motivo por el que el código anterior comprueba que la nueva posición y la posición existente son mayores que una centésima de la duración total.

Descripción de los tipos de MediaSource

Un MediaElement objeto puede reproducir elementos multimedia estableciendo su Source propiedad en un archivo multimedia remoto o local. La Source propiedad es de tipo MediaSourcey esta clase define dos métodos estáticos:

  • FromFile, devuelve una MediaSource instancia de un string argumento .
  • FromUri, devuelve una MediaSource instancia de un Uri argumento .

Además, la MediaSource clase también tiene operadores implícitos que devuelven MediaSource instancias de string y Uri argumentos.

Nota

Cuando la Source propiedad se establece en XAML, se invoca un convertidor de tipos para devolver una MediaSource instancia de o stringUri.

La MediaSource clase también tiene dos clases derivadas:

  • UriMediaSource, que se usa para especificar un archivo multimedia remoto desde un URI. Esta clase tiene una Uri propiedad que se puede establecer en .Uri
  • FileMediaSource, que se usa para especificar un archivo multimedia local de .string Esta clase tiene una File propiedad que se puede establecer en .string Además, esta clase tiene operadores implícitos para convertir en string un FileMediaSource objeto y un FileMediaSource objeto en .string

Nota

Cuando se crea un FileMediaSource objeto en XAML, se invoca un convertidor de tipos para devolver una FileMediaSource instancia de .string

Determinar el estado de MediaElement

La MediaElement clase define una propiedad enlazable de solo lectura denominada CurrentState, de tipo MediaElementState. Esta propiedad indica el estado actual del control, como si el medio está reproduciendo o en pausa, o si aún no está listo para reproducir el medio.

La enumeración MediaElementState define los miembros siguientes:

  • Closed indica que no MediaElement contiene ningún medio.
  • Opening indica que está MediaElement validando e intentando cargar el origen especificado.
  • Buffering indica que está MediaElement cargando el medio para su reproducción. Su Position propiedad no avanza durante este estado. MediaElement Si se estaba reproduciendo el vídeo, continúa mostrando el último fotograma mostrado.
  • Playing indica que MediaElement está reproduciendo el origen multimedia.
  • Paused indica que MediaElement no avanza su Position propiedad. MediaElement Si se estaba reproduciendo vídeo, continúa mostrando el fotograma actual.
  • Stopped indica que contiene MediaElement elementos multimedia, pero no se está reproducendo ni pausando. Su Position propiedad es 0 y no avanza. Si el medio cargado es vídeo, muestra MediaElement el primer fotograma.

Por lo general, no es necesario examinar la CurrentState propiedad al usar los controles de MediaElement transporte. Sin embargo, esta propiedad es importante al implementar sus propios controles de transporte.

Implementar controles de transporte personalizados

Los controles de transporte de un reproductor multimedia incluyen los botones que realizan las funciones Reproducir, Pausar y Detener. Estos botones suelen identificarse con iconos conocidos en lugar de texto, y las funciones Reproducir y Pausa suelen combinarse en un mismo botón.

De forma predeterminada, los MediaElement controles de reproducción están deshabilitados. Esto le permite controlar el MediaElement control mediante programación o proporcionando sus propios controles de transporte. En compatibilidad con esto, MediaElement incluye Playlos métodos , Pausey Stop .

En el ejemplo XAML siguiente se muestra una página que contiene un MediaElement control de transporte personalizado y :

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MediaElementDemos.CustomTransportPage"
             Title="Custom transport">
    <Grid>
        ...
        <MediaElement x:Name="mediaElement"
                      AutoPlay="False"
                      ... />
        <StackLayout BindingContext="{x:Reference mediaElement}"
                     ...>
            <Button Text="&#x25B6;&#xFE0F; Play"
                    HorizontalOptions="CenterAndExpand"
                    Clicked="OnPlayPauseButtonClicked">
                <Button.Triggers>
                    <DataTrigger TargetType="Button"
                                 Binding="{Binding CurrentState}"
                                 Value="{x:Static MediaElementState.Playing}">
                        <Setter Property="Text"
                                Value="&#x23F8; Pause" />
                    </DataTrigger>
                    <DataTrigger TargetType="Button"
                                 Binding="{Binding CurrentState}"
                                 Value="{x:Static MediaElementState.Buffering}">
                        <Setter Property="IsEnabled"
                                Value="False" />
                    </DataTrigger>
                </Button.Triggers>
            </Button>
            <Button Text="&#x23F9; Stop"
                    HorizontalOptions="CenterAndExpand"
                    Clicked="OnStopButtonClicked">
                <Button.Triggers>
                    <DataTrigger TargetType="Button"
                                 Binding="{Binding CurrentState}"
                                 Value="{x:Static MediaElementState.Stopped}">
                        <Setter Property="IsEnabled"
                                Value="False" />
                    </DataTrigger>
                </Button.Triggers>
            </Button>
        </StackLayout>
    </Grid>
</ContentPage>

En este ejemplo, los controles de transporte personalizados se definen como Button objetos . Sin embargo, solo hay dos Button objetos, con el primero Button que representa Play y Pause, y el segundo Button que representa Stop. DataTrigger Los objetos se usan para habilitar y deshabilitar los botones, y para cambiar el primer botón entre Reproducir y Pausar. Para más información sobre los desencadenadores de datos, consulte Desencadenadores de Xamarin.Forms.

El archivo de código subyacente tiene los controladores para los Clicked eventos:

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();
}

El botón Reproducir se puede presionar, una vez habilitado, para comenzar la reproducción:

Captura de pantalla de un objeto MediaElement con controles de transporte personalizados, en iOS y Android.

Al presionar el botón Pausar , se pausa la reproducción:

Captura de pantalla de un objeto MediaElement con reproducción en pausa, en iOS y Android.

Al presionar el botón Detener se detiene la reproducción y se devuelve la posición del archivo multimedia al principio.

Implementación de un control de volumen personalizado

Los controles de reproducción multimedia implementados por cada plataforma incluyen una barra de volumen. Esta barra es similar a un control deslizante y muestra el volumen del medio. Además, puede manipular la barra de volumen para aumentar o disminuir el volumen.

Una barra de volumen personalizada se puede implementar mediante , Slidercomo se muestra en el ejemplo siguiente:

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

En este ejemplo, los Slider datos enlazan su Value propiedad a la Volume propiedad de MediaElement. Esto es posible porque la Volume propiedad usa un TwoWay enlace. Por lo tanto, al cambiar la Value propiedad se producirá el Volume cambio de propiedad.

Nota

La Volume propiedad tiene una devolución de llamada de validación que garantiza que su valor sea mayor o igual que 0,0 y menor o igual que 1,0.

Para más información sobre el uso de un Slider control deslizante de Xamarin.Forms