Akses pratinjau kamera dengan MediaCapture

Artikel ini menunjukkan cara menampilkan streaming pratinjau kamera di aplikasi desktop WinUI 3, menangani skenario kontrol eksklusif, dan mengelola peristiwa siklus hidup aplikasi. Untuk panduan memulai cepat yang membahas dasar-dasar menampilkan pratinjau kamera, lihat Menampilkan pratinjau kamera di aplikasi WinUI.

Tampilkan pratinjau kamera

Di WinUI 3, Anda menggunakan MediaPlayerElement untuk menampilkan pratinjau kamera. Kontrol UWP CaptureElement tidak tersedia di WinUI 3.

Tambahkan MediaPlayerElement ke halaman XAML Anda:

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

Menginisialisasi MediaCapture

Buat instans MediaCapture dan inisialisasi dengan pengaturan yang diinginkan. Anda dapat menentukan perangkat kamera tertentu dengan mengatur 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;
    }
}

Mulai dan hentikan pratinjau

Setelah Anda menginisialisasi , sambungkan MediaCapturekamera ke MediaPlayerElement untuk tampilan pratinjau. Di WinUI 3, gunakan MediaFrameSource untuk memberi umpan bingkai ke pemutar:

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

Di WinUI 3, tidak ada kontrol CaptureElement. Sebagai gantinya, sambungkan MediaCapture ke MediaPlayerElement dengan membuat MediaSource dari MediaFrameSource. Ini memungkinkan Anda mengontrol sumber frame mana (kamera depan, kamera belakang, dll.) yang menyediakan pratinjau. Lihat Menampilkan pratinjau kamera di aplikasi WinUI untuk pendekatan yang direkomendasikan menggunakan sampel kamera Windows.

Kelola kendali eksklusif

Saat aplikasi lain mengambil alih kendali eksklusif atas kamera, instance MediaCapture Anda akan menerima event Failed. Daftar untuk peristiwa ini, misalnya dalam metode inisialisasi Anda:

_mediaCapture.Failed += MediaCapture_Failed;

Lalu hapus pratinjau Anda saat peristiwa tersebut terjadi:

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

Important

Dalam aplikasi desktop WinUI 3, gunakan DispatcherQueue.TryEnqueue untuk mengarahkan panggilan kembali ke utas UI. Metode UWP CoreDispatcher.RunAsync tidak tersedia.

Menangani peristiwa siklus hidup jendela

Dalam aplikasi desktop WinUI 3, sumber daya kamera tetap aktif bahkan ketika jendela diminimalkan atau disembunyikan. Anda harus menghentikan pratinjau ketika jendela tidak terlihat dan memulai ulang ketika jendela terlihat lagi. Dalam konstruktor jendela atau metode inisialisasi Anda, daftarkan untuk event VisibilityChanged:

this.VisibilityChanged += Window_VisibilityChanged;

Kemudian terapkan handler:

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

Membersihkan sumber daya

Saat jendela ditutup, hentikan pratinjau dan lepaskan instans MediaCapture. Daftarkan event Closed, misalnya dalam konstruktor jendela Anda:

this.Closed += Window_Closed;

Kemudian terapkan handler:

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