Bagikan melalui


Pengambilan foto, video, dan audio dasar dengan MediaCapture di aplikasi WinUI 3

Artikel ini menunjukkan cara paling sederhana untuk mengambil foto dan video menggunakan kelas MediaCapture . Kelas MediaCapture mengekspos set API yang kuat yang memberikan kontrol tingkat rendah atas alur tangkapan dan mengaktifkan skenario pengambilan tingkat lanjut, tetapi artikel ini dimaksudkan untuk membantu Anda menambahkan pengambilan media dasar ke aplikasi Anda dengan cepat dan mudah. Untuk mempelajari selengkapnya tentang fitur yang disediakan MediaCapture , lihat Kamera.

Menginisialisasi objek MediaCapture

Semua metode pengambilan yang dijelaskan dalam artikel ini memerlukan langkah pertama untuk menginisialisasi objek MediaCapture . Ini termasuk membuat instans objek, memilih perangkat pengambilan, mengatur parameter inisialisasi, lalu memanggil InitializeAsync. Biasanya aplikasi kamera akan menampilkan pratinjau kamera saat mengambil foto atau video di UI mereka menggunakan MediaPlayerElement. Untuk panduan menginisialisasi MediaCapture dan menampilkan pratinjau di UI XAML, lihat Menampilkan pratinjau kamera di aplikasi WinUI. Contoh kode dalam artikel ini akan mengasumsikan bahwa instans MediaCapture yang diinisialisasi telah dibuat.

Mengambil foto ke SoftwareBitmap

Kelas SoftwareBitmap menyediakan representasi umum gambar di beberapa fitur. Jika Anda ingin mengambil foto dan kemudian segera menggunakan gambar yang diambil di aplikasi Anda, seperti menampilkannya di XAML, alih-alih mengambil ke file, maka Anda harus mengambil ke SoftwareBitmap. Anda masih memiliki opsi untuk menyimpan gambar ke disk nanti.

Ambil foto ke SoftwareBitmap menggunakan kelas LowLagPhotoCapture . Dapatkan instans kelas ini dengan memanggil PrepareLowLagPhotoCaptureAsync, meneruskan objek ImageEncodingProperties yang menentukan format gambar yang Anda inginkan. CreateUncompressed membuat pengodean yang tidak dikompresi dengan format piksel yang ditentukan. Mulai pengambilan foto dengan memanggil CaptureAsync, yang mengembalikan objek CapturedPhoto . Dapatkan SoftwareBitmap dengan mengakses properti Bingkai lalu properti SoftwareBitmap .

Anda dapat mengambil beberapa foto dengan berulang kali memanggil CaptureAsync. Setelah selesai menangkap, panggil FinishAsync untuk mematikan sesi LowLagPhotoCapture dan membebaskan sumber daya terkait. Setelah memanggil FinishAsync, untuk mulai mengambil foto lagi, Anda harus memanggil PrepareLowLagPhotoCaptureAsync lagi untuk menginisialisasi ulang sesi pengambilan sebelum memanggil CaptureAsync.

// Prepare and capture photo
var lowLagCapture = await m_mediaCapture.PrepareLowLagPhotoCaptureAsync(ImageEncodingProperties.CreateUncompressed(MediaPixelFormat.Bgra8));

var capturedPhoto = await lowLagCapture.CaptureAsync();
var softwareBitmap = capturedPhoto.Frame.SoftwareBitmap;

// Capture more photos, if desired.
// Then call FinishAsync to clean up resources
await lowLagCapture.FinishAsync();

Mengambil foto ke aliran memori

Anda dapat menggunakan MediaCapture untuk mengambil foto ke aliran dalam memori, yang kemudian dapat Anda gunakan untuk mentranskode foto dari aliran ke file di disk.

Buat InMemoryRandomAccessStream dan kemudian panggil CapturePhotoToStreamAsync untuk menangkap foto ke dalam stream, dengan menyertakan stream dan sebuah objek ImageEncodingProperties yang menentukan format gambar yang akan digunakan. Anda dapat membuat properti pengodean kustom dengan menginisialisasi objek sendiri, tetapi kelas menyediakan metode statis, seperti ImageEncodingProperties.CreateJpeg untuk format pengodean umum.

Buat BitmapDecoder untuk mendekode gambar dari aliran memori. Buat BitmapEncoder untuk mengodekan gambar ke file dengan memanggil CreateForTranscodingAsync.

Anda dapat secara opsional membuat objek BitmapPropertySet lalu memanggil SetPropertiesAsync pada encoder gambar untuk menyertakan metadata tentang foto dalam file gambar. Untuk informasi selengkapnya tentang properti pengodean, lihat Metadata gambar.

Terakhir, panggil FlushAsync pada objek encoder untuk mentranskode foto dari aliran dalam memori ke file.

// Prepare and capture photo
var lowLagCapture = await m_mediaCapture.PrepareLowLagPhotoCaptureAsync(ImageEncodingProperties.CreateUncompressed(MediaPixelFormat.Bgra8));

var capturedPhoto = await lowLagCapture.CaptureAsync();
var softwareBitmap = capturedPhoto.Frame.SoftwareBitmap;

// Capture more photos, if desired.
// Then call FinishAsync to clean up resources
await lowLagCapture.FinishAsync();

Mengambil video

Tambahkan pengambilan video dengan cepat ke aplikasi Anda dengan menggunakan kelas LowLagMediaRecording .

Pertama, LowLagMediaRecording perlu bertahan saat video sedang diambil, jadi deklarasikan variabel kelas ke untuk objek.

LowLagMediaRecording m_mediaRecording;

Panggil PrepareLowLagRecordToStorageFileAsync untuk menginisialisasi perekaman media, meneruskan file storage dan objek MediaEncodingProfile yang menentukan pengodean untuk video. Kelas ini menyediakan metode statis, seperti CreateMp4, untuk membuat profil pengodean video umum. Panggil StartAsync untuk mulai mengambil video.

var myVideos = await Windows.Storage.StorageLibrary.GetLibraryAsync(Windows.Storage.KnownLibraryId.Videos);
StorageFile file = await myVideos.SaveFolder.CreateFileAsync("video.mp4", CreationCollisionOption.GenerateUniqueName);
m_mediaRecording = await m_mediaCapture.PrepareLowLagRecordToStorageFileAsync(
        MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto), file);

m_mediaCapture.RecordLimitationExceeded += m_mediaCapture_RecordLimitationExceeded;
await m_mediaRecording.StartAsync();

Untuk berhenti merekam video, panggil StopAsync.

await m_mediaRecording.StopAsync();

Anda dapat terus memanggil StartAsync dan StopAsync untuk mengambil video tambahan. Setelah selesai mengambil video, panggil FinishAsync untuk membuang sesi pengambilan dan bersihkan sumber daya terkait. Setelah panggilan ini, Anda harus memanggil PrepareLowLagRecordToStorageFileAsync lagi untuk menginisialisasi ulang sesi pengambilan sebelum memanggil StartAsync.

await m_mediaRecording.FinishAsync();

Saat mengambil video, Anda harus mendaftarkan handler untuk peristiwa RecordLimitationExceeded dari objek MediaCapture , yang akan dinaikkan oleh sistem operasi jika Anda melampaui batas untuk satu perekaman, saat ini tiga jam. Di handler untuk peristiwa, Anda harus menyelesaikan rekaman Anda dengan memanggil StopAsync.

private async void m_mediaCapture_RecordLimitationExceeded(MediaCapture sender)
{
    await m_mediaRecording.StopAsync();
    DispatcherQueue.TryEnqueue(() =>
    {
        tbStatus.Text = "Record limitation exceeded.";
    });
}

Anda dapat menjeda perekaman video lalu melanjutkan perekaman tanpa membuat file output terpisah dengan memanggil PauseAsync lalu memanggil ResumeAsync.

await m_mediaRecording.PauseAsync(Windows.Media.Devices.MediaCapturePauseBehavior.ReleaseHardwareResources);
await m_mediaRecording.ResumeAsync();

Memanggil PauseWithResultAsync mengembalikan objek MediaCapturePauseResult. Properti LastFrame adalah objek VideoFrame yang mewakili bingkai terakhir. Untuk menampilkan bingkai di XAML, dapatkan representasi SoftwareBitmap dari bingkai video. Saat ini, hanya gambar dalam format BGRA8 dengan saluran alfa yang telah dipramultiplikasi atau kosong yang didukung, jadi gunakan Konversi jika perlu untuk mendapatkan format yang benar. PauseWithResultAsync juga mengembalikan durasi video yang direkam di segmen sebelumnya jika Anda perlu melacak berapa banyak total waktu yang telah direkam.

Anda juga bisa mendapatkan bingkai hasil saat menghentikan video dengan memanggil StopWithResultAsync.

Memutar dan mengedit file video yang diambil

Setelah mengambil video ke file, Anda mungkin ingin memuat file dan memutarnya kembali dalam UI aplikasi Anda. Anda dapat melakukan ini menggunakan kontrol MediaPlayerElement XAML dan MediaPlayer terkait. Untuk informasi tentang memutar media di halaman XAML, lihat Memutar audio dan video dengan MediaPlayer.

Anda juga dapat membuat objek MediaClip dari file video dengan memanggil CreateFromFileAsync. MediaComposition menyediakan fungsionalitas pengeditan video dasar seperti mengatur urutan objek MediaClip, memangkas panjang video, membuat lapisan, menambahkan musik latar belakang, dan menerapkan efek video. Untuk informasi selengkapnya tentang bekerja dengan komposisi media, lihat Komposisi dan pengeditan media.

Merekam audio

Anda dapat dengan cepat menambahkan pengambilan audio ke aplikasi Anda dengan menggunakan teknik yang sama yang ditunjukkan di atas untuk menangkap video. Panggil PrepareLowLagRecordToStorageFileAsync untuk menginisialisasi sesi pengambilan, meneruskan file dan MediaEncodingProfile yang dihasilkan dalam contoh ini dengan metode statis CreateMp3 . Untuk mulai merekam, panggil StartAsync.

m_mediaCapture.RecordLimitationExceeded += m_mediaCapture_RecordLimitationExceeded;

var myVideos = await Windows.Storage.StorageLibrary.GetLibraryAsync(Windows.Storage.KnownLibraryId.Videos);
StorageFile file = await myVideos.SaveFolder.CreateFileAsync("audio.mp3", CreationCollisionOption.GenerateUniqueName);
m_mediaRecording = await m_mediaCapture.PrepareLowLagRecordToStorageFileAsync(
        MediaEncodingProfile.CreateMp3(AudioEncodingQuality.High), file);
await m_mediaRecording.StartAsync();

Panggil StopAsync untuk menghentikan perekaman audio.

await m_mediaRecording.StopAsync();

Anda dapat memanggil StartAsync dan StopAsync beberapa kali untuk merekam beberapa file audio. Setelah selesai mengambil audio, panggil FinishAsync untuk membuang sesi pengambilan dan bersihkan sumber daya terkait. Setelah panggilan ini, Anda harus memanggil PrepareLowLagRecordToStorageFileAsync lagi untuk menginisialisasi ulang sesi pengambilan sebelum memanggil StartAsync.

Untuk informasi tentang mendeteksi kapan sistem mengubah tingkat audio aliran pengambilan audio, lihat Mendeteksi dan merespons perubahan tingkat audio oleh sistem.