Table of Contents

MAUI App Demo

The Demo.Streaming.MAUI project is a cross-platform .NET MAUI application that demonstrates capture, playback, WebRTC communication, and embedded server functionality using the VASTreaming SDK. It runs on Android, iOS, macOS, and Windows from a single codebase.

Important

Always test this application on a physical device. Android and iOS emulators have very limited media capabilities — hardware video codecs, camera capture, GPU-accelerated rendering, and real-time streaming perform poorly or do not work at all in emulated environments.

Demo Pages

The application uses a tabbed navigation layout. Each tab hosts a demo page showcasing a specific feature:

Page Tab Description Documentation
SimpleCapturePage Capture Camera/microphone capture and publishing to a remote server Simple Capture
ExtendedCapturePage Capture+ Advanced capture with video mixing and compositing Advanced Capture and Mixing
SimplePlaybackPage Playback Basic media playback from a remote source Simple Playback
ExtendedPlaybackPage Playback+ Advanced playback with recording and snapshots Advanced Playback
WebRtcPlaybackPage WebRTC WebRTC playback from a server One-Way WebRTC
WebRtcTwoWayPage WebRTC 2-Way WebRTC two-way communication between peers Two-Way WebRTC
ServerPage1 RTSP Server Embedded RTSP streaming server running within the app Embedded Server
ServerPage2 Multi-proto Server Multi-protocol streaming server supporting RTMP, RTSP, SRT, HLS, MPEG-DASH, and WebRTC Multi-Protocol Server

The application uses Shell-based navigation with a flyout menu. Pages that are always available are declared in AppShell.xaml:

<FlyoutItem Title="Simple Capture">
    <ShellContent ContentTemplate="{DataTemplate local:SimpleCapturePage}" />
</FlyoutItem>
<FlyoutItem Title="Simple Playback">
    <ShellContent ContentTemplate="{DataTemplate local:SimplePlaybackPage}" />
</FlyoutItem>
<FlyoutItem Title="Extended Playback">
    <ShellContent ContentTemplate="{DataTemplate local:ExtendedPlaybackPage}" />
</FlyoutItem>

Pages that require specific compilation symbols are added programmatically in AppShell.xaml.cs:

#if VAST_FEATURE_MIXING
// Insert Extended Capture after Simple Capture (index 1)
Items.Insert(1, new FlyoutItem
{
    Title = "Extended Capture",
    Items = { new ShellSection { Items = { new ShellContent {
        ContentTemplate = new DataTemplate(typeof(ExtendedCapturePage)) } } } }
});
#endif

#if VAST_FEATURE_WEBRTC
Items.Add(new FlyoutItem { Title = "WebRTC Playback", ... });
Items.Add(new FlyoutItem { Title = "WebRTC 2-Way", ... });
#endif

#if VAST_FEATURE_RTSP
Items.Add(new FlyoutItem { Title = "RTSP Server", ... });
#endif

#if VAST_FEATURE_CORESERVER
Items.Add(new FlyoutItem { Title = "Multi-proto Server", ... });
#endif

Application Initialization

MauiProgram

public static MauiApp CreateMauiApp()
{
    VAST.Common.Log.LogFileName = System.IO.Path.Combine(
        VAST.Common.SpecialFolderHelper.GetPath(
            VAST.Common.SpecialFolder.UserSpecificApplicationData),
        "Demo.Streaming.MAUI.log");
    VAST.Common.Log.LogLevel = VAST.Common.Log.Level.Debug;
    VAST.Common.Log.MaxLogFileSize = 10 * 1024 * 1024;

    VAST.Common.License.Key = "YOUR_LICENSE_KEY";

#if VAST_FEATURE_FFMPEG
    VAST.Codecs.CodecGlobal.Initialize();
#endif

    VAST.Common.NtpTime.Sync();

    var builder = MauiApp.CreateBuilder();
    builder
        .UseMauiApp<App>()
        .ConfigureFonts(fonts =>
        {
            fonts.AddFont("OpenSansRegular.ttf", "OpenSansRegular");
            fonts.AddFont("OpenSansSemibold.ttf", "OpenSansSemibold");
        }).ConfigureMauiHandlers(handlers =>
        {
            handlers.AddHandler(typeof(VAST.Controls.VideoPreviewControl),
                typeof(VAST.Controls.VideoPreviewHandler));
            handlers.AddHandler(typeof(VAST.Controls.MediaPlayerControlBase),
                typeof(VAST.Controls.MediaPlayerHandler));
        });

    return builder.Build();
}

The initialization performs the following:

  1. Logging — configures the log file in the platform-specific application data folder using SpecialFolderHelper, with a 10 MB file size limit
  2. License — the license key must be set before any other VASTreaming operation
  3. FFmpegCodecGlobal.Initialize() is called when the VAST_FEATURE_FFMPEG compilation symbol is defined to prevent codec assembly from being purged by linker
  4. NTP syncNtpTime.Sync() synchronizes the internal clock for accurate timestamp generation and sources synchronization in Advanced Capture and Mixing sample
  5. MAUI handlers — registers two custom MAUI handlers for VASTreaming UI controls:
Control Handler Description
VideoPreviewControl VideoPreviewHandler Renders live camera preview for capture pages
MediaPlayerControlBase MediaPlayerHandler Renders media playback for playback and WebRTC pages

App

protected override Window CreateWindow(IActivationState activationState)
{
    var window = new Window(new AppShell());
    window.Title = "VASTreaming MAUI Demo";
    window.Destroying += Window_Destroying;
    return window;
}

private void Window_Destroying(object sender, EventArgs e)
{
    VAST.Media.MediaGlobal.Uninitialize();
}

The App class creates the main window with AppShell (the Shell-based flyout container) as its root. MediaGlobal.Uninitialize() is called when the window is destroyed to stop internal monitoring threads and release resources.

Platform Support

The application targets the following platforms:

Platform Minimum Version
Windows Windows 10.0.19041
Android API 21+ (Android 5.0+)
iOS 12.2
macOS (Mac Catalyst) 12.0

Each platform has a PlatformSpecific partial class that provides platform-specific implementations (e.g., recording file paths).

Setup

  1. Set the license key in MauiProgram.cs:

    VAST.Common.License.Key = "YOUR_LICENSE_KEY";
    
  2. Select the target platform and run the application

See Also