Table of Contents

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:

  1. Plays media from a URI using MediaPlayerControl with configurable playback parameters
  2. Provides decoder framework and rendering strategy selection
  3. Configures video renderer type and audio output device on Windows
  4. Records the playing stream to an MP4 file while playback continues
  5. Captures JPEG snapshots of the current video frame
  6. 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