Xamarin Community Toolkit MediaElement

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

MediaElement est une vue permettant de lire de la vidéo et de 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 schéma d’URI ms-appx:/// .
  • Fichiers qui proviennent des dossiers de données locaux et temporaires de l’application, à l’aide du schéma d’URI ms-appdata:/// .
  • Bibliothèque de l’appareil.

MediaElement peut utiliser les contrôles de lecture de plateforme, appelés contrôles de transport. Toutefois, ils sont désactivés par défaut et peuvent être remplacés 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 la plateforme :

Capture d’écran d’un élément 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 s’adapter à la zone d’affichage. La valeur par défaut de cette propriété est AspectFit.
  • AutoPlay, de type bool, indique si la lecture du mé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 la status actuelle 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, indique 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 allumé 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 tout au long du 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 courte période après avoir interagi avec l’écran. Il n’existe aucun moyen de maintenir les contrôles visibles en permanence. Sur WPF, aucun contrôle système n’est pris en charge. Cette propriété n’a donc 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 adossées à BindableProperty des objets, ce qui signifie qu’elles peuvent être des cibles de liaisons de données et avec un 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 le a fini de MediaElement lire son média.
  • MediaFailed est déclenché en cas d’erreur associée à la source du mé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 les Playméthodes , Pauseet Stop .

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 contenu multimé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 des médias, définissez la propriété sur AutoPlayfalse.

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é sur true. MediaElement utilise ensuite les contrôles de lecture de la plateforme lorsqu’ils sont disponibles.

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 schéma d’URI ms-appx:/// .
  • Fichiers qui proviennent des dossiers de données locaux et temporaires de l’application, à l’aide du schéma d’URI ms-appdata:/// .
  • Bibliothèque de l’appareil.

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

Lire du contenu multimé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 schéma d’URI ms-appx:/// . 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 Resources ou un sous-dossier du dossier Resources . Le fichier multimédia doit avoir la Build Action valeur BundleResource.
  • Sur Android, les fichiers multimédias doivent être stockés dans un sous-dossier de Ressources nommé raw. Le dossier raw ne peut pas contenir de sous-dossiers. Le fichier multimédia doit avoir la Build Action valeur AndroidResource.
  • Sur UWP, les fichiers multimédias peuvent être stockés dans n’importe quel dossier du projet. Le fichier multimédia doit avoir la BuildAction valeur 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 valeur 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 peut ensuite être utilisée pour appliquer le schéma d’URI ms-appx:/// à 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 du contenu multimédia à partir des dossiers locaux et temporaires de l’application

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

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

Outre la lecture des fichiers multimédias stockés dans les dossiers de données locaux ou temporaires de l’application, UWP peut également lire les fichiers multimédias qui se trouvent dans le dossier itinérant de l’application. Pour ce faire, préfixez le fichier multimédia avec ms-appdata:///roaming/.

Lors de l’utilisation de la liaison de données, un convertisseur de valeur 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 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 y soit copié par l’application. Pour ce faire, par exemple, copiez 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: File System Helpers.

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

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

Chacune des plateformes comprend une fonctionnalité 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ées 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 ce instance, et le nom de fichier retourné est utilisé pour créer un FileMediaSource objet et pour lui affecter la Source propriété du MediaElement.

Modifier les proportions de la vidéo

La Aspect propriété détermine comment le média vidéo sera 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 n’importe lequel des membres d’énumération Aspect :

  • AspectFit indique que la vidéo sera mise en boîte aux lettres, si nécessaire, pour s’adapter à la zone d’affichage, tout en conservant les proportions.
  • AspectFill indique que la vidéo sera clippée afin qu’elle remplit 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 pendant la lecture. Par conséquent, la propriété peut être liée aux données à un Slider contrôle (ou similaire) pour afficher la progression dans le média. CommunityToolkit fournit également un TimeSpanToDoubleConverter qui convertit un TimeSpan en une valeur à virgule flottante représentant le nombre total de secondes écoulées. De cette façon, vous pouvez définir le curseur Maximum sur le Duration du média et le Value sur pour Position 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 est Slider liée aux données à la Duration propriété du MediaElement et la Value propriété du Slider est liée aux données à la Position propriété du MediaElement. Par conséquent, faites glisser les Slider résultats dans la position de lecture du média en changeant :

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

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

Notes

Sur Android, le Slider seul a 1 000 étapes discrètes, quels que soient les Minimum paramètres et Maximum . Si la longueur du support est supérieure à 1 000 secondes, deux valeurs différentes Position correspondent à la même Value de .Slider C’est pourquoi le code ci-dessus vérifie que la nouvelle position et la position existante sont supérieures au centième de la durée totale.

Comprendre les types MediaSource

Un MediaElement peut lire un média 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 string arguments et Uri .

Notes

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

La MediaSource classe a é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. En outre, cette classe a des opérateurs implicites pour convertir un FileMediaSourcestring en objet et un FileMediaSource objet en string.

Notes

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

Déterminer l’status 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 la status actuelle du contrôle, par exemple si le média est en cours de 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 ne MediaElement contient aucun média.
  • Opening indique que le MediaElement est en cours de validation et tente de charger la source spécifiée.
  • Buffering indique que le MediaElement charge le média pour la lecture. Sa Position propriété n’avance pas pendant cet état. Si le MediaElement était en train de lire la vidéo, il continue d’afficher le dernier cadre affiché.
  • Playing indique que est en train de MediaElement lire la source multimédia.
  • Paused indique que le n’avance MediaElement pas sa Position propriété. Si le MediaElement était en train de lire la vidéo, il continue d’afficher l’image actuelle.
  • Stopped indique que contient le MediaElement média, mais qu’il n’est pas lu ou mis en pause. Sa Position propriété est 0 et n’avance pas. Si le média chargé est vidéo, affiche MediaElement la première image.

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 le MediaElement par programmation ou en fournissant vos propres contrôles de transport. Pour prendre en charge cela, MediaElement inclut les Playméthodes , Pauseet Stop .

L’exemple XAML suivant montre une page qui contient un MediaElement et des 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’y a que deux Button objets, 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 pour les 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();
}

Une fois activé, vous pouvez appuyer sur le bouton Lire pour commencer la lecture :

Capture d’écran d’un élément 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 la lecture :

Capture d’écran d’un élément MediaElement avec la 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 leur 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 Slider curseur Xamarin.Forms