MediaElement del kit de herramientas de la comunidad de Xamarin
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:
Nota:
MediaElement
está disponible en iOS, Android, el Plataforma universal de Windows (UWP), macOS, Windows Presentation Foundation y Tizen.
MediaElement
define las siguientes propiedades:
Aspect
, de tipoAspect
, determina cómo se escalará el medio para ajustarse al área de visualización. El valor predeterminado de esta propiedad esAspectFit
.AutoPlay
, de tipobool
, indica si la reproducción multimedia comenzará automáticamente cuando se establezca laSource
propiedad . El valor predeterminado de esta propiedad estrue
.BufferingProgress
, de tipodouble
, indica el progreso de almacenamiento en búfer actual. El valor predeterminado de esta propiedad es 0,0.CanSeek
, de tipobool
, indica si se puede cambiar la posición de los medios estableciendo el valor de laPosition
propiedad . Se trata de una propiedad de solo lectura.CurrentState
, de tipoMediaElementState
, indica el estado actual del control. Se trata de una propiedad de solo lectura, cuyo valor predeterminado esMediaElementState.Closed
.Duration
, de tipoTimeSpan?
, indica la duración de los medios abiertos actualmente. Se trata de una propiedad de solo lectura cuyo valor predeterminado esnull
.IsLooping
, de tipobool
, 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 esfalse
.KeepScreenOn
, de tipobool
, determina si la pantalla del dispositivo debe permanecer en durante la reproducción multimedia. El valor predeterminado de esta propiedad esfalse
.Position
, de tipoTimeSpan
, describe el progreso actual a través del tiempo de reproducción del medio. Esta propiedad usa unTwoWay
enlace y su valor predeterminado esTimeSpan.Zero
.ShowsPlaybackControls
, de tipobool
, determina si se muestran los controles de reproducción de plataformas. El valor predeterminado de esta propiedad esfalse
. 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 tipodouble
, determina la velocidad de reproducción del medio. El valor predeterminado de esta propiedad es 1.Source
, de tipoMediaSource
, indica el origen del medio cargado en el control .VideoHeight
, de tipoint
, indica el alto del control. Se trata de una propiedad de solo lectura.VideoWidth
, de tipoint
, indica el ancho del control. Se trata de una propiedad de solo lectura.Volume
, de tipodouble
, determina el volumen del medio, que se representa en una escala lineal entre 0 y 1. Esta propiedad usa unTwoWay
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 laMediaElement
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 Play
los métodos , Pause
y 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 true
en . 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 Resources o en una subcarpeta de la carpeta Resources . El archivo multimedia debe tener un
Build Action
deBundleResource
. - 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
deAndroidResource
. - En UWP, los archivos multimedia se pueden almacenar en cualquier carpeta del proyecto. El archivo multimedia debe tener un
BuildAction
deContent
.
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 DependencyService
a ella.
El servicio de dependencias de selección de vídeo que se usa en la aplicación de ejemplo es muy similar a uno definido en Seleccionar una foto de la biblioteca de imágenes, excepto 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 llamando 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án los medios 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 incluirá en la bandeja de letras, si es necesario, para ajustarse al área de visualizació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 enlazarse a datos a un Slider
control (o similar) para mostrar el progreso a través del medio. CommunityToolkit también proporciona un TimeSpanToDoubleConverter
objeto que convierte en TimeSpan
un valor de punto flotante que representa el total de segundos transcurridos. De este modo, puede establecer el control deslizante Maximum
en el de los Duration
medios y en Value
para Position
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
es 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:
Además, se usa un DataTrigger
objeto para deshabilitar Slider
cuando 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 general.
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 MediaSource
y esta clase define dos métodos estáticos:
FromFile
, devuelve unaMediaSource
instancia de unstring
argumento.FromUri
, devuelve unaMediaSource
instancia de unUri
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 string
Uri
.
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 unaUri
propiedad que se puede establecer en .Uri
FileMediaSource
, que se usa para especificar un archivo multimedia local de .string
Esta clase tiene unaFile
propiedad que se puede establecer en .string
Además, esta clase tiene operadores implícitos para convertir unstring
objeto en unFileMediaSource
objeto y unFileMediaSource
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 noMediaElement
contiene ningún medio.Opening
indica queMediaElement
está validando e intentando cargar el origen especificado.Buffering
indica queMediaElement
está cargando el medio para la reproducción. SuPosition
propiedad no avanza durante este estado.MediaElement
Si se estaba reproduciendo vídeo, continúa mostrando el último fotograma mostrado.Playing
indica queMediaElement
está reproduciendo el origen multimedia.Paused
indica que noMediaElement
avanza suPosition
propiedad.MediaElement
Si el objeto estaba reproduciendo vídeo, continúa mostrando el fotograma actual.Stopped
indica queMediaElement
contiene medios, pero no se está reproducendo ni en pausa. SuPosition
propiedad es 0 y no avanza. Si el medio cargado es vídeo,MediaElement
muestra 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 Play
los métodos , Pause
y Stop
.
En el ejemplo XAML siguiente se muestra una página que contiene controles MediaElement
de transporte personalizados 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="▶️ Play"
HorizontalOptions="CenterAndExpand"
Clicked="OnPlayPauseButtonClicked">
<Button.Triggers>
<DataTrigger TargetType="Button"
Binding="{Binding CurrentState}"
Value="{x:Static MediaElementState.Playing}">
<Setter Property="Text"
Value="⏸ Pause" />
</DataTrigger>
<DataTrigger TargetType="Button"
Binding="{Binding CurrentState}"
Value="{x:Static MediaElementState.Buffering}">
<Setter Property="IsEnabled"
Value="False" />
</DataTrigger>
</Button.Triggers>
</Button>
<Button Text="⏹ 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();
}
Se puede presionar el botón Reproducir , una vez habilitado, para comenzar la reproducción:
Al presionar el botón Pausar , se pausa la reproducción:
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 , Slider
como 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, cambiar la Value
propiedad dará como resultado 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 obtener más información sobre el uso de un Slider
control deslizante de Xamarin.Forms