MediaElement
MediaElement
是用于播放视频和音频的控件。 基础平台支持的媒体可以从以下源播放:
- 使用 URI(HTTP 或 HTTPS)的 Web。
- 使用
embed://
URI 方案嵌入平台应用程序中的资源。 - 使用
filesystem://
URI 方案的来自应用的本地文件系统的文件。
MediaElement
可以使用平台播放控件,这些控件称为传输控件。 但是,默认情况下它们处于禁用状态,可以替换为你自己的传输控件。 以下屏幕截图显示 MediaElement
使用平台传输控件播放视频:
注意
MediaElement
可在 iOS、Android、Windows、macOS 和 Tizen 上获取。
MediaElement
使用以下平台实现。
平台 | 平台媒体播放器实现 |
---|---|
Android | ExoPlayer,非常感谢 ExoPlayerXamarin 维护者! |
iOS/macOS | AVPlayer |
Windows | MediaPlayer |
使用入门
若要使用 .NET MAUI Community 工具包的 MediaElement
功能,需要执行以下步骤。
安装 NuGet 包
在应用程序内使用 MediaElement
之前,需要安装 CommunityToolkit.Maui.MediaElement
NuGet 包,并在 MauiProgram.cs 中添加初始化行。 如下所示:
包名称:CommunityToolkit.Maui.MediaElement
Package url:https://www.nuget.org/packages/CommunityToolkit.Maui.MediaElement
初始化包
首先,需要将 using 语句添加到 MauiProgram.cs 文件的顶部
using CommunityToolkit.Maui.MediaElement;
为了正确使用 MediaElement
,必须在启动应用程序 MauiProgram.cs 文件时,对 MauiAppBuilder
类调用 UseMauiCommunityToolkitMediaElement
方法。 以下示例演示如何执行此操作。
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseMauiCommunityToolkitMediaElement()
有关如何执行此操作的详细信息,请参阅入门页。
特定于平台的初始化
要访问 MediaElement
功能,需执行以下特定于平台的设置。
使用 MediaElement
时,必须执行以下步骤:
1.将 ResizableActivity
和 Launchmode
添加到活动
[Activity(Theme = "@style/Maui.SplashTheme", ResizeableActivity = true, MainLauncher = true, LaunchMode = LaunchMode.SingleTask)]
public class MainActivity : MauiAppCompatActivity
{
}
2.将以下内容添加到 <application>
标记内的 AndroidManifest.xml
。
<service android:name="communityToolkit.maui.media.services" android:exported="false" android:enabled="true" android:foregroundServiceType="mediaPlayback">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
<intent-filter>
<action android:name="androidx.media3.session.MediaSessionService"/>
</intent-filter>
</service>
3.将以下权限添加到 AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL" />
下面是 AndroidManifest.xml
中所需设置的示例
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:enableOnBackInvokedCallback="true" android:supportsRtl="true">
<service android:name="communityToolkit.maui.media.services" android:exported="false" android:enabled="true" android:foregroundServiceType="mediaPlayback">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
<intent-filter>
<action android:name="androidx.media3.session.MediaSessionService"/>
</intent-filter>
</service>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL" />
注意
此对 Android 清单的修改可在播放视频时显示元数据。 它为通知提供支持,对于通知在所有相关 API 中发挥作用至关重要。 此更改引入了服务并授予必要的权限。
如需包含在应用程序中的此方法的完整示例,请参阅 .NET MAUI Community 工具包示例应用程序
支持的格式
每个平台支持的多媒体格式可能有所不同。 在某些情况下,它甚至可能取决于运行应用时所用操作系统上提供或安装了哪些解码器。 有关每个平台上支持哪些格式的更多详细信息,请参阅以下链接。
平台 | 链接 | 说明 |
---|---|---|
Android | ExoPlayer 支持的格式 | |
iOS/macOS | iOS/macOS 支持的格式 | 有关此内容的官方文档不存在 |
Windows | Windows 支持的格式 | 在 Windows 上,支持的格式在很大程度上取决于用户计算机上安装的编解码器 |
Tizen | Tizen 支持的格式 |
重要
如果用户使用的是 Windows N 版本,则默认情况下不支持视频播放。 Windows N 版本有意未安装视频播放格式。
常见方案
以下各节介绍了 MediaElement
的常见使用方案。
播放远程媒体
MediaElement
可以使用 HTTP 和 HTTPS URI 方案播放远程媒体文件。 这可通过将 Source
属性设置为媒体文件的 URI 来实现:
<toolkit:MediaElement Source="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
ShouldShowPlaybackControls="True" />
重要
从 HTTP 终结点播放远程源时,可能需要禁用阻止访问不安全 Web 终结点的操作系统安全措施。 这至少适用于 iOS 和 Android。
默认情况下,Source
属性定义的媒体不会在媒体打开后立即开始播放。 要启用自动媒体播放,请将 ShouldAutoPlay
属性设置为 true
。
平台提供的媒体播放控件默认处于启用状态,可以通过将 ShouldShowPlaybackControls
属性设置为 false
将其禁用。
使用元数据
MediaElement
可以将元数据用于 MediaElement.MetadataTitle
、MediaElement.MetadataArtist
和 MediaElement.MetadataArtworkUrl
。 你可以在 Windows、Mac Catalyst、iOS 和 Android 的锁屏控件上设置标题或艺术家,以显示当前播放的内容。 可以使用锁屏的插图设置本地或远程 URL。 至少应为 1080P 才能显示最佳质量。 它必须是 URL,并且为 .jpg
或 .png
<toolkit:MediaElement
MetadataTitle="Title"
MetadataArtist="Artist"
MetadataArtworkUrl="http://www.myownpersonaldomain.com/image.jpg" />
MediaElement.MetadataTitle="Title";
MediaElement.MetadataArtist="Artist";
MediaElement.MetadataArtworkUrl="http://www.myownpersonaldomain.com/image.jpg";
重要
可以在 XAML 或代码隐藏中设置元数据。 如果要在代码隐藏中设置它,则需要在代码隐藏中设置源代码。 应最后设置源。 如果在 XAML 或构造函数中设置元数据,则可以安全地忽略此注释。
播放本地媒体
可以从以下源播放本地媒体:
- 使用
embed://
URI 方案嵌入平台应用程序中的资源。 - 使用
filesystem://
URI 方案的来自应用的本地文件系统的文件。
注意
简写 embed://
和 filesystem://
只能在 XAML 中使用。 在代码中,请分别使用 MediaSource.FromResource()
和 MediaSource.FromFile()
。 使用这些方法,可以省略 embed://
和 filesystem://
前缀。 路径的其余部分应相同。
播放嵌入在应用包中的媒体
MediaElement
可以使用 embed://
URI 方案播放嵌入应用包中的媒体文件。 媒体文件通过将它们放在平台项目中来嵌入到应用包中。
要启用媒体文件以便从本地资源播放,请将该文件添加到 .NET MAUI 项目的 Resources/Raw
文件夹。 在根目录中添加文件时,URI 将为 embed://MyFile.mp4
。
还可以将文件放在子文件夹中。 如果 MyFile.mp4
位于 Resources/Raw/MyVideos
中,则要与 MediaElement
一起使用它的 URI 将是 embed://MyVideos/MyFile.mp4
。
如何在 XAML 中使用此语法的示例如下所示。
<toolkit:MediaElement Source="embed://MyFile.mp4"
ShouldShowPlaybackControls="True" />
了解 MediaSource 类型
MediaElement
可以通过将其 Source
属性设置为远程或本地媒体文件来播放媒体。 Source
属性的类型为 MediaSource
,此类定义三种静态方法:
FromFile
,从string
参数返回FileMediaSource
实例。FromUri
,从Uri
参数返回UriMediaSource
实例。FromResource
,从string
参数返回ResourceMediaSource
实例。
此外,MediaSource
类还包含从 string
和 Uri
参数返回 MediaSource
实例的隐式运算符。
注意
在 XAML 中设置 Source
属性时,将调用类型转换器从 string
或 Uri
返回 MediaSource
实例。
MediaSource
类还包含以下派生类:
FileMediaSource
,用于指定string
中的本地媒体文件。 此类包含可设置为string
的Path
属性。 此外,此类还包含将string
转换为FileMediaSource
对象,并将FileMediaSource
对象转换为string
的隐式运算符。UriMediaSource
,用于指定 URI 中的远程媒体文件。 此类包含可设置为Uri
的Uri
属性。ResourceMediaSource
,用于指定通过应用的资源文件提供的嵌入文件。 此类包含可设置为string
的Path
属性。
注意
在 XAML 中创建 FileMediaSource
对象时,将调用类型转换器从 string
返回 FileMediaSource
实例。
更改视频纵横比
Aspect
属性确定如何缩放视频媒体以适应显示区域。 默认情况下,此属性设置为 AspectFit
枚举成员,但可以设置为任何 Aspect
枚举成员:
AspectFit
指示视频将采用黑边(如果需要)以适应显示区域,同时保留纵横比。AspectFill
指示视频将被剪裁,以便它填充显示区域,同时保留纵横比。Fill
指示视频将被拉伸以填充显示区域。
确定 MediaElement
状态
MediaElement
类定义名为 CurrentState
的只读可绑定属性,类型为 MediaElementState
。 此属性指示控件的当前状态,例如媒体是在播放还是暂停,或者是否尚未准备好播放媒体。
MediaElementState
枚举定义以下成员:
None
指示MediaElement
不包含媒体。Opening
指示MediaElement
正在验证并尝试加载指定的源。Buffering
指示MediaElement
正在加载要播放的媒体。 其Position
属性在此状态下不会推进。 如果MediaElement
播放过视频,它将继续显示最后显示的帧。Playing
指示MediaElement
正在播放媒体源。Paused
指示MediaElement
不推进其Position
属性。 如果MediaElement
播放过视频,它将继续显示当前帧。Stopped
指示MediaElement
包含媒体但未播放或暂停。 其Position
属性重置为 0,并且不会推进。Failed
指示MediaElement
无法加载或播放媒体。 尝试加载新媒体项、尝试播放媒体项或媒体播放因故障中断时,可能会发生这种情况。 使用MediaFailed
事件检索其他详细信息。
使用 MediaElement
传输控件时,通常不需要检查 CurrentState
属性。 但是,在实现自己的传输控件时,此属性变得非常重要。
实现自定义传输控件
媒体播放器的传输控件包括执行“播放”、“暂停”和“停止”功能的按钮。 这些按钮通常使用熟悉的图标而非文本来标识,且“播放”和“暂停”功能通常合并成一个按钮。
默认情况下,MediaElement
播放控件处于禁用状态。 这样一来,可以以编程方式或通过提供自己的传输控件控制 MediaElement
。 为了支持此功能,MediaElement
包括 Play
、Pause
和 Stop
方法。
以下 XAML 示例显示包含 MediaElement
和自定义传输控件的页面:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
x:Class="MediaElementDemos.CustomTransportPage"
Title="Custom transport">
<Grid>
...
<toolkit:MediaElement x:Name="mediaElement"
ShouldAutoPlay="False"
... />
<HorizontalStackLayout BindingContext="{x:Reference mediaElement}"
...>
<Button Text="Play"
HorizontalOptions="Center"
Clicked="OnPlayPauseButtonClicked">
<Button.Triggers>
<DataTrigger TargetType="Button"
Binding="{Binding CurrentState}"
Value="{x:Static toolkit:MediaElementState.Playing}">
<Setter Property="Text"
Value="Pause" />
</DataTrigger>
<DataTrigger TargetType="Button"
Binding="{Binding CurrentState}"
Value="{x:Static toolkit:MediaElementState.Buffering}">
<Setter Property="IsEnabled"
Value="False" />
</DataTrigger>
</Button.Triggers>
</Button>
<Button Text="Stop"
HorizontalOptions="Center"
Clicked="OnStopButtonClicked">
<Button.Triggers>
<DataTrigger TargetType="Button"
Binding="{Binding CurrentState}"
Value="{x:Static toolkit:MediaElementState.Stopped}">
<Setter Property="IsEnabled"
Value="False" />
</DataTrigger>
</Button.Triggers>
</Button>
</HorizontalStackLayout>
</Grid>
</ContentPage>
在此示例中,自定义传输控件定义为 Button
对象。 但是,只有两个 Button
对象,第一个 Button
表示“播放”和“暂停”,第二个 Button
表示“停止”。 DataTrigger
对象用于启用和禁用按钮,以及在“播放”和“暂停”之间切换第一个按钮。 有关数据触发器的详细信息,请参阅 .NET MAUI 触发器。
代码隐藏文件包含 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>
<toolkit:MediaElement ShouldAutoPlay="False"
Source="{StaticResource AdvancedAsync}" />
<Slider Maximum="1.0"
Minimum="0.0"
Value="{Binding Volume}"
Rotation="270"
WidthRequest="100" />
</StackLayout>
在此示例中,Slider
数据将其 Value
属性绑定到 MediaElement
的 Volume
属性。 这是可能的,因为 Volume
属性使用 TwoWay
绑定。 因此,更改 Value
属性将导致 Volume
属性更改。
注意
Volume
属性包含验证回调,可确保其值大于或等于 0.0,并且小于或等于 1.0。
有关使用 Slider
的详细信息,请参阅 .NET MAUI 滑块
清理 MediaElement
资源
要防止内存泄漏,必须释放 MediaElement
的资源。 可以通过断开处理程序的连接来完成此操作。
需要执行此操作的位置取决于应用中使用 MediaElement
的位置和方式,但通常如果在单个页面上包含 MediaElement
并且未在后台播放媒体,则需要在用户离开页面时释放资源。
下面可以找到演示如何执行此操作的示例代码片段。 首先,请确保在页面上挂接 Unloaded
事件。
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
x:Class="MediaElementDemos.FreeResourcesPage"
Title="Free Resources"
Unloaded="ContentPage_Unloaded">
<toolkit:MediaElement x:Name="mediaElement"
ShouldAutoPlay="False"
... />
</ContentPage>
然后在代码隐藏中,调用该方法以断开处理程序的连接。
public partial class FreeResourcesPage : ContentPage
{
void ContentPage_Unloaded(object? sender, EventArgs e)
{
// Stop and cleanup MediaElement when we navigate away
mediaElement.Handler?.DisconnectHandler();
}
}
要详细了解处理程序,请参阅有关处理程序的 .NET MAUI 文档。
属性
属性 | 类型 | 说明 | 默认值 |
---|---|---|---|
方面 | 方面 | 确定当前加载的(视觉对象)媒体的缩放模式。 这是一种可绑定属性。 | Aspect.AspectFit |
CurrentState | MediaElementState |
指示控件的当前状态。 这是一种只读可绑定属性。 | MediaElementState.None |
持续时间 | TimeSpan |
指示当前打开的媒体的持续时间。 这是一种只读可绑定属性。 | TimeSpan.Zero |
位置 | TimeSpan |
介绍媒体播放时间的当前进度。 这是一种只读可绑定属性。 如果要设置 Position ,请使用 SeekTo() 方法。 |
TimeSpan.Zero |
ShouldAutoPlay | bool |
指示设置 Source 属性时是否自动开始播放媒体。 这是一种可绑定属性。 |
false |
ShouldLoopPlayback | bool |
介绍当前加载的媒体源在播放结束后是否应从头恢复播放。 这是一种可绑定属性。 | false |
ShouldKeepScreenOn | bool |
确定设备屏幕是否应在媒体播放期间保持打开状态。 这是一种可绑定属性。 | false |
ShouldMute | bool |
确定音频当前是否静音。 这是一种可绑定属性。 | false |
ShouldShowPlaybackControls | bool |
确定是否显示平台播放控件。 这是一种可绑定属性。 请注意,在 iOS 和 Windows 上,这些控件仅在与屏幕交互后显示一小段时间。 无法始终使这些控件保持可见。 | true |
Source | MediaSource? |
加载到控件中的媒体的源。 | null |
速度 | double |
确定媒体的播放速度。 这是一种可绑定属性 | 1 |
MediaHeight | int |
加载媒体的高度(以像素为单位)。 这是一种只读可绑定属性。 非可视媒体未报告,可能不会始终在 iOS/macOS 上填充实时流式传输内容。 | 0 |
MediaWidth | int |
加载媒体的宽度(以像素为单位)。 这是一种只读可绑定属性。 非可视媒体未报告,可能不会始终在 iOS/macOS 上填充实时流式传输内容。 | 0 |
体积 | double |
确定媒体的音量,以 0 到 1 之间的线性标尺表示。 这是一种可绑定属性。 | 1 |
事件
事件 | 说明 |
---|---|
MediaOpened | 在验证并打开媒体流时发生。 |
MediaEnded | 在 MediaElement 播放完其媒体时发生。 |
MediaFailed | 当存在与媒体源关联的错误时发生。 |
PositionChanged | 在 Position 属性值更改后发生。 |
SeekCompleted | 当请求的查找操作的查找点准备好播放时发生。 |
方法
事件 | 说明 |
---|---|
玩游戏 | 开始播放加载的媒体。 |
暂停 | 暂停播放当前媒体。 |
停止 | 停止播放并重置当前媒体的位置。 |
SeekTo | 取一个 TimeSpan 值来设置 Position 属性,取一个 CancellationToken 来取消 Task 。 |
示例
可以在 .NET MAUI 社区工具包示例应用程序中查找此控件操作的示例。
API
可以在 .NET MAUI 社区工具包 GitHub 存储库上查找 MediaElement
的源代码。