Skip to content

Commit f9c0b06

Browse files
authored
Merge pull request #637 from AvaloniaUI/fixes/mediaplayer-tweaks
Accelerate MediaPlayer tweaks
2 parents 9ac9914 + 281928f commit f9c0b06

File tree

3 files changed

+77
-83
lines changed

3 files changed

+77
-83
lines changed

accelerate/components/media-player/mediaplayer.md

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ the `MediaPlayerControl`.
3131

3232
### Playback Properties
3333

34-
| Property | Type | Description |
35-
|----------------|------------------|--------------------------------------------------------------------|
36-
| Position | TimeSpan | Gets or sets the current playback position. |
37-
| Duration | TimeSpan? | Gets the total duration of the media. Null for non-seekable media. |
38-
| LoadedBehavior | MediaPlayerState | Gets or sets playback behavior when media is loaded. |
34+
| Property | Type | Description |
35+
|----------------|---------------------------|--------------------------------------------------------------------|
36+
| Position | TimeSpan | Gets or sets the current playback position. |
37+
| Duration | TimeSpan? | Gets the total duration of the media. Null for non-seekable media. |
38+
| LoadedBehavior | MediaPlayerLoadedBehavior | Gets or sets playback behavior when media is loaded. |
3939

4040
### State Properties
4141

@@ -71,7 +71,7 @@ the `MediaPlayerControl`.
7171
| MediaPaused | Occurs when media playback has been paused. |
7272
| MediaStopped | Occurs when media playback has been stopped. |
7373
| MediaPlaybackCompleted | Occurs when media playback has completed. |
74-
| OnErrorOccurred | Occurs when an error is encountered. |
74+
| ErrorOccurred | Occurs when an error is encountered. |
7575
| PropertyChanged | Standard INotifyPropertyChanged event. |
7676

7777
## Methods
@@ -118,7 +118,7 @@ await player.InitializeAsync();
118118

119119
// Configure
120120
player.Volume = 0.8;
121-
player.LoadedBehavior = MediaPlayerState.AutoPlay;
121+
player.LoadedBehavior = MediaPlayerLoadedBehavior.Manual;
122122

123123
// Load and play media
124124
player.Source = new UriSource("https://example.com/audio.mp3");
@@ -135,7 +135,7 @@ player.MediaStarted += (s, e) => Console.WriteLine("Playback started");
135135
player.MediaPlaybackCompleted += (s, e) => Console.WriteLine("Playback completed");
136136

137137
// Error handling
138-
player.OnErrorOccurred += (s, e) => {
138+
player.ErrorOccurred += (s, e) => {
139139
Console.WriteLine($"Error: {e.ErrorMessage}");
140140
};
141141
```
@@ -153,23 +153,18 @@ await player.UnInitialize();
153153

154154
The MediaPlayer uses an event-based approach to error handling:
155155

156-
- When an error occurs, the player transitions to MediaPlayerState.Error
157-
- The `OnErrorOccurred` event is raised with detailed error information
156+
- When an error occurs, the player transitions to an Error state internally
157+
- The `ErrorOccurred` event is raised with detailed error information
158158
- Most methods check for the Error state and will not proceed
159159
- Call ReleaseAsync() to reset the error state
160160

161161
```csharp
162162
// Subscribe to error events
163-
player.OnErrorOccurred += (sender, args) => async {
163+
player.ErrorOccurred += (sender, args) =>
164+
{
164165
// Handle the error appropriately here with your custom logic.
165166
// ...
166167
Console.WriteLine($"Error: {args.ErrorMessage}");
167-
168-
// Optionally reset the player
169-
await player.ReleaseAsync();
170-
171-
// Set this to true to avoid unhandled exception crash.
172-
args.Handled = true;
173168
};
174169

175170
// Try to play media
@@ -195,8 +190,7 @@ catch (Exception ex) {
195190
- Call `UnInitialize()` when completely done with `MediaPlayer`.
196191

197192
2. **Error Handling**:
198-
- Subscribe to the `OnErrorOccurred` event to handle playback errors.
199-
- Use `ReleaseAsync()` to reset the player after an error.
193+
- Subscribe to the `ErrorOccurred` event to handle playback errors.
200194

201195
3. **Resource Management**:
202196
- Properly clean up to avoid resource leaks.

accelerate/components/media-player/mediaplayercontrol.md

Lines changed: 56 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -71,44 +71,44 @@ interface for media playback.
7171

7272
| Event | Description |
7373
|-----------------|--------------------------------------------------------------|
74-
| OnErrorOccurred | Occurs when an error is encountered during media operations. |
74+
| ErrorOccurred | Occurs when an error is encountered during media operations. |
7575

7676
## Usage Examples
7777

7878
### Basic Usage
7979

8080
```xaml
81-
<MediaPlayerControl Name="mediaPlayer" Source="{Binding MediaSource}"
82-
Volume="0.8"
83-
LoadedBehavior="AutoPlay" />
81+
<MediaPlayerControl Name="mediaPlayerControl" Source="{Binding MediaSource}"
82+
Volume="0.8"
83+
LoadedBehavior="AutoPlay" />
8484
```
8585

8686
### Binding to Commands
8787

8888
```xaml
89-
<Button Command="{Binding #mediaPlayer.PlayPauseCommand}"
89+
<Button Command="{Binding #mediaPlayerControl.PlayPauseCommand}"
9090
Content="Play/Pause" />
9191

92-
<Button Command="{Binding #mediaPlayer.StopCommand}"
92+
<Button Command="{Binding #mediaPlayerControl.StopCommand}"
9393
Content="Stop" />
9494
```
9595

9696
### Error Handling
9797

9898
```csharp
99-
mediaPlayer.OnErrorOccurred += (sender, args) =>
99+
mediaPlayerControl.ErrorOccurred += (sender, args) =>
100100
{
101101
Console.WriteLine($"Media error: {args.Message}");
102102
args.Handled = true; // Prevents the exception from being thrown.
103103
};
104104
```
105105

106-
**Note**: This callback gives you the opportunity to reset the state of the `MediaPlayer` gracefully.
106+
**Note**: This callback gives you the opportunity to reset the state of the `MediaPlayerControl` gracefully.
107+
107108

108109
## Template Parts and Customization
109110

110-
The default control template for `MediaPlayerControl` in `Avalonia.Media.Themes.Fluent`
111-
includes several key parts:
111+
The default control template for `MediaPlayerControl` includes several key parts:
112112

113113
- **PART_MediaPlayerPresenter**: Displays the video content
114114
- **MediaControlOverlay**: Contains the playback controls
@@ -117,49 +117,50 @@ includes several key parts:
117117
The most basic configuration of the `MediaPlayerControl` can be like this:
118118

119119
```xml
120-
<!-- Put this in a ResourceDictionary referenced by your app.
121-
This by default replaces the -->
120+
<!-- In a ResourceDictionary referenced by your app. -->
122121
<ControlTheme x:Key="{x:Type MediaPlayerControl}" TargetType="MediaPlayerControl">
122+
<Setter Property="Template">
123123
<ControlTemplate>
124-
<!-- This border is for decoration and for setting a default background for the control
125-
When there's no media. -->
126-
<Border Background="Gray" ClipToBounds="True" CornerRadius="4">
127-
<Panel>
128-
<!-- This is used to have a dark background against the MediaPlayerPresenter when there's a
129-
video to be displayed. -->
130-
<Border IsVisible="{TemplateBinding HasVideo}">
131-
<Border Background="Black" IsVisible="{TemplateBinding IsMediaActive}"/>
132-
</Border>
133-
134-
<!-- This ViewBox is responsible on how the MediaPlayerPresenter is stretched to fit
135-
the bounding area of the control. -->
136-
<Viewbox>
137-
<!-- The control in which the internal MediaPlayer draws the video -->
138-
<MediaPlayerPresenter Name="PART_MediaPlayerPresenter"/>
139-
</Viewbox>
140-
141-
<!-- Example of the overlay playback controls.
142-
Use the built-in Commands to easily control the playback. -->
143-
<DockPanel LastChildFill="True" MaxHeight="64" VerticalAlignment="Bottom">
144-
<ProgressBar DockPanel.Dock="Bottom"
145-
IsIndeterminate="True"
146-
IsVisible="{TemplateBinding IsBuffering}"/>
147-
<StackPanel Orientation="Horizontal"
148-
HorizontalAlignment="Center"
149-
Spacing="10"
150-
Margin="5"
151-
TextElement.FontSize="24">
152-
<Button Content="&#x23EF;"
153-
Padding="5,-5,5,0"
154-
Command="{TemplateBinding PlayPauseCommand}"/>
155-
<Button Content="&#x23F9;"
156-
Padding="5,-5,5,0"
157-
Command="{TemplateBinding StopCommand}"/>
158-
</StackPanel>
159-
</DockPanel>
160-
</Panel>
161-
</Border>
124+
<!-- This border is for decoration and for setting a default background for the control
125+
When there's no media. -->
126+
<Border Background="Gray" ClipToBounds="True" CornerRadius="4">
127+
<Panel>
128+
<!-- This is used to have a dark background against the MediaPlayerPresenter when there's a
129+
video to be displayed. -->
130+
<Border IsVisible="{TemplateBinding HasVideo}">
131+
<Border Background="Black" IsVisible="{TemplateBinding IsMediaActive}"/>
132+
</Border>
133+
134+
<!-- This ViewBox is responsible on how the MediaPlayerPresenter is stretched to fit
135+
the bounding area of the control. -->
136+
<Viewbox>
137+
<!-- The control in which the internal MediaPlayer draws the video -->
138+
<MediaPlayerPresenter Name="PART_MediaPlayerPresenter"/>
139+
</Viewbox>
140+
141+
<!-- Example of the overlay playback controls.
142+
Use the built-in Commands to easily control the playback. -->
143+
<DockPanel LastChildFill="True" MaxHeight="64" VerticalAlignment="Bottom">
144+
<ProgressBar DockPanel.Dock="Bottom"
145+
IsIndeterminate="True"
146+
IsVisible="{TemplateBinding IsBuffering}"/>
147+
<StackPanel Orientation="Horizontal"
148+
HorizontalAlignment="Center"
149+
Spacing="10"
150+
Margin="5"
151+
TextElement.FontSize="24">
152+
<Button Content="&#x23EF;"
153+
Padding="5,-5,5,0"
154+
Command="{TemplateBinding PlayPauseCommand}"/>
155+
<Button Content="&#x23F9;"
156+
Padding="5,-5,5,0"
157+
Command="{TemplateBinding StopCommand}"/>
158+
</StackPanel>
159+
</DockPanel>
160+
</Panel>
161+
</Border>
162162
</ControlTemplate>
163+
</Setter>
163164
</ControlTheme>
164165
```
165166

@@ -195,7 +196,7 @@ flowchart LR
195196
class Init,Setup,Cleanup phase
196197
```
197198

198-
Here's a more comprehensive graph of `MediaPlayerControl`'s interactions with `MediaPlayer` over the course of its
199+
Here's a more comprehensive graph of `MediaPlayerControl`'s interactions with its internal `MediaPlayer` over the course of its
199200
lifetime:
200201

201202
```mermaid
@@ -247,11 +248,11 @@ flowchart LR
247248
## Best Practices
248249

249250
1. **Error Handling**:
250-
- Always subscribe to the `OnErrorOccurred` event to handle errors gracefully.
251-
- Set the `Handled` property to true on the `OnErrorOccurred` event handler if you've managed the error.
251+
- Always subscribe to the `ErrorOccurred` event to handle errors gracefully.
252+
- Set the `Handled` property to true on the `ErrorOccurred` event handler if you've managed the error.
252253

253254
2. **Resource Management**:
254-
- The control manages the `MediaPlayer` lifecycle automatically.
255+
- The control manages the `MediaPlayerControl` lifecycle automatically.
255256

256257
3. **UI Integration**:
257258
- Use the built-in commands for integrating with custom buttons/controls.
@@ -260,4 +261,4 @@ flowchart LR
260261
## Related Components
261262

262263
- [MediaPlayer](mediaplayer.md)
263-
- [MediaSource](mediasource.md)
264+
- [MediaSource](mediasource.md)

accelerate/components/media-player/quickstart.md

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,10 @@ Accelerate MediaControls package.
2020

2121
## Installation
2222

23-
Add the Avalonia Accelerate MediaControls packages to your project:
23+
Add the Avalonia Accelerate MediaPlayer package to your project:
2424

2525
```bash
26-
dotnet add package Avalonia.Media
27-
dotnet add package Avalonia.Media.Theme.Fluent
26+
dotnet add package Avalonia.Controls.MediaPlayer
2827
```
2928

3029
Add the default theme to your App.axaml:
@@ -134,11 +133,11 @@ public async void OpenFile_Click(object sender, RoutedEventArgs e)
134133

135134
```csharp
136135
// Play/pause
137-
await mediaPlayer.Player.PlayAsync();
138-
await mediaPlayer.Player.PauseAsync();
136+
await mediaPlayer.PlayAsync();
137+
await mediaPlayer.PauseAsync();
139138

140139
// Stop
141-
await mediaPlayer.Player.StopAsync();
140+
await mediaPlayer.StopAsync();
142141

143142
// Seek to position
144143
mediaPlayer.Position = TimeSpan.FromSeconds(30);
@@ -147,7 +146,7 @@ mediaPlayer.Position = TimeSpan.FromSeconds(30);
147146
mediaPlayer.Volume = 0.75;
148147

149148
// Mute/unmute
150-
mediaPlayer.Player.IsMuted = true;
149+
mediaPlayer.IsMuted = true;
151150
```
152151

153152
### Media Information
@@ -169,7 +168,7 @@ TimeSpan position = mediaPlayer.Position;
169168
### Error Handling
170169

171170
```csharp
172-
mediaPlayer.OnErrorOccurred += (sender, args) =>
171+
mediaPlayer.ErrorOccurred += (sender, args) =>
173172
{
174173
Console.WriteLine($"Media error: {args.Message}");
175174
args.Handled = true; // Prevents the exception from being thrown.
@@ -242,7 +241,7 @@ Common issues and solutions:
242241

243242
5. **Player in error state**
244243
- Call `Player.ReleaseAsync()` to reset from the error state
245-
- Handle the `OnErrorOccurred` event for any error messages and reset accordingly.
244+
- Handle the `ErrorOccurred` event for any error messages and reset accordingly.
246245

247246
For more detailed information on the components:
248247

0 commit comments

Comments
 (0)