Поделиться через


Эффекты для захвата видео

В этом разделе показано, как применить эффекты к просмотру и записи видеопотоков камеры и показано, как использовать эффект стабилизации видео.

Примечание.

В этой статье рассматриваются основные понятия и код, описанные в разделе "Базовый" фото, видео и аудиозапись с помощью MediaCapture, в котором описаны шаги по реализации базового фото и видеозахвата. Рекомендуется ознакомиться с основным шаблоном захвата мультимедиа в этой статье, прежде чем перейти к более сложным сценариям захвата. В коде этой статьи предполагается, что приложение уже имеет экземпляр MediaCapture, который был правильно инициализирован.

Добавление и удаление эффектов из видеопотока камеры

Чтобы записать или просмотреть видео с камеры устройства, используйте объект MediaCapture, как описано в разделе "Базовый" фото, видео и аудиозапись с помощью MediaCapture. После инициализации объекта MediaCapture можно добавить один или несколько эффектов видео в поток предварительной версии или записи, вызвав AddVideoEffectAsync, передав объект IVideoEffectDefinition, представляющий эффект, который нужно добавить, и элемент перечисления MediaStreamType, указывающий, следует ли добавить эффект в поток предварительной версии камеры или поток записи.

Примечание.

На некоторых устройствах поток предварительной версии и поток записи одинаковы, что означает, что при вызове AddVideoEffectAsync при вызове AddVideoEffectAsync при вызове MediaStreamType.VideoPreview будет применяться эффект как к предварительным, так и к потокам записей. Вы можете определить, совпадают ли потоки предварительной версии и записи на текущем устройстве, проверив свойство VideoDeviceCharacteristic объекта MediaCaptureSettings для объекта MediaCaptureSetting. Если значением этого свойства является VideoDeviceCharacteristic.AllStreamsIdentical или VideoDeviceCharacteristic.PreviewRecordStreamsIdentical, то потоки одинаковы, и любой эффект, который вы применяете к одному, повлияет на другое.

В следующем примере добавляется эффект как для предварительного просмотра камеры, так и для потоков записей. В этом примере показано, как проверить, совпадают ли записи и потоки предварительной версии.

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);
}

Обратите внимание, что AddVideoEffectAsync возвращает объект, реализующий IMediaExtension, представляющий добавленный эффект видео. Некоторые эффекты позволяют изменять параметры эффекта, передав свойствоSet в метод SetProperties.

Начиная с Windows 10 версии 1607, вы также можете использовать объект, возвращенный AddVideoEffectAsync, чтобы удалить эффект из конвейера видео, передав его в RemoveEffectAsync. RemoveEffectAsync автоматически определяет, был ли добавлен параметр объекта эффекта в предварительный просмотр или поток записей, поэтому при вызове не нужно указывать тип потока.

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

Вы также можете удалить все эффекты из потока предварительной версии или записи, вызвав ClearEffectsAsync и указав поток, для которого следует удалить все эффекты.

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

Эффект стабилизации видео

Эффект стабилизации видео управляет кадрами видеопотока, чтобы свести к минимуму сжатие, вызванное удержанием устройства захвата в руке. Так как этот метод приводит к смещению пикселей вправо, влево, вверх и вниз, и потому что эффект не может знать, что содержимое находится за пределами видеокадры, стабилизированное видео немного обрезается из исходного видео. Функция служебной программы предоставляется для настройки параметров кодирования видео, чтобы оптимально управлять обрезкой, выполняемой эффектом.

На устройствах, поддерживающих его, оптическое стабилизация изображений (OIS) стабилизирует видео путем механических манипуляций с устройством захвата и, следовательно, не требует обрезки краев видеокадров. Дополнительные сведения см. в разделе "Запись элементов управления устройствами" для записи видео.

Настройка приложения для использования стабилизации видео

Помимо пространств имен, необходимых для базового захвата мультимедиа, для эффекта стабилизации видео требуется следующее пространство имен.

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

Объявите переменную-член для хранения объекта VideoStabilizationEffect. В рамках реализации эффекта вы измените свойства кодирования, используемые для кодирования захваченного видео. Объявите две переменные, чтобы сохранить резервную копию исходных входных и выходных свойств кодирования, чтобы восстановить их позже при отключении эффекта. Наконец, объявите переменную-член типа MediaEncodingProfile , так как этот объект будет получен из нескольких расположений в коде.

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

Для этого сценария необходимо назначить объект профиля кодирования мультимедиа переменной-члену, чтобы получить к ней доступ позже.

_encodingProfile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto);

Инициализация эффекта стабилизации видео

После инициализации объекта MediaCapture создайте новый экземпляр объекта VideoStabilizationEffectDefinition. Вызовите MediaCapture.AddVideoEffectAsync, чтобы добавить эффект в конвейер видео и получить экземпляр класса VideoStabilizationEffect. Укажите MediaStreamType.VideoRecord , чтобы указать, что эффект должен применяться к потоку записи видео.

Зарегистрируйте обработчик событий для события EnabledChanged и вызовите вспомогательный метод SetUpVideoStabilizationRecommendationAsync, оба из которых рассматриваются далее в этой статье. Наконец, задайте для свойства Enabled эффект значение true, чтобы включить эффект.

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

Как упоминалось ранее в этой статье, метод, используемый эффект стабилизации видео, обязательно приводит к тому, что стабилизированное видео будет немного обрезано из исходного видео. Определите следующую вспомогательные функции в коде, чтобы настроить свойства кодирования видео, чтобы оптимально обработать это ограничение эффекта. Этот шаг не требуется для использования эффекта стабилизации видео, но если вы не выполняете этот шаг, результирующее видео будет немного масштабировано и, следовательно, немного ниже визуальной точности.

Вызовите GetRecommendedStreamConfiguration в экземпляре эффекта стабилизации видео, передавая объект VideoDeviceController, который сообщает эффект о свойствах кодирования текущего входного потока и MediaEncodingProfile, что позволяет эффекту знать текущие свойства кодировки выходных данных. Этот метод возвращает объект VideoStreamConfiguration , содержащий новые рекомендуемые свойства кодирования входных и выходных потоков.

Рекомендуемые свойства кодирования входных данных, если оно поддерживается устройством, более высокое разрешение, которое вы указали для обеспечения минимальной потери разрешения после применения обрезки эффекта.

Вызов VideoDeviceController.SetMediaStreamPropertiesAsync , чтобы задать новые свойства кодирования. Прежде чем задать новые свойства, используйте переменную-член для хранения начальных свойств кодирования, чтобы изменить параметры обратно при отключении эффекта.

Если эффект стабилизации видео должен обрезать выходное видео, рекомендуемые свойства кодировки выходных данных будут размером обрезанного видео. Это означает, что разрешение выходных данных будет соответствовать обрезанным размеру видео. Если вы не используете рекомендуемые свойства вывода, видео будет масштабироваться до исходного размера выходных данных, что приведет к потере визуальной точности.

Задайте свойство Video объекта MediaEncodingProfile. Прежде чем задать новые свойства, используйте переменную-член для хранения начальных свойств кодирования, чтобы изменить параметры обратно при отключении эффекта.

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

Обработка отключенного эффекта стабилизации видео

Система может автоматически отключить эффект стабилизации видео, если пропускная способность пикселя слишком высока для обработки эффекта или если он обнаруживает, что эффект работает медленно. Если это происходит, вызывается событие EnabledChanged. Экземпляр VideoStabilizationEffect в параметре отправителя указывает новое состояние эффекта, включено или отключено. VideoStabilizationEffectEnabledChangedEventArgs имеет значение VideoStabilizationEffectEnabledChangedReason, указывающее, почему эффект включен или отключен. Обратите внимание, что это событие также возникает при программном включении или отключении эффекта, в этом случае причина будет программной.

Как правило, это событие используется для настройки пользовательского интерфейса приложения, чтобы указать текущее состояние стабилизации видео.

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);
    });
}

Очистка эффекта стабилизации видео

Чтобы очистить эффект стабилизации видео, вызовите RemoveEffectAsync , чтобы удалить эффект из конвейера видео. Если переменные-члены, содержащие свойства начальной кодировки, не имеют значения NULL, используйте их для восстановления свойств кодирования. Наконец, удалите обработчик событий EnabledChanged и задайте значение 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;