Xamarin Community Toolkit MediaElement

Télécharger l’exemple. Télécharger l’exemple

MediaElement est une vue pour lire la vidéo et l’audio. Les médias pris en charge par la plateforme sous-jacente peuvent être lus à partir des sources suivantes :

  • Le web, à l’aide d’un URI (HTTP ou HTTPS).
  • Ressource incorporée dans l’application de plateforme, à l’aide du ms-appx:/// schéma d’URI.
  • Fichiers provenant des dossiers de données locaux et temporaires de l’application, à l’aide du ms-appdata:/// schéma d’URI.
  • Bibliothèque de l’appareil.

MediaElement peut utiliser les contrôles de lecture de plateforme, appelés contrôles de transport. Toutefois, elles sont désactivées par défaut et peuvent être remplacées par vos propres contrôles de transport. Les captures d’écran suivantes montrent MediaElement la lecture d’une vidéo avec les contrôles de transport de plateforme :

Capture d’écran d’un MediaElement qui lit une vidéo, sur iOS et Android.

Notes

MediaElementest disponible sur iOS, Android, le plateforme Windows universelle (UWP), macOS, Windows Presentation Foundation et Tizen.

MediaElement définit les propriétés suivantes :

  • Aspect, de type Aspect, détermine la façon dont le média sera mis à l’échelle pour ajuster la zone d’affichage. La valeur par défaut de cette propriété est AspectFit.
  • AutoPlay, de type bool, indique si la lecture multimédia commence automatiquement lorsque la Source propriété est définie. La valeur par défaut de cette propriété est true.
  • BufferingProgress, de type double, indique la progression actuelle de la mise en mémoire tampon. La valeur par défaut de cette propriété est 0.0.
  • CanSeek, de type bool, indique si le média peut être repositionné en définissant la valeur de la Position propriété. Il s’agit d’une propriété en lecture seule.
  • CurrentState, de type MediaElementState, indique l’état actuel du contrôle. Il s’agit d’une propriété en lecture seule, dont la valeur par défaut est MediaElementState.Closed.
  • Duration, de type TimeSpan?, indique la durée du média actuellement ouvert. Il s’agit d’une propriété en lecture seule dont la valeur par défaut est null.
  • IsLooping, de type bool, décrit si la source multimédia actuellement chargée doit reprendre la lecture à partir du début après avoir atteint sa fin. La valeur par défaut de cette propriété est false.
  • KeepScreenOn, de type bool, détermine si l’écran de l’appareil doit rester activé pendant la lecture multimédia. La valeur par défaut de cette propriété est false.
  • Position, de type TimeSpan, décrit la progression actuelle via le temps de lecture du média. Cette propriété utilise une TwoWay liaison et sa valeur par défaut est TimeSpan.Zero.
  • ShowsPlaybackControls, de type bool, détermine si les contrôles de lecture des plateformes sont affichés. La valeur par défaut de cette propriété est false. Notez que sur iOS, les contrôles ne sont affichés que pendant une brève période après l’interaction avec l’écran. Il n’existe aucun moyen de garder les contrôles visibles à tout moment. Sur WPF, aucun contrôle système n’est pris en charge afin que cette propriété n’ait aucun effet.
  • Speed, de type double, détermine la vitesse de lecture du média. La valeur par défaut de cette propriété est 1.
  • Source, de type MediaSource, indique la source du média chargé dans le contrôle.
  • VideoHeight, de type int, indique la hauteur du contrôle. Il s’agit d’une propriété en lecture seule.
  • VideoWidth, de type int, indique la largeur du contrôle. Il s’agit d’une propriété en lecture seule.
  • Volume, de type double, détermine le volume du média, qui est représenté sur une échelle linéaire comprise entre 0 et 1. Cette propriété utilise une TwoWay liaison et sa valeur par défaut est 1.

Ces propriétés, à l’exception de la CanSeek propriété, sont sauvegardées par BindableProperty des objets, ce qui signifie qu’elles peuvent être des cibles de liaisons de données et de style.

La MediaElement classe définit également quatre événements :

  • MediaOpened est déclenché lorsque le flux multimédia a été validé et ouvert.
  • MediaEnded est déclenché lorsque la fin de la MediaElement lecture de son média est terminée.
  • MediaFailed est déclenché lorsqu’une erreur est associée à la source multimédia.
  • SeekCompleted est déclenché lorsque le point de recherche d’une opération de recherche demandée est prêt pour la lecture.

En outre, MediaElement inclut Play, Pauseet Stop méthodes.

Pour plus d’informations sur les formats multimédias pris en charge sur Android, consultez Formats multimédias pris en charge sur developer.android.com. Pour plus d’informations sur les formats multimédias pris en charge sur le plateforme Windows universelle (UWP), consultez Codecs pris en charge.

Lire le média distant

Un MediaElement peut lire des fichiers multimédias distants à l’aide des schémas d’URI HTTP et HTTPS. Pour ce faire, définissez la Source propriété sur l’URI du fichier multimédia :

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

Par défaut, le média défini par la Source propriété est lu immédiatement après l’ouverture du média. Pour supprimer la lecture automatique du média, définissez la AutoPlay propriété sur false.

Les contrôles de lecture multimédia sont désactivés par défaut et sont activés en définissant la ShowsPlaybackControls propriété truesur . MediaElement utilisera ensuite les contrôles de lecture de la plateforme où il est disponible.

Lire le média local

Les médias locaux peuvent être lus à partir des sources suivantes :

  • Ressource incorporée dans l’application de plateforme, à l’aide du ms-appx:/// schéma d’URI.
  • Fichiers provenant des dossiers de données locaux et temporaires de l’application, à l’aide du ms-appdata:/// schéma d’URI.
  • Bibliothèque de l’appareil.

Pour plus d’informations sur ces schémas d’URI, consultez schémas d’URI.

Lire le média incorporé dans le package d’application

Un MediaElement peut lire des fichiers multimédias incorporés dans le package d’application, à l’aide du ms-appx:/// schéma d’URI. Les fichiers multimédias sont incorporés dans le package d’application en les plaçant dans le projet de plateforme.

Le stockage d’un fichier multimédia dans le projet de plateforme est différent pour chaque plateforme :

  • Sur iOS, les fichiers multimédias doivent être stockés dans le dossier Ressources ou un sous-dossier du dossier Ressources . Le fichier multimédia doit avoir un Build Action de BundleResource.
  • Sur Android, les fichiers multimédias doivent être stockés dans un sous-dossier des ressourcesnommées brutes. Le dossier raw ne peut pas contenir de sous-dossiers. Le fichier multimédia doit avoir un Build Action de AndroidResource.
  • Sur UWP, les fichiers multimédias peuvent être stockés dans n’importe quel dossier du projet. Le fichier multimédia doit avoir un BuildAction de Content.

Les fichiers multimédias qui répondent à ces critères peuvent ensuite être lus à l’aide du schéma d’URI ms-appx:/// :

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

Lors de l’utilisation de la liaison de données, un convertisseur de valeurs peut être utilisé pour appliquer ce schéma d’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}");
    }
    // ...
}

Une instance du VideoSourceConverter fichier multimédia incorporé peut ensuite être utilisée pour appliquer le ms-appx:/// schéma d’URI à un fichier multimédia incorporé :

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

Pour plus d’informations sur le schéma d’URI ms-appx, consultez ms-appx et ms-appx-web.

Lire les médias à partir des dossiers locaux et temporaires de l’application

Un MediaElement peut lire des fichiers multimédias copiés dans les dossiers de données locaux ou temporaires de l’application à l’aide du ms-appdata:/// schéma d’URI.

L’exemple suivant montre la Source propriété définie sur un fichier multimédia stocké dans le dossier de données local de l’application :

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

L’exemple suivant montre la Source propriété dans un fichier multimédia stocké dans le dossier de données temporaires de l’application :

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

Important

En plus de lire des fichiers multimédias stockés dans les dossiers de données locaux ou temporaires de l’application, UWP peut également lire des fichiers multimédias situés dans le dossier itinérant de l’application. Cela peut être obtenu en préfixant le fichier multimédia avec ms-appdata:///roaming/.

Lors de l’utilisation de la liaison de données, un convertisseur de valeurs peut être utilisé pour appliquer ce schéma d’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}");
    }
    // ...
}

Une instance du VideoSourceConverter fichier peut ensuite être utilisée pour appliquer le ms-appdata:/// schéma d’URI à un fichier multimédia dans le dossier de données local ou temporaire de l’application :

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

Pour plus d’informations sur le schéma d’URI ms-appdata, consultez ms-appdata.

Copie d’un fichier multimédia dans le dossier de données local ou temporaire de l’application

La lecture d’un fichier multimédia stocké dans le dossier de données local ou temporaire de l’application nécessite que le fichier multimédia soit copié par l’application. Cela peut être accompli, par exemple, en copiant un fichier multimédia à partir du package d’application :

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

Notes

L’exemple de code ci-dessus utilise la FileSystem classe incluse dans Xamarin.Essentials. Pour plus d’informations, consultez Xamarin.Essentials : Helpers du système de fichiers.

Lire le média à partir de la bibliothèque d’appareils

La plupart des appareils mobiles modernes et des ordinateurs de bureau ont la possibilité d’enregistrer des vidéos et du son à l’aide de la caméra et du microphone de l’appareil. Les supports créés sont ensuite stockés en tant que fichiers sur l’appareil. Ces fichiers peuvent être récupérés à partir de la bibliothèque et lus par le MediaElement.

Chacune des plateformes comprend une installation qui permet à l’utilisateur de sélectionner des médias dans la bibliothèque de l’appareil. Dans Xamarin.Forms, les projets de plateforme peuvent appeler cette fonctionnalité et peuvent être appelés par la DependencyService classe.

Le service de dépendance de sélection vidéo utilisé dans l’exemple d’application est très similaire à celui défini dans La sélection d’une photo à partir de la bibliothèque d’images, sauf que le sélecteur retourne un nom de fichier plutôt qu’un Stream objet. Le projet de code partagé définit une interface nommée IVideoPicker, qui définit une méthode unique nommée GetVideoFileAsync. Chaque plateforme implémente ensuite cette interface dans une VideoPicker classe.

L’exemple de code suivant montre comment récupérer un fichier multimédia à partir de la bibliothèque d’appareils :

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

Le service de dépendance de sélection vidéo est appelé en appelant la DependencyService.Get méthode pour obtenir l’implémentation d’une IVideoPicker interface dans le projet de plateforme. La GetVideoFileAsync méthode est ensuite appelée sur cette instance, et le nom de fichier retourné est utilisé pour créer un FileMediaSource objet et pour le définir sur la Source propriété du MediaElement.

Modifier les proportions vidéo

La Aspect propriété détermine la façon dont les médias vidéo seront mis à l’échelle pour s’adapter à la zone d’affichage. Par défaut, cette propriété est définie sur le AspectFit membre d’énumération, mais elle peut être définie sur l’un des membres d’énumération Aspect :

  • AspectFit indique que la vidéo sera boîte à lettres, si nécessaire, pour s’adapter à la zone d’affichage, tout en conservant les proportions.
  • AspectFill indique que la vidéo sera découpée afin qu’elle remplisse la zone d’affichage, tout en conservant les proportions.
  • Fill indique que la vidéo sera étirée pour remplir la zone d’affichage.

Liaison à la propriété Position

La notification de modification de propriété pour la Position propriété pouvant être liée se déclenche à intervalles de 200 ms lors de la lecture. Par conséquent, la propriété peut être liée aux données d’un Slider contrôle (ou similaire) pour afficher la progression via le média. CommunityToolkit fournit également une TimeSpanToDoubleConverter valeur à virgule flottante qui TimeSpan représente le nombre total de secondes écoulées. De cette façon, vous pouvez définir le curseur Maximum sur le Duration média et sur celui-ci PositionValue pour fournir une progression précise :

<?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>

Dans cet exemple, la Maximum propriété de l’objet Slider est liée aux données à la Duration propriété de l’objet MediaElement et la Value propriété de celle-ci Slider est liée aux données à la Position propriété du MediaElement. Par conséquent, le fait de faire glisser les Slider résultats dans la position de lecture multimédia change :

Capture d’écran d’un MediaElement avec une barre de position, sur iOS et Android.

En outre, un DataTrigger objet est utilisé pour désactiver le Slider moment où le média effectue la mise en mémoire tampon. Pour plus d’informations sur les déclencheurs de données, consultez Déclencheurs Xamarin.Forms.

Notes

Sur Android, la Slider seule étape de 1 000 étapes discrètes, indépendamment des paramètres et Maximum des Minimum paramètres. Si la longueur du support est supérieure à 1 000 secondes, deux valeurs différentes Position correspondent à la Slidermême Value valeur . C’est pourquoi le code ci-dessus vérifie que la nouvelle position et la position existante sont supérieures à un centième de la durée globale.

Comprendre les types MediaSource

Un MediaElement média peut être lu en définissant sa Source propriété sur un fichier multimédia distant ou local. La Source propriété est de type MediaSource, et cette classe définit deux méthodes statiques :

  • FromFile, retourne une MediaSource instance à partir d’un string argument.
  • FromUri, retourne une MediaSource instance à partir d’un Uri argument.

En outre, la MediaSource classe a également des opérateurs implicites qui retournent MediaSource des instances à partir des arguments et Uri des string arguments.

Notes

Lorsque la Source propriété est définie en XAML, un convertisseur de type est appelé pour retourner une MediaSource instance à partir d’un string ou Uri.

La MediaSource classe possède également deux classes dérivées :

  • UriMediaSource, qui est utilisé pour spécifier un fichier multimédia distant à partir d’un URI. Cette classe a une Uri propriété qui peut être définie sur un Uri.
  • FileMediaSource, qui est utilisé pour spécifier un fichier multimédia local à partir d’un string. Cette classe a une File propriété qui peut être définie sur un string. De plus, cette classe a des opérateurs implicites pour convertir un stringFileMediaSource objet en objet et un FileMediaSource objet en un string.

Notes

Lorsqu’un FileMediaSource objet est créé en XAML, un convertisseur de type est appelé pour retourner une FileMediaSource instance à partir d’un string.

Déterminer l’état de MediaElement

La MediaElement classe définit une propriété pouvant être liée en lecture seule nommée CurrentState, de type MediaElementState. Cette propriété indique l’état actuel du contrôle, par exemple si le média est en lecture ou en pause, ou s’il n’est pas encore prêt à lire le média.

L’énumération MediaElementState définit les membres suivants :

  • Closed indique que le MediaElement support ne contient aucun média.
  • Opening indique que la MediaElement validation et la tentative de chargement de la source spécifiée sont effectuées.
  • Buffering indique que le MediaElement support est chargé pour la lecture. Sa Position propriété n’avance pas pendant cet état. Si la MediaElement vidéo était en cours de lecture, elle continue d’afficher le dernier cadre affiché.
  • Playing indique que la MediaElement source multimédia est en lecture.
  • Paused indique que la MediaElement propriété n’avance Position pas. Si la MediaElement vidéo était en cours de lecture, elle continue d’afficher l’image actuelle.
  • Stopped indique que le MediaElement média contient, mais qu’il n’est pas lu ou suspendu. Sa Position propriété est 0 et n’avance pas. Si le média chargé est vidéo, le MediaElement premier image s’affiche.

Il n’est généralement pas nécessaire d’examiner la CurrentState propriété lors de l’utilisation des contrôles de MediaElement transport. Toutefois, cette propriété devient importante lors de l’implémentation de vos propres contrôles de transport.

Implémenter des contrôles de transport personnalisés

Les contrôles de transport d’un lecteur multimédia incluent les boutons qui exécutent les fonctions Lecture, Pause et Arrêt. Ces boutons sont habituellement identifiés par des icônes familières plutôt que du texte, et les fonctions Lecture et Pause sont généralement combinées en un seul bouton.

Par défaut, les contrôles de MediaElement lecture sont désactivés. Cela vous permet de contrôler par MediaElement programmation ou en fournissant vos propres contrôles de transport. Pour ce faire, inclut Play, MediaElementPauseet Stop les méthodes.

L’exemple XAML suivant montre une page qui contient des MediaElement contrôles de transport personnalisés :

<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>

Dans cet exemple, les contrôles de transport personnalisés sont définis en tant qu’objets Button . Toutefois, il n’existe que deux Button objets, avec le premier Button représentant Play et Pause, et le second Button représentant Stop. DataTrigger les objets sont utilisés pour activer et désactiver les boutons, et pour basculer le premier bouton entre Lecture et Pause. Pour plus d’informations sur les déclencheurs de données, consultez Déclencheurs Xamarin.Forms.

Le fichier code-behind contient les gestionnaires des Clicked événements :

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

Le bouton Lecture peut être enfoncé, une fois qu’il est activé, pour commencer la lecture :

Capture d’écran d’un MediaElement avec des contrôles de transport personnalisés, sur iOS et Android.

Le fait d’appuyer sur le bouton Suspendre entraîne la suspension de lecture :

Capture d’écran d’un MediaElement avec lecture suspendue, sur iOS et Android.

Le fait d’appuyer sur le bouton Arrêter arrête la lecture et retourne la position du fichier multimédia au début.

Implémenter un contrôle de volume personnalisé

Les contrôles de lecture multimédia implémentés par chaque plateforme incluent une barre de volume. Cette barre ressemble à un curseur et affiche le volume du média. En outre, vous pouvez manipuler la barre de volume pour augmenter ou diminuer le volume.

Une barre de volume personnalisée peut être implémentée à l’aide d’un Slider, comme illustré dans l’exemple suivant :

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

Dans cet exemple, les Slider données lient sa Value propriété à la Volume propriété du MediaElement. Cela est possible, car la Volume propriété utilise une TwoWay liaison. Par conséquent, la modification de la Value propriété entraîne la modification de la Volume propriété.

Notes

La Volume propriété a un rappel de validation qui garantit que sa valeur est supérieure ou égale à 0,0, et inférieure ou égale à 1,0.

Pour plus d’informations sur l’utilisation d’un Slidercurseur Xamarin.Forms