Efek untuk pengambilan video

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

Catatan

Artikel ini didasarkan pada 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. Sebaiknya biasakan diri Anda dengan pola pengambilan media dasar dalam artikel itu sebelum beralih ke skenario pengambilan yang lebih maju. Kode dalam artikel ini mengasumsikan bahwa aplikasi Anda sudah memiliki instance MediaCapture yang telah diinsialisasi dengan benar.

Menambahkan dan menghapus efek dari aliran video kamera

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

Catatan

Pada beberapa perangkat, aliran pratinjau dan aliran tangkapan sama, yang berarti bahwa jika Anda menentukan MediaStreamType.VideoPreview atau MediaStreamType.VideoRecord saat Anda memanggil AddVideoEffectAsync, efeknya akan diterapkan ke pratinjau dan merekam aliran. Anda dapat menentukan apakah pratinjau dan streaming 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 pada satu akan memengaruhi yang lain.

Contoh berikut menambahkan efek ke pratinjau kamera dan merekam aliran. Contoh ini menggambarkan 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 untuk mengubah pengaturan efek dengan meneruskan PropertySet ke dalam 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, jadi 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 capture stream dengan memanggil ClearEffectsAsync dan menentukan aliran yang semua efek harus dihapus.

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

Efek stabilisasi video

Efek stabilisasi video memanipulasi bingkai aliran video untuk meminimalkan guncangan yang disebabkan oleh memegang perangkat penangkap 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 distabilkan dipotong sedikit dari video aslinya. Fungsi utilitas disediakan untuk memungkinkan Anda menyesuaikan pengaturan pengkodean video Anda untuk mengelola pemotongan yang dilakukan secara optimal oleh efek.

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

Menyiapkan aplikasi Anda untuk menggunakan stabilisasi video

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

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

Mendeklarasikan variabel anggota untuk menyimpan objek VideoStabilizationEffect . Sebagai bagian dari implementasi efek, Anda akan memodifikasi properti pengkodean yang Anda gunakan untuk menyandikan video yang diambil. Deklarasikan dua variabel untuk menyimpan salinan cadangan dari properti pengkodean input dan output awal sehingga Anda dapat memulihkannya nanti saat efeknya dinonaktifkan. Terakhir, deklarasikan variabel anggota tipe 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 pengkodean media ke variabel anggota sehingga Anda dapat mengaksesnya nanti.

_encodingProfile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto);

Menginisialisasi efek stabilisasi video

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

Daftarkan penangan peristiwa untuk acara EnabledChanged dan panggil metode pembantu SetUpVideoStabilizationRecommendationAsync, yang keduanya dibahas kemudian di artikel ini. Terakhir, atur properti Yang Diaktifkan efek ke true untuk mengaktifkan efeknya.

// 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 tentu menyebabkan video yang distabilkan dipotong sedikit dari video sumber. Tentukan fungsi pembantu berikut dalam kode Anda untuk menyesuaikan properti pengkodean 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 ditingkatkan sedikit dan karena itu memiliki kesetiaan visual yang sedikit lebih rendah.

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

Properti pengkodean input yang direkomendasikan adalah, jika didukung oleh perangkat, resolusi yang lebih tinggi bahwa pengaturan awal yang Anda berikan sehingga ada kerugian minimal dalam resolusi setelah pemotongan efek diterapkan.

Panggil VideoDeviceController.SetMediaStreamPropertiesAsync untuk mengatur properti pengkodean baru. Sebelum mengatur properti baru, gunakan variabel anggota untuk menyimpan properti pengkodean awal sehingga Anda dapat mengubah pengaturan kembali saat Anda menonaktifkan efeknya.

Jika efek stabilisasi video harus memotong video keluaran, properti pengkodean output yang disarankan akan menjadi ukuran video yang dipotong. Ini berarti bahwa resolusi output akan cocok dengan ukuran video yang dipotong. Jika Anda tidak menggunakan properti output yang disarankan, video akan ditingkatkan agar sesuai dengan ukuran output awal, yang akan mengakibatkan hilangnya kesetiaan visual.

Atur properti Video dari objek MediaEncodingProfile . Sebelum mengatur properti baru, gunakan variabel anggota untuk menyimpan properti pengkodean awal sehingga Anda dapat mengubah pengaturan kembali saat Anda menonaktifkan efeknya.

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 oleh efek atau jika mendeteksi bahwa efeknya berjalan lambat. Jika ini terjadi, peristiwa EnabledChanged akan dinaikkan. Instans VideoStabilizationEffect dalam parameter pengirim menunjukkan status efek baru, diaktifkan atau dinonaktifkan. VideoStabilizationEffectEnabledChangedEventArgs memiliki nilai VideoStabilizationEffectEnabledChangedReason yang menunjukkan mengapa efek diaktifkan atau dinonaktifkan. Perhatikan bahwa acara ini juga dinaikkan jika Anda secara terprogram mengaktifkan atau menonaktifkan efeknya, dalam hal ini alasannya akan Terprogram.

Biasanya, Anda akan menggunakan acara 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 pengkodean awal tidak null, gunakan untuk memulihkan properti pengkodean. Terakhir, hapus penangan peristiwa Yang Diaktifkan dan atur efeknya menjadi nol.

// 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;