Kameraförhandsgranskningsåtkomst med MediaCapture

Den här artikeln visar hur du visar kamerans förhandsgranskningsström i en WinUI 3-skrivbordsapp, hanterar exklusiva kontrollscenarier och hanterar händelser för appens livscykel. En snabbstart som beskriver grunderna för att visa en kameraförhandsgranskning finns i Visa kameraförhandsgranskningen i en WinUI-app.

Visa kameraförhandsgranskningen

I WinUI 3 använder du MediaPlayerElement för att visa kameraförhandsgranskningen. UWP-kontrollen CaptureElement är inte tillgänglig i WinUI 3.

Lägg till en MediaPlayerElement på XAML-sidan:

<MediaPlayerElement x:Name="PreviewElement"
                    AutoPlay="True"
                    HorizontalAlignment="Stretch" />

Initiera MediaCapture

Skapa en MediaCapture-instans och initiera den med önskade inställningar. Du kan ange en viss kameraenhet genom att ange VideoDeviceId.

using Windows.Media.Capture;
using Windows.Devices.Enumeration;

private MediaCapture _mediaCapture;

private async Task InitializeCameraAsync()
{
    _mediaCapture = new MediaCapture();

    var settings = new MediaCaptureInitializationSettings
    {
        StreamingCaptureMode = StreamingCaptureMode.Video
    };

    // Optionally select a specific camera
    var devices = await DeviceInformation.FindAllAsync(
        DeviceClass.VideoCapture);

    if (devices.Count > 0)
    {
        settings.VideoDeviceId = devices[0].Id;
    }

    try
    {
        await _mediaCapture.InitializeAsync(settings);
    }
    catch (UnauthorizedAccessException)
    {
        // Camera access denied — prompt the user to enable camera
        // access in Windows Settings.
        return;
    }
}

Starta och stoppa förhandsversionen

När du har initierat MediaCaptureansluter du kameran till förhandsgranskningsskärmen MediaPlayerElement . I WinUI 3 använder du en MediaFrameSource för att mata in bildrutor till spelaren:

using Windows.Media.Capture;
using Windows.Media.Capture.Frames;
using Microsoft.UI.Xaml.Controls;

private async Task StartPreviewAsync()
{
    // Get a frame source for the preview stream
    var frameSource = _mediaCapture.FrameSources.FirstOrDefault(
        source => source.Value.Info.MediaStreamType ==
            Windows.Media.Capture.MediaStreamType.VideoPreview
            || source.Value.Info.SourceKind ==
            MediaFrameSourceKind.Color);

    if (frameSource.Value != null)
    {
        var mediaSource = Windows.Media.Core.MediaSource
            .CreateFromMediaFrameSource(frameSource.Value);
        PreviewElement.Source = mediaSource;
    }
}

private async Task StopPreviewAsync()
{
    await _mediaCapture.StopPreviewAsync();
    PreviewElement.Source = null;
}

Note

I WinUI 3 finns det ingen CaptureElement kontroll. Anslut MediaCapture i stället till en MediaPlayerElement genom att skapa en MediaSource från en MediaFrameSource. Detta låter dig styra vilken bildkälla (frontkamera, bakre kamera osv.) som används för förhandsvisningen. Se Visa kameraförhandsgranskningen i en WinUI-app för den rekommenderade metoden med hjälp av exemplet Windows Kamera.

Hantera exklusiv styrning

När en annan app tar exklusiv kontroll över kameran får instansen MediaCapture en misslyckad händelse. Registrera dig för den här händelsen, till exempel i initieringsmetoden:

_mediaCapture.Failed += MediaCapture_Failed;

Rensa sedan förhandsversionen när händelsen inträffar:

private void MediaCapture_Failed(MediaCapture sender,
    MediaCaptureFailedEventArgs errorEventArgs)
{
    DispatcherQueue.TryEnqueue(async () =>
    {
        await StopPreviewAsync();
        // Display an error message to the user
    });
}

Important

I WinUI 3-skrivbordsappar använder du DispatcherQueue.TryEnqueue för att konvertera anrop tillbaka till användargränssnittstråden. UWP-metoden CoreDispatcher.RunAsync är inte tillgänglig.

Hantera livscykelhändelser för fönster

I en WinUI 3-skrivbordsapp förblir kameraresursen aktiv även när fönstret minimeras eller döljs. Du bör stoppa förhandsgranskningen när fönstret inte visas och starta om det när fönstret blir synligt igen. Registrera dig för VisibilityChanged händelsen i fönsterkonstruktorn eller initieringsmetoden:

this.VisibilityChanged += Window_VisibilityChanged;

Implementera sedan hanteraren:

private async void Window_VisibilityChanged(object sender,
    Microsoft.UI.Xaml.WindowVisibilityChangedEventArgs args)
{
    if (args.Visible)
    {
        await StartPreviewAsync();
    }
    else
    {
        await StopPreviewAsync();
    }
}

Rensa resurser

När fönstret stängs ska du stoppa förhandsvisningen och frigöra instansen MediaCapture. Registrera dig för Closed händelsen, till exempel i fönsterkonstruktorn:

this.Closed += Window_Closed;

Implementera sedan hanteraren:

private async void Window_Closed(object sender,
    Microsoft.UI.Xaml.WindowEventArgs args)
{
    await StopPreviewAsync();
    _mediaCapture?.Dispose();
    _mediaCapture = null;
}