Acesso à pré-visualização da câmara com MediaCapture

Este artigo mostra como mostrar o fluxo de pré-visualização da câmara numa aplicação de desktop WinUI 3, gerir cenários de controlo exclusivos e gerir eventos do ciclo de vida da aplicação. Para um início rápido que cobre o básico de como mostrar uma pré-visualização da câmara, veja Mostrar a pré-visualização da câmara numa aplicação WinUI.

Exibir a visualização da câmera

No WinUI 3, usas o MediaPlayerElement para mostrar a pré-visualização da câmara. O controlo UWP CaptureElement não está disponível no WinUI 3.

Adicione a MediaPlayerElement à sua página XAML:

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

Inicialize MediaCapture

Cria uma instância do MediaCapture e inicializa-a com as definições desejadas. Pode especificar um dispositivo de câmara específico definindo o 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;
    }
}

Iniciar e parar a pré-visualização

Depois de inicializares MediaCapture, liga a câmara ao MediaPlayerElement para pré-visualização. No WinUI 3, utilize um MediaFrameSource para fornecer frames ao leitor multimédia:

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

No WinUI 3, não existe nenhum controlo CaptureElement. Em vez disso, ligue MediaCapture a MediaPlayerElement criando um(a) MediaSource a partir de um MediaFrameSource. Isto dá-te controlo sobre qual fonte de frames (câmara frontal, traseira, etc.) fornece a pré-visualização. Consulte Mostrar a pré-visualização da câmara numa aplicação WinUI para conhecer a abordagem recomendada que utiliza o exemplo Câmara do Windows.

Gerir o controlo exclusivo

Quando outra aplicação assume o controlo exclusivo da câmara, a instância MediaCapture recebe um evento Falha. Registe-se para este evento, por exemplo no seu método de inicialização:

_mediaCapture.Failed += MediaCapture_Failed;

Em seguida, limpa a pré-visualização quando o evento ocorrer:

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

Importante

Nas aplicações de desktop do WinUI 3, utiliza-se DispatcherQueue.TryEnqueue para redirecionar chamadas para a thread da interface. O método UWP CoreDispatcher.RunAsync não está disponível.

Gerir eventos do ciclo de vida da janela

Numa aplicação de desktop WinUI 3, o recurso da câmara mantém-se ativo mesmo quando a janela está minimizada ou oculta. Deves parar a pré-visualização quando a janela não estiver visível e reiniciá-la quando a janela voltar a ficar visível. No construtor da janela ou no método de inicialização, registe o evento VisibilityChanged:

this.VisibilityChanged += Window_VisibilityChanged;

Depois implementa o handler:

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

Limpeza de recursos

Quando a janela for fechada, pare a pré-visualização e elimine a instância MediaCapture. Registe-se no evento Closed, por exemplo, no construtor da janela:

this.Closed += Window_Closed;

Depois implementa o handler:

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