Advanced Playback
The ExtendedPlaybackPage extends the Simple Playback page with recording to MP4 files, snapshot capture, decoder framework selection, rendering strategy configuration, and audio output device selection. Playback and recording can run simultaneously using a shared media source.
Overview
The ExtendedPlaybackPage performs the following:
- Plays media from a URI using MediaPlayerControl with configurable playback parameters
- Provides decoder framework and rendering strategy selection
- Configures video renderer type and audio output device on Windows
- Records the playing stream to an MP4 file while playback continues
- Captures JPEG snapshots of the current video frame
- Shares a single IMediaSource between the player and the recording session using reference counting
All features from the Simple Playback page — track selection, seeking, playback speed control, and live stream statistics — are also available.
Playback Parameters
Before starting playback, the page configures PlaybackParameters:
this.player.PlaybackParameters.RenderingStrategy = VAST.Media.RenderingStrategy.LowLatency;
this.player.PlaybackParameters.PreferredVideoFramework = VAST.Common.MediaFramework.Builtin;
this.player.PlaybackParameters.PreferredAudioFramework = VAST.Common.MediaFramework.Builtin;
Rendering Strategy
| Strategy | Description |
|---|---|
| Low Latency | Minimal latency at the expense of smoothness |
| Smooth | Smooth playback at the expense of latency (can be several seconds) |
Decoder Framework
| Option | Framework | Description |
|---|---|---|
| Media Foundation | MediaFoundation |
Windows built-in framework (Windows only) |
| FFmpeg | FFmpeg |
FFmpeg decoders (all platforms) |
| Nvidia | CUDA |
Nvidia hardware decoding (Windows only, requires Nvidia GPU) |
| Builtin | Builtin |
Built-in framework (non-Windows platforms) |
Hardware Acceleration
this.player.PlaybackParameters.AllowHardwareAcceleration = true;
Enables GPU-accelerated decoding (forced on for Nvidia). This setting is effective on Windows and macOS only — on Android and iOS, hardware acceleration is always on for the built-in framework and always off for FFmpeg, regardless of this setting.
Video Renderer Type
this.player.PlaybackParameters.VideoRendererType = VAST.Media.VideoRendererType.Auto;
Video rendering backend with Auto, Best, and Compatible options. On platforms other than Windows, this setting has no effect because platform-specific rendering UI controls managed by the OS are used. On Windows, the Compatible option can be used to render on old computers, virtual machines, and other environments having issues with the Best renderer.
Output Audio Device
On Windows, the target audio output device can be set:
this.player.PlaybackParameters.AudioOutputDeviceId = deviceId;
Audio output devices are enumerated at startup using WASAPI:
await VAST.Capture.AudioDeviceEnumerator.Enumerate(
new VAST.Capture.AudioDeviceEnumeratorParameters
{
Framework = VAST.Common.MediaFramework.WASAPI,
Direction = VAST.Common.MediaFlowDirection.Output
});
Shared Media Source
Unlike the Simple Playback page which sets the player's Source property directly, the Extended Playback page creates a shared IMediaSource that can be used by both the player and the recording session simultaneously:
this.mediaSource = VAST.Media.SourceFactory.Create(this.tboxUri.Text);
this.mediaSource.Uri = this.tboxUri.Text;
this.mediaSource.AddRef();
this.player.SourceMedia = this.mediaSource;
this.player.Play();
AddRef() is called because the source may be shared between the player and the recording session. The source is released only when both the player and the recording session have stopped.
Recording
The page can record the playing stream to an MP4 file using IsoSink and MediaSession:
VAST.File.ISO.IsoSink fileSink = new VAST.File.ISO.IsoSink(
new VAST.File.ISO.ParsingParameters { WriteMediaDataLast = true });
fileSink.Uri = System.IO.Path.Combine(this.fileRecordingPath,
$"rec-{DateTime.Now:yyyy-MM-dd-HH-mm-ss}.mp4");
this.createMediaSource();
VAST.Media.MediaSession recordingSession = new VAST.Media.MediaSession();
recordingSession.AddSource(this.mediaSource);
recordingSession.AddSink(fileSink);
recordingSession.Start();
WriteMediaDataLast optimizes the MP4 file structure by writing the media data (mdat) after the movie header (moov), which enables faster playback start for the recorded file.
Recording reuses the existing media source if playback is already active, or creates a new one if it is not. Recording and playback can start and stop independently — the shared source is released only when both have stopped.
The recording file path is obtained from a platform-specific helper that returns the appropriate documents directory for each platform.
Snapshots
The page captures JPEG snapshots of the currently displayed video frame:
using (var jpegStream = await this.player.TakeSnapshot())
{
if (jpegStream != null)
{
using (var fs = new System.IO.FileStream(snapshotPath, System.IO.FileMode.OpenOrCreate))
{
jpegStream.Position = 0;
await jpegStream.CopyToAsync(fs);
}
}
}
TakeSnapshot() returns an asynchronous Stream containing JPEG image data. The snapshot is saved to the same directory as recordings with a timestamped filename.
Send Log
The page includes a Send Log button that uploads the application log file to VASTreaming support for diagnostics:
await VAST.Common.License.SendLog("MAUI extended playback issue");
SendLog sends the current log file to the support server. A valid license key must be configured for this feature to work.
See Also
- Sample Applications — overview of all demo projects
- MAUI App Demo — parent page with app initialization and demo page overview