Efek untuk pengambilan video

Topik ini menunjukkan kepada Anda cara menerapkan efek pada pratinjau kamera dan merekam aliran video dan menunjukkan kepada Anda cara menggunakan efek stabilisasi video.

Catatan

Artikel ini dibangun berdasarkan konsep dan kode yang dibahas dalam pengambilan foto, video, dan audio Dasar dengan MediaCapture, yang menjelaskan langkah-langkah untuk menerapkan pengambilan foto dan video dasar. Kami menyarankan agar Anda membiasakan diri dengan pola pengambilan media dasar dalam artikel tersebut sebelum beralih ke skenario pengambilan yang lebih canggih. Kode dalam artikel ini mengasumsikan bahwa aplikasi Anda sudah memiliki instans MediaCapture yang telah diinisialisasi dengan benar.

Menambahkan dan menghapus efek dari aliran video kamera

Untuk mengambil atau mempratinjau video dari kamera perangkat, Anda menggunakan objek MediaCapture seperti yang dijelaskan dalam Pengambilan foto, video, dan audio Dasar dengan MediaCapture. Setelah menginisialisasi objek MediaCapture , Anda dapat menambahkan satu atau beberapa efek video ke pratinjau atau mengambil aliran dengan memanggil AddVideoEffectAsync, meneruskan objek IVideoEffectDefinition yang mewakili efek yang akan ditambahkan, dan anggota enumerasi MediaStreamType yang menunjukkan apakah efek harus ditambahkan ke aliran pratinjau kamera atau aliran rekaman.

Catatan

Di beberapa perangkat, aliran pratinjau dan aliran pengambilan sama, yang berarti bahwa jika Anda menentukan MediaStreamType.VideoPreview atau MediaStreamType.VideoRecord saat Anda memanggil AddVideoEffectAsync, efeknya akan diterapkan ke pratinjau dan aliran rekaman. Anda dapat menentukan apakah pratinjau dan aliran rekaman sama pada perangkat saat ini dengan memeriksa properti VideoDeviceCharacteristic dari MediaCaptureSettings untuk objek MediaCapture . Jika nilai properti ini adalah VideoDeviceCharacteristic.AllStreamsIdentical atau VideoDeviceCharacteristic.PreviewRecordStreamsIdentical, maka alirannya sama dan efek apa pun yang Anda terapkan ke yang lain akan memengaruhi yang lain.

Contoh berikut menambahkan efek ke pratinjau kamera dan aliran rekaman. Contoh ini mengilustrasikan pemeriksaan untuk melihat apakah aliran rekaman dan pratinjau sama.

if (mediaCapture.MediaCaptureSettings.VideoDeviceCharacteristic == VideoDeviceCharacteristic.AllStreamsIdentical ||
    mediaCapture.MediaCaptureSettings.VideoDeviceCharacteristic == VideoDeviceCharacteristic.PreviewRecordStreamsIdentical)
{
    // This effect will modify both the preview and the record streams, because they are the same stream.
    myRecordEffect = await mediaCapture.AddVideoEffectAsync(myEffectDefinition, MediaStreamType.VideoRecord);
}
else
{
    myRecordEffect = await mediaCapture.AddVideoEffectAsync(myEffectDefinition, MediaStreamType.VideoRecord);
    myPreviewEffect = await mediaCapture.AddVideoEffectAsync(myEffectDefinition, MediaStreamType.VideoPreview);
}

Perhatikan bahwa AddVideoEffectAsync mengembalikan objek yang mengimplementasikan IMediaExtension yang mewakili efek video yang ditambahkan. Beberapa efek memungkinkan Anda mengubah pengaturan efek dengan meneruskan PropertySet ke metode SetProperties .

Dimulai dengan Windows 10, versi 1607, Anda juga dapat menggunakan objek yang dikembalikan oleh AddVideoEffectAsync untuk menghapus efek dari alur video dengan meneruskannya ke RemoveEffectAsync. RemoveEffectAsync secara otomatis menentukan apakah parameter objek efek ditambahkan ke pratinjau atau aliran rekaman, sehingga Anda tidak perlu menentukan jenis aliran saat melakukan panggilan.

if (myRecordEffect != null)
{
    await mediaCapture.RemoveEffectAsync(myRecordEffect);
}
if(myPreviewEffect != null)
{
    await mediaCapture.RemoveEffectAsync(myPreviewEffect);
}

Anda juga dapat menghapus semua efek dari pratinjau atau mengambil aliran dengan memanggil ClearEffectsAsync dan menentukan aliran yang semua efeknya harus dihapus.

await mediaCapture.ClearEffectsAsync(MediaStreamType.VideoPreview);
await mediaCapture.ClearEffectsAsync(MediaStreamType.VideoRecord);

Efek stabilisasi video

Efek stabilisasi video memanipulasi bingkai aliran video untuk meminimalkan goyangan yang disebabkan oleh memegang perangkat tangkapan di tangan Anda. Karena teknik ini menyebabkan piksel digeser ke kanan, kiri, atas, dan bawah, dan karena efeknya tidak dapat mengetahui apa konten di luar bingkai video, video yang stabil sedikit dipangkas dari video aslinya. Fungsi utilitas disediakan untuk memungkinkan Anda menyesuaikan pengaturan pengodean video Anda untuk mengelola pemotongan yang dilakukan oleh efek secara optimal.

Pada perangkat yang mendukungnya, Optical Image Stabilization (OIS) menstabilkan video dengan memanipulasi perangkat pengambilan secara mekanis dan, oleh karena itu, tidak perlu memangkas tepi bingkai video. Untuk informasi selengkapnya, lihat Mengambil kontrol perangkat untuk pengambilan video.

Menyiapkan aplikasi Anda untuk menggunakan stabilisasi video

Selain namespace yang diperlukan untuk pengambilan media dasar, menggunakan efek stabilisasi video memerlukan namespace layanan berikut.

using Windows.Media.Core;
using Windows.Media.MediaProperties;
using Windows.Media.Effects;
using Windows.Media;

Nyatakan variabel anggota untuk menyimpan objek VideoStabilizationEffect . Sebagai bagian dari implementasi efek, Anda akan memodifikasi properti pengodean yang Anda gunakan untuk mengodekan video yang diambil. Deklarasikan dua variabel untuk menyimpan salinan cadangan properti pengodean input dan output awal sehingga Anda dapat memulihkannya nanti saat efek dinonaktifkan. Terakhir, nyatakan variabel anggota jenis MediaEncodingProfile karena objek ini akan diakses dari beberapa lokasi dalam kode Anda.

private VideoStabilizationEffect _videoStabilizationEffect;
private VideoEncodingProperties _inputPropertiesBackup;
private VideoEncodingProperties _outputPropertiesBackup;
private MediaEncodingProfile _encodingProfile;

Untuk skenario ini, Anda harus menetapkan objek profil pengodean media ke variabel anggota sehingga Anda dapat mengaksesnya nanti.

_encodingProfile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto);

Menginisialisasi efek stabilisasi video

Setelah objek MediaCapture Anda diinisialisasi, buat instans baru objek VideoStabilizationEffectDefinition . Panggil MediaCapture.AddVideoEffectAsync untuk menambahkan efek ke alur video dan mengambil instans kelas VideoStabilizationEffect . Tentukan MediaStreamType.VideoRecord untuk menunjukkan bahwa efek harus diterapkan ke aliran rekaman video.

Daftarkan penanganan aktivitas untuk peristiwa EnabledChanged dan panggil metode pembantu SetUpVideoStabilizationRecommendationAsync, yang keduanya dibahas nanti di artikel ini. Terakhir, atur properti Efek yang diaktifkan ke true untuk mengaktifkan efek.

// Create the effect definition
VideoStabilizationEffectDefinition stabilizerDefinition = new VideoStabilizationEffectDefinition();

// Add the video stabilization effect to media capture
_videoStabilizationEffect =
    (VideoStabilizationEffect)await mediaCapture.AddVideoEffectAsync(stabilizerDefinition, MediaStreamType.VideoRecord);

_videoStabilizationEffect.EnabledChanged += VideoStabilizationEffect_EnabledChanged;

await SetUpVideoStabilizationRecommendationAsync();

_videoStabilizationEffect.Enabled = true;

Seperti yang dibahas sebelumnya dalam artikel ini, teknik yang digunakan efek stabilisasi video selalu menyebabkan video yang stabil dipangkas sedikit dari video sumber. Tentukan fungsi pembantu berikut dalam kode Anda untuk menyesuaikan properti pengodean video untuk menangani batasan efek ini secara optimal. Langkah ini tidak diperlukan untuk menggunakan efek stabilisasi video, tetapi jika Anda tidak melakukan langkah ini, video yang dihasilkan akan sedikit ditingkatkan skalanya dan karenanya memiliki keakuratan visual yang sedikit lebih rendah.

Panggil GetRecommendedStreamConfiguration pada instans efek stabilisasi video Anda, meneruskan objek VideoDeviceController , yang menginformasikan efek tentang properti pengodean aliran input Anda saat ini, dan MediaEncodingProfile Anda yang memungkinkan efek mengetahui properti pengodean output Anda saat ini. Metode ini mengembalikan objek VideoStreamConfiguration yang berisi properti pengodean aliran input dan output baru yang direkomendasikan.

Properti pengodean input yang direkomendasikan adalah, jika didukung oleh perangkat, resolusi yang lebih tinggi bahwa pengaturan awal yang Anda berikan sehingga ada kehilangan resolusi minimal setelah pemangkasan efek diterapkan.

Panggil VideoDeviceController.SetMediaStreamPropertiesAsync untuk mengatur properti pengodean baru. Sebelum mengatur properti baru, gunakan variabel anggota untuk menyimpan properti pengodean awal sehingga Anda dapat mengubah pengaturan kembali saat Menonaktifkan efek.

Jika efek stabilisasi video harus memangkas video output, properti pengodean output yang direkomendasikan akan menjadi ukuran video yang dipangkas. Ini berarti bahwa resolusi output akan cocok dengan ukuran video yang dipangkas. Jika Anda tidak menggunakan properti output yang direkomendasikan, video akan ditingkatkan agar sesuai dengan ukuran output awal, yang akan mengakibatkan hilangnya keakuratan visual.

Atur properti Video objek MediaEncodingProfile . Sebelum mengatur properti baru, gunakan variabel anggota untuk menyimpan properti pengodean awal sehingga Anda dapat mengubah pengaturan kembali saat Menonaktifkan efek.

private async Task SetUpVideoStabilizationRecommendationAsync()
{

    // Get the recommendation from the effect based on our current input and output configuration
    var recommendation = _videoStabilizationEffect.GetRecommendedStreamConfiguration(mediaCapture.VideoDeviceController, _encodingProfile.Video);

    // Handle the recommendation for the input into the effect, which can contain a larger resolution than currently configured, so cropping is minimized
    if (recommendation.InputProperties != null)
    {
        // Back up the current input properties from before VS was activated
        _inputPropertiesBackup = mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoRecord) as VideoEncodingProperties;

        // Set the recommendation from the effect (a resolution higher than the current one to allow for cropping) on the input
        await mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.VideoRecord, recommendation.InputProperties);
        await mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.VideoPreview, recommendation.InputProperties);
    }

    // Handle the recommendations for the output from the effect
    if (recommendation.OutputProperties != null)
    {
        // Back up the current output properties from before VS was activated
        _outputPropertiesBackup = _encodingProfile.Video;

        // Apply the recommended encoding profile for the output
        _encodingProfile.Video = recommendation.OutputProperties;
    }
}

Menangani efek stabilisasi video yang dinonaktifkan

Sistem dapat secara otomatis menonaktifkan efek stabilisasi video jika throughput piksel terlalu tinggi untuk ditangani efek atau jika mendeteksi bahwa efek berjalan lambat. Jika ini terjadi, peristiwa EnabledChanged akan dinaikkan. Instans VideoStabilizationEffect dalam parameter pengirim menunjukkan status baru efek, diaktifkan atau dinonaktifkan. Nilai VideoStabilizationEffectEnabledChangedEventArgs memiliki nilai VideoStabilizationEffectEnabledChangedReason yang menunjukkan mengapa efek diaktifkan atau dinonaktifkan. Perhatikan bahwa peristiwa ini juga dimunculkan jika Anda mengaktifkan atau menonaktifkan efek secara terprogram, dalam hal ini alasannya akan Terprogram.

Biasanya, Anda akan menggunakan peristiwa ini untuk menyesuaikan UI aplikasi Anda untuk menunjukkan status stabilisasi video saat ini.

private async void VideoStabilizationEffect_EnabledChanged(VideoStabilizationEffect sender, VideoStabilizationEffectEnabledChangedEventArgs args)
{
    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        // Update your UI to reflect the change in status
        ShowMessageToUser("video stabilization status: " + sender.Enabled + ". Reason: " + args.Reason);
    });
}

Membersihkan efek stabilisasi video

Untuk membersihkan efek stabilisasi video, panggil RemoveEffectAsync untuk menghapus efek dari alur video. Jika variabel anggota yang berisi properti pengodean awal tidak null, gunakan variabel tersebut untuk memulihkan properti pengodean. Terakhir, hapus penanganan aktivitas EnabledChanged dan atur efeknya ke null.

// Clear all effects in the pipeline
await mediaCapture.RemoveEffectAsync(_videoStabilizationEffect);

// If backed up settings (stream properties and encoding profile) exist, restore them and clear the backups
if (_inputPropertiesBackup != null)
{
    await mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.VideoRecord, _inputPropertiesBackup);
    _inputPropertiesBackup = null;
}

if (_outputPropertiesBackup != null)
{
    _encodingProfile.Video = _outputPropertiesBackup;
    _outputPropertiesBackup = null;
}

_videoStabilizationEffect.EnabledChanged -= VideoStabilizationEffect_EnabledChanged;

_videoStabilizationEffect = null;