Přístup k náhledu fotoaparátu pomocí MediaCapture

Tento článek ukazuje, jak zobrazit stream náhledu fotoaparátu v desktopové aplikaci WinUI 3, zpracovat exkluzivní řídicí scénáře a spravovat události životního cyklu aplikace. Rychlý start, který popisuje základy zobrazení náhledu fotoaparátu, najdete v tématu Zobrazení náhledu kamery v aplikaci WinUI.

Zobrazení náhledu kamery

Ve WinUI 3 použijete MediaPlayerElement k zobrazení náhledu kamery. Ovládací prvek UPW CaptureElement není k dispozici ve WinUI 3.

Přidejte na svou stránku XAML prvek MediaPlayerElement:

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

Inicializovat zachytávání médií

Vytvořte instanci MediaCapture a inicializujete ji s požadovaným nastavením. Konkrétní zařízení fotoaparátu můžete zadat nastavením 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;
    }
}

Spuštění a zastavení náhledu

Po inicializaci MediaCapturepřipojte fotoaparát k zobrazení náhledu MediaPlayerElement . Ve WinUI 3 použijte MediaFrameSource k podávání snímků přehrávači:

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

Ve WinUI 3 neexistuje žádný CaptureElement ovládací prvek. Místo toho připojte MediaCapture k objektu MediaPlayerElement vytvořením objektu MediaSource z objektu MediaFrameSource. Díky tomu máte kontrolu nad tím, jaký zdroj snímků (přední kamera, zadní kamera atd.) poskytuje náhled. Doporučený postup s využitím ukázky Windows Camera najdete v článku Zobrazení náhledu kamery v aplikaci WinUI.

Zpracování výhradního ovládacího prvku

Když jiná aplikace převezme výhradní kontrolu nad fotoaparátem, vaše MediaCapture instance obdrží událost , která selhala . Zaregistrujte se pro tuto událost, například v metodě inicializace:

_mediaCapture.Failed += MediaCapture_Failed;

Poté při výskytu události vyčistěte náhled:

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

Important

V desktopových aplikacích WinUI 3 použijte DispatcherQueue.TryEnqueue k zařazování volání zpět do vlákna uživatelského rozhraní. Metoda UPW CoreDispatcher.RunAsync není k dispozici.

Zpracování událostí životního cyklu okna

V desktopové aplikaci WinUI 3 zůstane prostředek fotoaparátu aktivní i v případě, že je okno minimalizované nebo skryté. Náhled byste měli zastavit, když okno není viditelné, a až se okno znovu zobrazí, restartujte ho. V konstruktoru okna nebo inicializační metodě zaregistrujte událost VisibilityChanged :

this.VisibilityChanged += Window_VisibilityChanged;

Poté implementujte obslužnou rutinu:

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

Vyčistěte zdroje

Po zavření okna zastavte náhled a uvolněte instanci MediaCapture. Zaregistrujte událost Closed, například v konstruktoru okna:

this.Closed += Window_Closed;

Poté implementujte obslužnou rutinu:

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