Xamarin Community Toolkit MediaElement

Scaricare l'esempio. Scaricare l'esempio

MediaElement è una visualizzazione per la riproduzione di video e audio. I supporti supportati dalla piattaforma sottostante possono essere riprodotti dalle origini seguenti:

  • Il Web, usando un URI (HTTP o HTTPS).
  • Una risorsa incorporata nell'applicazione della piattaforma, usando lo ms-appx:/// schema URI.
  • File provenienti dalle cartelle dati locali e temporanee dell'app, usando lo ms-appdata:/// schema URI.
  • Libreria del dispositivo.

MediaElement può usare i controlli di riproduzione della piattaforma, definiti controlli di trasporto. Tuttavia, sono disabilitati per impostazione predefinita e possono essere sostituiti con i propri controlli di trasporto. Gli screenshot seguenti mostrano MediaElement la riproduzione di un video con i controlli di trasporto della piattaforma:

Screenshot di un oggetto MediaElement che riproduce un video in iOS e Android.

Nota

MediaElementè disponibile in iOS, Android, il piattaforma UWP (Universal Windows Platform) (UWP), macOS, Windows Presentation Foundation e Tizen.

MediaElement definisce le proprietà seguenti:

  • Aspect, di tipo Aspect, determina il modo in cui il supporto verrà ridimensionato per adattarsi all'area di visualizzazione. Il valore predefinito di questa proprietà è AspectFit.
  • AutoPlay, di tipo bool, indica se la riproduzione multimediale inizierà automaticamente quando viene impostata la Source proprietà . Il valore predefinito di questa proprietà è true.
  • BufferingProgress, di tipo double, indica lo stato di avanzamento del buffering corrente. Il valore predefinito di questa proprietà è 0,0.
  • CanSeek, di tipo bool, indica se i supporti possono essere riposizionati impostando il valore della Position proprietà . Questa proprietà è di sola lettura.
  • CurrentState, di tipo MediaElementState, indica lo stato corrente del controllo . Si tratta di una proprietà di sola lettura, il cui valore predefinito è MediaElementState.Closed.
  • Duration, di tipo TimeSpan?, indica la durata del supporto attualmente aperto. Si tratta di una proprietà di sola lettura il cui valore predefinito è null.
  • IsLooping, di tipo bool, indica se l'origine multimediale attualmente caricata deve riprendere la riproduzione dall'inizio dopo aver raggiunto la fine. Il valore predefinito di questa proprietà è false.
  • KeepScreenOn, di tipo bool, determina se la schermata del dispositivo deve rimanere attiva durante la riproduzione multimediale. Il valore predefinito di questa proprietà è false.
  • Position, di tipo TimeSpan, descrive lo stato di avanzamento corrente attraverso il tempo di riproduzione del supporto. Questa proprietà usa un'associazione TwoWay e il relativo valore predefinito è TimeSpan.Zero.
  • ShowsPlaybackControls, di tipo bool, determina se vengono visualizzati i controlli di riproduzione delle piattaforme. Il valore predefinito di questa proprietà è false. Si noti che in iOS i controlli vengono visualizzati solo per un breve periodo dopo l'interazione con lo schermo. Non è possibile mantenere sempre visibili i controlli. In WPF non sono supportati controlli di sistema, pertanto questa proprietà non ha alcun effetto.
  • Speed, di tipo double, determina la velocità di riproduzione del supporto. Il valore predefinito di questa proprietà è 1.
  • Source, di tipo MediaSource, indica l'origine del supporto caricato nel controllo .
  • VideoHeight, di tipo int, indica l'altezza del controllo . Questa proprietà è di sola lettura.
  • VideoWidth, di tipo int, indica la larghezza del controllo. Questa proprietà è di sola lettura.
  • Volume, di tipo double, determina il volume del supporto, rappresentato su una scala lineare compresa tra 0 e 1. Questa proprietà usa un'associazione TwoWay e il relativo valore predefinito è 1.

Queste proprietà, ad eccezione della CanSeek proprietà , sono supportate da BindableProperty oggetti , il che significa che possono essere destinazioni di data binding e stili.

La MediaElement classe definisce anche quattro eventi:

  • MediaOpened viene generato quando il flusso multimediale è stato convalidato e aperto.
  • MediaEnded viene generato al termine della riproduzione del MediaElement supporto.
  • MediaFailed viene generato quando si verifica un errore associato all'origine multimediale.
  • SeekCompleted viene generato quando il punto di ricerca di un'operazione di ricerca richiesta è pronto per la riproduzione.

Include anche MediaElementPlayi metodi , Pausee Stop .

Per informazioni sui formati multimediali supportati in Android, vedere Formati multimediali supportati in developer.android.com. Per informazioni sui formati multimediali supportati nel piattaforma UWP (Universal Windows Platform) (UWP), vedi Codec supportati.

Riprodurre supporti remoti

Un MediaElement oggetto può riprodurre file multimediali remoti usando gli schemi URI HTTP e HTTPS. Questa operazione viene eseguita impostando la Source proprietà sull'URI del file multimediale:

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

Per impostazione predefinita, il supporto definito dalla Source proprietà viene riprodotto immediatamente dopo l'apertura del supporto. Per eliminare la riproduzione automatica dei contenuti multimediali, impostare la AutoPlay proprietà su false.

I controlli di riproduzione multimediale sono disabilitati per impostazione predefinita e sono abilitati impostando la ShowsPlaybackControls proprietà su true. MediaElement userà quindi i controlli di riproduzione della piattaforma, se disponibili.

Riprodurre file multimediali locali

I supporti locali possono essere riprodotti dalle origini seguenti:

  • Una risorsa incorporata nell'applicazione della piattaforma, usando lo ms-appx:/// schema URI.
  • File provenienti dalle cartelle dati locali e temporanee dell'app, usando lo ms-appdata:/// schema URI.
  • Libreria del dispositivo.

Per altre informazioni su questi schemi URI, vedere Schemi URI.

Riprodurre contenuti multimediali incorporati nel pacchetto dell'app

Un MediaElement oggetto può riprodurre file multimediali incorporati nel pacchetto dell'app, usando lo ms-appx:/// schema URI. I file multimediali vengono incorporati nel pacchetto dell'app inserendoli nel progetto della piattaforma.

L'archiviazione di un file multimediale nel progetto della piattaforma è diversa per ogni piattaforma:

  • In iOS i file multimediali devono essere archiviati nella cartella Resources o in una sottocartella della cartella Resources . Il file multimediale deve avere un oggetto Build Action .BundleResource
  • In Android, i file multimediali devono essere archiviati in una sottocartella di Risorse denominateraw. La cartella raw non può contenere sottocartelle. Il file multimediale deve avere un oggetto Build Action .AndroidResource
  • Nella piattaforma UWP i file multimediali possono essere archiviati in qualsiasi cartella del progetto. Il file multimediale deve avere un oggetto BuildAction .Content

I file multimediali che soddisfano questi criteri possono quindi essere riprodotti usando lo ms-appx:/// schema URI:

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

Quando si usa il data binding, è possibile usare un convertitore di valori per applicare questo schema 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}");
    }
    // ...
}

Un'istanza VideoSourceConverter di può quindi essere usata per applicare lo ms-appx:/// schema URI a un file multimediale incorporato:

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

Per altre informazioni sullo schema URI ms-appx, vedere ms-appx e ms-appx-web.

Riprodurre elementi multimediali dalle cartelle locali e temporanee dell'app

Un MediaElement oggetto può riprodurre file multimediali copiati nelle cartelle dati locali o temporanee dell'app, usando lo ms-appdata:/// schema URI.

L'esempio seguente mostra la Source proprietà impostata su un file multimediale archiviato nella cartella dati locale dell'app:

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

L'esempio seguente mostra la Source proprietà in un file multimediale archiviato nella cartella dei dati temporanei dell'app:

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

Importante

Oltre a riprodurre file multimediali archiviati nelle cartelle dati locali o temporanee dell'app, la piattaforma UWP può anche riprodurre file multimediali che si trovano nella cartella roaming dell'app. A tale scopo, è possibile anteporre al file ms-appdata:///roaming/multimediale il prefisso .

Quando si usa il data binding, è possibile usare un convertitore di valori per applicare questo schema 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}");
    }
    // ...
}

Un'istanza di VideoSourceConverter può quindi essere usata per applicare lo ms-appdata:/// schema URI a un file multimediale nella cartella dati locale o temporanea dell'app:

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

Per altre informazioni sullo schema URI ms-appdata, vedere ms-appdata.

Copia di un file multimediale nella cartella dati locale o temporanea dell'app

La riproduzione di un file multimediale archiviato nella cartella dati locale o temporanea dell'app richiede che il file multimediale venga copiato dall'app. A tale scopo, ad esempio, è possibile copiare un file multimediale dal pacchetto dell'app:

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

L'esempio di codice precedente usa la FileSystem classe inclusa in Xamarin.Essentials. Per altre informazioni, vedere Xamarin.Essentials: Helpers del file system.

Riprodurre supporti dalla libreria di dispositivi

La maggior parte dei dispositivi mobili moderni e dei computer desktop ha la possibilità di registrare video e audio usando la fotocamera e il microfono del dispositivo. I supporti creati vengono quindi archiviati come file nel dispositivo. Questi file possono essere recuperati dalla libreria e riprodotti da MediaElement.

Ognuna delle piattaforme include una struttura che consente all'utente di selezionare supporti dalla libreria del dispositivo. In Xamarin.Forms i progetti della piattaforma possono richiamare questa funzionalità e può essere chiamato dalla DependencyService classe.

Il servizio di dipendenza di selezione video usato nell'applicazione di esempio è molto simile a quello definito in Selezione di una foto dalla libreria immagini, ad eccezione del fatto che il selettore restituisce un nome file anziché un Stream oggetto. Il progetto di codice condiviso definisce un'interfaccia denominata IVideoPicker, che definisce un singolo metodo denominato GetVideoFileAsync. Ogni piattaforma implementa quindi questa interfaccia in una VideoPicker classe.

Nell'esempio di codice seguente viene illustrato come recuperare un file multimediale dalla libreria di dispositivi:

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

Il servizio di selezione delle dipendenze video viene richiamato chiamando il DependencyService.Get metodo per ottenere l'implementazione di un'interfaccia IVideoPicker nel progetto della piattaforma. Il GetVideoFileAsync metodo viene quindi chiamato su tale istanza e il nome file restituito viene usato per creare un FileMediaSource oggetto e impostarlo sulla Source proprietà dell'oggetto MediaElement.

Modifica del rapporto di aspetto video

La Aspect proprietà determina la scalabilità dei supporti video per adattare l'area di visualizzazione. Per impostazione predefinita, questa proprietà è impostata sul membro di enumerazione, ma può essere impostata su uno dei membri dell'enumerazione AspectFitAspect :

  • AspectFit indica che il video verrà posta in arrivo, se necessario, per adattarsi all'area di visualizzazione, mantenendo il rapporto di aspetto.
  • AspectFill indica che il video verrà ritagliato in modo che riempia l'area di visualizzazione, mantenendo il rapporto di aspetto.
  • Fill indica che il video verrà esteso per riempire l'area di visualizzazione.

Associazione alla proprietà Position

La notifica di modifica della proprietà per la proprietà associabile viene attivata a intervalli di 200ms durante la Position riproduzione. Pertanto, la proprietà può essere associata a un Slider controllo (o simile) per visualizzare lo stato di avanzamento tramite i supporti. CommunityToolkit fornisce anche un oggetto che converte un TimeSpanToDoubleConverterTimeSpan in un valore a virgola mobile che rappresenta i secondi totali trascorsi. In questo modo è possibile impostare il dispositivo di scorrimento Maximum sul supporto e sull'oggetto DurationValue per Position fornire lo stato di avanzamento accurato:

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

In questo esempio la proprietà dell'oggetto Slider è associata alla proprietà dell'oggetto MediaElement e la Value proprietà dell'oggetto Slider è associata alla DurationPosition proprietà dell'oggetto MediaElement.Maximum Pertanto, trascinando i Slider risultati nella posizione di riproduzione multimediale che cambia:

Screenshot di MediaElement con una barra di posizione, in iOS e Android.

Inoltre, un DataTrigger oggetto viene usato per disabilitare l'oggetto Slider quando il supporto è buffering. Per altre informazioni sui trigger di dati, vedere Trigger Xamarin.Forms.

Nota

In Android l'unico Slider passaggio discreto è 1000, indipendentemente dalle Minimum impostazioni e Maximum . Se la lunghezza del supporto è maggiore di 1000 secondi, due valori diversi Position corrispondono allo stesso Value oggetto .Slider Questo è il motivo per cui il codice precedente verifica che la nuova posizione e la posizione esistente siano maggiori di un centesimo della durata complessiva.

Informazioni sui tipi MediaSource

Un MediaElement oggetto può riprodurre supporti impostandone la Source proprietà su un file multimediale remoto o locale. La Source proprietà è di tipo MediaSourcee questa classe definisce due metodi statici:

  • FromFile, restituisce un'istanza MediaSource da un string argomento.
  • FromUri, restituisce un'istanza MediaSource da un Uri argomento.

Inoltre, la MediaSource classe include operatori impliciti che restituiscono MediaSource istanze da string e Uri argomenti.

Nota

Quando la proprietà è impostata in XAML, viene richiamato un convertitore di tipi per restituire un'istanza SourceMediaSource da un string oggetto o Uri.

La MediaSource classe include anche due classi derivate:

  • UriMediaSource, utilizzato per specificare un file multimediale remoto da un URI. Questa classe ha una Uri proprietà che può essere impostata su un Urioggetto .
  • FileMediaSource, che viene usato per specificare un file multimediale locale da un stringoggetto . Questa classe ha una File proprietà che può essere impostata su un stringoggetto . Inoltre, questa classe include operatori impliciti per convertire un string oggetto in un FileMediaSource oggetto e un FileMediaSource oggetto in un stringoggetto .

Nota

Quando un oggetto viene creato in XAML, viene richiamato un FileMediaSource convertitore di tipi per restituire un'istanza FileMediaSource da un stringoggetto .

Determinare lo stato di MediaElement

La MediaElement classe definisce una proprietà associabile di sola lettura denominata CurrentState, di tipo MediaElementState. Questa proprietà indica lo stato corrente del controllo, ad esempio se il supporto è in riproduzione o sospeso o se non è ancora pronto per riprodurre i supporti.

L'enumerazione MediaElementState definisce i membri seguenti:

  • Closed indica che l'oggetto MediaElement non contiene supporti.
  • Opening indica che la convalida e il MediaElement tentativo di caricare l'origine specificata.
  • Buffering indica che il caricamento del MediaElement supporto per la riproduzione. La proprietà Position non avanza durante questo stato. Se il MediaElement video è stato riprodotto, continua a visualizzare l'ultima cornice visualizzata.
  • Playing indica che l'oggetto sta riproducendo l'origine MediaElement multimediale.
  • Paused indica che la MediaElement proprietà Position non viene avanzata. Se il MediaElement video è stato riprodotto, continua a visualizzare il frame corrente.
  • Stopped indica che l'oggetto MediaElement contiene supporti, ma non viene riprodotto o sospeso. La sua Position proprietà è 0 e non avanza. Se il supporto caricato è video, viene MediaElement visualizzato il primo fotogramma.

In genere non è necessario esaminare la CurrentState proprietà quando si usano i MediaElement controlli di trasporto. Tuttavia, questa proprietà diventa importante quando si implementano i propri controlli di trasporto.

Implementare controlli di trasporto personalizzati

I controlli di trasporto di un lettore multimediale includono i pulsanti che eseguono le funzioni Play, Pause e Stop. Questi pulsanti sono identificati in genere con icone note anziché testo e le funzioni di riproduzione e pausa sono in genere unite in un unico pulsante.

Per impostazione predefinita, i MediaElement controlli di riproduzione sono disabilitati. In questo modo è possibile controllare a livello di MediaElement codice o fornire i propri controlli di trasporto. A supporto di questo, MediaElement include Play, Pausee Stop metodi.

L'esempio XAML seguente mostra una pagina che contiene MediaElement controlli di trasporto personalizzati e:

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

In questo esempio i controlli di trasporto personalizzati sono definiti come Button oggetti. Tuttavia, sono presenti solo due Button oggetti, con il primo Button che rappresenta Play e Pause e il secondo Button che rappresenta Stop. DataTrigger gli oggetti vengono usati per abilitare e disabilitare i pulsanti e per passare il primo pulsante tra Play e Pause. Per altre informazioni sui trigger di dati, vedere Trigger Xamarin.Forms.

Il file code-behind include i gestori per gli Clicked eventi:

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

Il pulsante Play può essere premuto, una volta abilitato, per avviare la riproduzione:

Screenshot di mediaElement con controlli di trasporto personalizzati, in iOS e Android.

Premendo il pulsante Pausa viene restituita la sospensione della riproduzione:

Screenshot di MediaElement con riproduzione sospesa, in iOS e Android.

Premendo il pulsante Arresta la riproduzione e restituisce la posizione del file multimediale all'inizio.

Implementare un controllo volume personalizzato

I controlli di riproduzione multimediale implementati da ogni piattaforma includono una barra del volume. Questa barra è simile a un dispositivo di scorrimento e mostra il volume del supporto. È inoltre possibile modificare la barra del volume per aumentare o ridurre il volume.

È possibile implementare una barra del volume personalizzata usando un Slideroggetto , come illustrato nell'esempio seguente:

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

In questo esempio, i Slider dati associano la Volume relativa Value proprietà alla proprietà di MediaElement. Ciò è possibile perché la proprietà usa un'associazione VolumeTwoWay . Pertanto, la modifica della Value proprietà comporta la modifica della Volume proprietà.

Nota

La Volume proprietà ha un callback di convalida che garantisce che il relativo valore sia maggiore o uguale a 0,0 e minore o uguale a 1,0.

Per altre informazioni sull'uso di un Slider dispositivo di scorrimento di Xamarin.Forms