Xamarin Community Toolkit MediaElement
MediaElement
— это представление для воспроизведения видео и звука. Мультимедиа, поддерживаемые базовой платформой, можно воспроизводить из следующих источников:
- Веб-сайт с использованием URI (HTTP или HTTPS).
- Ресурс, внедренный в приложение платформы с использованием
ms-appx:///
схемы URI. - Файлы, поступающие из локальных и временных папок данных приложения, используя схему
ms-appdata:///
URI. - Библиотека устройства.
MediaElement
может использовать элементы управления воспроизведением платформы, которые называются элементами управления транспортировкой. Однако они отключены по умолчанию и могут быть заменены собственными элементами управления транспортировкой. На следующих снимках экрана показано MediaElement
воспроизведение видео с элементами управления транспортировкой платформы:
Примечание
MediaElement
доступен в iOS, Android, универсальная платформа Windows (UWP), macOS, Windows Presentation Foundation и Tizen.
MediaElement
определяет следующие свойства:
Aspect
с типомAspect
определяет, как будет масштабироваться носитель в соответствии с областью отображения. Значение по умолчанию этого свойства равноAspectFit
.AutoPlay
с типомbool
указывает, начнется ли воспроизведение мультимедиа автоматически приSource
установке свойства . Значение по умолчанию этого свойства равноtrue
.BufferingProgress
с типомdouble
указывает текущий ход выполнения буферизации. Значение этого свойства по умолчанию — 0,0.CanSeek
с типомbool
указывает, можно ли изменить положение носителя, задав значениеPosition
свойства . Это свойство доступно только для чтения.CurrentState
с типомMediaElementState
указывает текущее состояние элемента управления. Это свойство доступно только для чтения, значение по умолчанию —MediaElementState.Closed
.Duration
с типомTimeSpan?
указывает продолжительность открытого в данный момент носителя. Это свойство, доступное только для чтения, значением по умолчанию являетсяnull
.IsLooping
с типомbool
описывает, должен ли загруженный в данный момент источник мультимедиа возобновлять воспроизведение с начала после достижения его окончания. Значение по умолчанию этого свойства равноfalse
.KeepScreenOn
с типомbool
определяет, должен ли экран устройства оставаться включен во время воспроизведения мультимедиа. Значение по умолчанию этого свойства равноfalse
.Position
с типомTimeSpan
описывает текущий ход выполнения во время воспроизведения мультимедиа. Это свойство использует привязкуTwoWay
и имеет значение по умолчанию .TimeSpan.Zero
ShowsPlaybackControls
с типомbool
определяет, отображаются ли элементы управления воспроизведением платформ. Значение по умолчанию этого свойства равноfalse
. Обратите внимание, что в iOS элементы управления отображаются только в течение короткого периода после взаимодействия с экраном. Элементы управления не могут быть видимыми в любое время. В WPF системные элементы управления не поддерживаются, поэтому это свойство не оказывает никакого влияния.Speed
с типомdouble
определяет скорость воспроизведения мультимедиа. Значение этого свойства по умолчанию равно 1.Source
с типомMediaSource
указывает источник носителя, загруженного в элемент управления .VideoHeight
с типомint
указывает высоту элемента управления. Это свойство доступно только для чтения.VideoWidth
с типомint
указывает ширину элемента управления . Это свойство доступно только для чтения.Volume
с типомdouble
определяет объем носителя, который представлен в линейной шкале от 0 до 1. Это свойство использует привязкуTwoWay
и имеет значение по умолчанию 1.
Эти свойства, за исключением CanSeek
свойства , поддерживаются объектами BindableProperty
, что означает, что они могут быть целевыми объектами привязок данных и стили.
Класс MediaElement
также определяет четыре события:
MediaOpened
активируется при проверке и открытии потока мультимедиа.MediaEnded
срабатывает,MediaElement
когда завершает воспроизведение носителя.MediaFailed
срабатывает при возникновении ошибки, связанной с источником мультимедиа.SeekCompleted
активируется, когда точка поиска запрошенной операции поиска готова к воспроизведению.
Кроме того, MediaElement
включает Play
методы , Pause
и Stop
.
Сведения о поддерживаемых форматах мультимедиа в Android см. в статье Поддерживаемые форматы мультимедиа в developer.android.com. Сведения о поддерживаемых форматах мультимедиа в универсальная платформа Windows (UWP) см. в разделе Поддерживаемые кодеки.
Воспроизведение удаленного носителя
Может MediaElement
воспроизводить удаленные файлы мультимедиа с помощью схем URI HTTP и HTTPS. Для этого для свойства задается Source
URI файла мультимедиа:
<MediaElement Source="https://sec.ch9.ms/ch9/5d93/a1eab4bf-3288-4faf-81c4-294402a85d93/XamarinShow_mid.mp4"
ShowsPlaybackControls="True" />
По умолчанию носитель, определенный свойством , Source
воспроизводится сразу после открытия носителя. Чтобы отключить автоматическое AutoPlay
воспроизведение мультимедиа, задайте для свойства значение false
.
Элементы управления воспроизведением мультимедиа отключены по умолчанию и включаются, задав свойству ShowsPlaybackControls
значение true
. MediaElement
затем будет использовать элементы управления воспроизведением платформы, где они доступны.
Воспроизведение локальных носителей
Локальный носитель можно воспроизводить из следующих источников:
- Ресурс, внедренный в приложение платформы с использованием
ms-appx:///
схемы URI. - Файлы, поступающие из локальных и временных папок данных приложения, используя схему
ms-appdata:///
URI. - Библиотека устройства.
Дополнительные сведения об этих схемах URI см. в разделе Схемы URI.
Воспроизведение мультимедиа, внедренного в пакет приложения
Объект MediaElement
может воспроизводить файлы мультимедиа, внедренные в пакет приложения, с помощью ms-appx:///
схемы URI. Файлы мультимедиа внедряются в пакет приложения, помещая их в проект платформы.
Хранение файла мультимедиа в проекте платформы отличается для каждой платформы:
- В iOS файлы мультимедиа должны храниться в папке Resources или в подпапке папки Resources . Файл мультимедиа должен иметь значение
Build Action
BundleResource
. - В Android файлы мультимедиа должны храниться во вложенной папке Resources с именем raw. В папке raw не может быть вложенных папок. Файл мультимедиа должен иметь значение
Build Action
AndroidResource
. - В UWP файлы мультимедиа можно хранить в любой папке проекта. Файл мультимедиа должен иметь значение
BuildAction
Content
.
Затем файлы мультимедиа, соответствующие этим критериям, можно воспроизвести с помощью ms-appx:///
схемы URI:
<MediaElement Source="ms-appx:///XamarinForms101UsingEmbeddedImages.mp4"
ShowsPlaybackControls="True" />
При использовании привязки данных для применения следующей схемы 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}");
}
// ...
}
Затем экземпляр VideoSourceConverter
можно использовать для применения ms-appx:///
схемы URI к внедренным файлам мультимедиа:
<MediaElement Source="{Binding MediaSource, Converter={StaticResource VideoSourceConverter}}"
ShowsPlaybackControls="True" />
Дополнительные сведения о схеме URI ms-appx см. в разделах ms-appx и ms-appx-web.
Воспроизведение мультимедиа из локальных и временных папок приложения
Объект MediaElement
может воспроизводить файлы мультимедиа, которые копируются в локальные или временные папки данных приложения, используя схему ms-appdata:///
URI.
В следующем примере показано Source
свойство, заданное для файла мультимедиа, хранящегося в локальной папке данных приложения:
<MediaElement Source="ms-appdata:///local/XamarinVideo.mp4"
ShowsPlaybackControls="True" />
В следующем примере показано Source
свойство файла мультимедиа, хранящегося во временной папке данных приложения:
<MediaElement Source="ms-appdata:///temp/XamarinVideo.mp4"
ShowsPlaybackControls="True" />
Важно!
Помимо воспроизведения файлов мультимедиа, хранящихся в локальных или временных папках данных приложения, UWP также может воспроизводить файлы мультимедиа, расположенные в перемещаемой папке приложения. Это можно сделать, установив в файле мультимедиа префикс .ms-appdata:///roaming/
При использовании привязки данных для применения следующей схемы 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}");
}
// ...
}
Затем экземпляр VideoSourceConverter
можно использовать для применения ms-appdata:///
схемы URI к файлу мультимедиа в локальной или временной папке данных приложения:
<MediaElement Source="{Binding MediaSource, Converter={StaticResource VideoSourceConverter}}"
ShowsPlaybackControls="True" />
Дополнительные сведения о схеме URI ms-appdata см. в разделе ms-appdata.
Копирование файла мультимедиа в локальную или временную папку данных приложения
Для воспроизведения файла мультимедиа, хранящегося в локальной или временной папке данных приложения, требуется, чтобы файл мультимедиа был скопирован приложением. Это можно сделать, например, скопировав файл мультимедиа из пакета приложения:
// 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);
}
}
}
}
Примечание
В приведенном выше примере кода используется класс , включенный FileSystem
в Xamarin.Essentials. Дополнительные сведения см. в разделе Xamarin.Essentials: вспомогательные функции файловой системы.
Воспроизведение мультимедиа из библиотеки устройств
Большинство современных мобильных устройств и настольных компьютеров имеют возможность записывать видео и звук с помощью камеры и микрофона устройства. Созданный носитель затем сохраняется на устройстве в виде файлов. Эти файлы можно извлечь из библиотеки и воспроизвести с MediaElement
помощью .
Каждая из платформ включает в себя средство, позволяющее пользователю выбирать мультимедиа из библиотеки устройства. В Xamarin.Forms проекты платформы могут вызывать эту функцию, и она может вызываться классом DependencyService
.
Служба зависимостей выбора видео, используемая в примере приложения, очень похожа на службу, определенную в разделе Выбор фотографии из библиотеки рисунков, за исключением того, что средство выбора возвращает имя файла, а не Stream
объект. Проект общего кода определяет интерфейс с именем IVideoPicker
, который определяет один метод с именем GetVideoFileAsync
. Затем каждая платформа реализует этот интерфейс в VideoPicker
классе .
В следующем примере кода показано, как получить файл мультимедиа из библиотеки устройств:
string filename = await DependencyService.Get<IVideoPicker>().GetVideoFileAsync();
if (!string.IsNullOrWhiteSpace(filename))
{
mediaElement.Source = new FileMediaSource
{
File = filename
};
}
Служба зависимостей выбора видео вызывается путем вызова DependencyService.Get
метода для получения реализации IVideoPicker
интерфейса в проекте платформы. Затем GetVideoFileAsync
метод вызывается для этого экземпляра, и возвращенное имя файла используется для создания FileMediaSource
объекта и задания ему Source
свойства MediaElement
объекта .
Изменение пропорций видео
Свойство Aspect
определяет, как будет масштабироваться видеофайл в соответствии с областью отображения. По умолчанию этому свойству AspectFit
присваивается элемент перечисления, но ему может быть присвоен любой из Aspect
членов перечисления:
AspectFit
указывает, что видео будет в почтовом ящике, если это необходимо, для размещения в области отображения с сохранением пропорций.AspectFill
указывает, что видео будет обрезано таким образом, чтобы оно заполняло область отображения с сохранением пропорций.Fill
указывает, что видео будет растянуто для заполнения области отображения.
Привязка к свойству Position
Уведомление об изменении свойства для привязываемого Position
свойства срабатывает с интервалом 200 мс во время воспроизведения. Таким образом, свойство может быть привязано к элементу Slider
управления (или аналогичному) для отображения хода выполнения через носитель. CommunityToolkit также предоставляет объект , TimeSpanToDoubleConverter
который преобразует в TimeSpan
значение с плавающей запятой, представляющее общее количество затраченных секунд. Таким образом, для ползунка Maximum
Duration
можно задать значение носителя, а для Value
— для точного Position
хода выполнения:
<?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>
В этом примере Maximum
свойство объекта привязано Slider
к свойству Duration
MediaElement
объекта , а Value
свойство Slider
объекта — к свойству Position
MediaElement
объекта . Таким образом, перетаскивание Slider
результатов в положение воспроизведения мультимедиа изменится:
Кроме того, DataTrigger
объект используется для отключения Slider
при буферизации носителя. Дополнительные сведения о триггерах данных см. в разделе Триггеры Xamarin.Forms.
Примечание
В Android Slider
только имеет 1000 дискретных шагов, независимо от Minimum
параметров и Maximum
. Если длина носителя превышает 1000 секунд, то два разных Position
значения будут соответствовать одному и тому же Value
значению Slider
. Именно поэтому приведенный выше код проверяет, что новая позиция и существующая позиция превышают сотую часть общей длительности.
Общие сведения о типах MediaSource
Может MediaElement
воспроизводить мультимедиа, задав для его Source
свойства удаленный или локальный файл мультимедиа. Свойство Source
имеет тип MediaSource
, и этот класс определяет два статических метода:
FromFile
, возвращаетMediaSource
экземпляр из аргументаstring
.FromUri
, возвращаетMediaSource
экземпляр из аргументаUri
.
Кроме того, класс MediaSource
также имеет неявные операторы, которые возвращают MediaSource
экземпляры из string
аргументов и Uri
.
Примечание
Если свойство задано Source
в XAML, вызывается преобразователь типов для возврата экземпляра MediaSource
string
из или Uri
.
Класс MediaSource
также имеет два производных класса:
UriMediaSource
, который используется для указания удаленного файла мультимедиа из универсального кода ресурса (URI). Этот класс имеетUri
свойство , для которого можно задать значениеUri
.FileMediaSource
, который используется для указания локального файла мультимедиа изstring
. Этот класс имеетFile
свойство , для которого можно задать значениеstring
. Кроме того, этот класс имеет неявные операторы для преобразования вstring
FileMediaSource
объект иFileMediaSource
объекта вstring
.
Примечание
FileMediaSource
При создании объекта в XAML вызывается преобразователь типов для возврата экземпляра FileMediaSource
из string
.
Определение состояния MediaElement
Класс MediaElement
определяет привязываемое свойство только для чтения с именем CurrentState
, типа MediaElementState
. Это свойство указывает текущее состояние элемента управления, например, воспроизводимый или приостановленный носитель, или он еще не готов к воспроизведению мультимедиа.
Перечисление MediaElementState
определяет следующие члены:
Closed
указывает, чтоMediaElement
не содержит носителей.Opening
указывает, чтоMediaElement
выполняет проверку и пытается загрузить указанный источник.Buffering
указывает, чтоMediaElement
загружает мультимедиа для воспроизведения. ЕгоPosition
свойство не перемещает во время этого состояния. Если воспроизводилосьMediaElement
видео, он продолжает отображать последний отображаемый кадр.Playing
указывает, чтоMediaElement
воспроизводит источник мультимедиа.Paused
указывает, чтоMediaElement
объект не перемещает своеPosition
свойство . Если воспроизводитMediaElement
видео, он продолжает отображать текущий кадр.Stopped
указывает, чтоMediaElement
содержит мультимедиа, но не воспроизводится или приостанавливается. ЕгоPosition
свойство равно 0 и не перемещается вперед. Если загруженным носителем является видео, отображаетсяMediaElement
первый кадр.
Обычно не требуется проверять CurrentState
свойство при использовании элементов управления транспортировкой MediaElement
. Однако это свойство становится важным при реализации собственных элементов управления транспортировкой.
Реализация пользовательских элементов управления транспортировкой
Элементы управления транспортировкой проигрывателя мультимедиа включают кнопки, которые выполняют функции Воспроизведения, Приостановка и Остановка. Эти кнопки обычно определяются по знакомым значкам, а не тексту. Как правило, функции Воспроизведение и Пауза объединены в одну кнопку.
По умолчанию элементы управления воспроизведением MediaElement
отключены. Это позволяет управлять программными MediaElement
средствами или путем предоставления собственных элементов управления транспортировкой. Для поддержки этого MediaElement
включает Play
методы , и .Stop
Pause
В следующем примере XAML показана страница, содержащая и пользовательские элементы управления транспортировкой MediaElement
:
<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>
В этом примере пользовательские элементы управления транспортировкой определяются как Button
объекты . Однако существует только два Button
объекта: первый Button
представляет воспроизведение и паузу, а второй Button
— stop. DataTrigger
Объекты используются для включения и отключения кнопок, а также для переключения первой кнопки между воспроизведением и паузой. Дополнительные сведения о триггерах данных см. в разделе Триггеры Xamarin.Forms.
Файл кода программной части содержит обработчики для Clicked
событий:
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();
}
После включения можно нажать кнопку Воспроизвести , чтобы начать воспроизведение:
Нажатие кнопки Пауза приводит к приостановке воспроизведения:
Нажатие кнопки Остановить останавливает воспроизведение и возвращает позицию файла мультимедиа в начало.
Реализация пользовательского элемента управления громкости
Элементы управления воспроизведением мультимедиа, реализованные каждой платформой, включают в себя полосу громкости. Эта панель похожа на ползунок и показывает объем носителя. Кроме того, можно управлять полосой тома для увеличения или уменьшения громкости.
Пользовательскую панель тома можно реализовать с помощью Slider
, как показано в следующем примере:
<StackLayout>
<MediaElement AutoPlay="False"
Source="{StaticResource AdvancedAsync}" />
<Slider Maximum="1.0"
Minimum="0.0"
Value="{Binding Volume}"
Rotation="270"
WidthRequest="100" />
</StackLayout>
В этом примере Slider
данные привязывают свое Value
свойство к свойству Volume
MediaElement
объекта . Это возможно, так как Volume
свойство использует привязку TwoWay
. Таким образом, изменение Value
свойства приведет к изменению Volume
свойства.
Примечание
Свойство Volume
имеет обратный вызов проверки, который гарантирует, что его значение больше или равно 0,0 и меньше или равно 1,0.
Дополнительные сведения об использовании Slider
см. в разделе Ползунок Xamarin.Forms.