비디오 캡처에 대한 효과

이 항목에서는 카메라 미리 보기 및 녹화 비디오 스트림에 효과를 적용하는 방법과 비디오 안정화 효과를 사용하는 방법을 보여 줍니다.

참고 항목

이 문서는 기본 사진 및 비디오 캡처 구현 단계를 설명하는 MediaCapture를 사용한 기본적인 사진, 비디오 및 오디오 캡처에 설명된 개념 및 코드를 토대로 작성되었습니다. 좀 더 수준 높은 캡처 시나리오를 진행하기 전에 해당 문서의 기본 미디어 캡처 패턴을 좀 더 잘 이해하는 것이 좋습니다. 이 문서의 코드는 앱에 적절히 초기화된 MediaCapture의 인스턴스가 이미 있다고 가정합니다.

카메라 비디오 스트림에서 효과 추가 및 제거

디바이스의 카메라에서 비디오를 캡처하거나 미리 보려면 MediaCapture를 사용하여 기본 사진, 비디오 및 오디오 캡처에 설명된 대로 MediaCapture 개체를 사용합니다. MediaCapture 개체를 초기화한 후 AddVideoEffectAsync를 호출하고, 추가할 효과를 나타내는 IVideoEffectDefinition 개체를 전달하고, 효과를 카메라의 미리 보기 스트림 또는 레코드 스트림에 추가할지 여부를 나타내는 MediaStreamType열거형의 멤버를 전달하여 하나 이상의 비디오 효과를 미리 보기 또는 캡처 스트림에 추가할 수 있습니다.

참고 항목

일부 디바이스에서는 미리 보기 스트림과 캡처 스트림이 동일합니다. 즉, AddVideoEffectAsync를 호출할 때 MediaStreamType.VideoPreview 또는 MediaStreamType.VideoRecord를 지정하면 미리 보기 스트림과 레코드 스트림 모두에 효과가 적용됩니다. MediaCapture 개체에 대한 MediaCaptureSettingsVideoDeviceCharacteristic 속성을 검사하여 현재 디바이스에서 미리 보기 및 레코드 스트림이 동일한지 여부를 확인할 수 있습니다. 이 속성의 값이 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을 구현하는 개체를 반환합니다. 일부 효과를 사용하면 PropertySetSetProperties 메서드에 전달하여 효과 설정을 변경할 수 있습니다.

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

Video stabilization 효과

비디오 손떨림 보정 효과는 비디오 스트림의 프레임을 조작하여 캡처 장치를 손에 들고서 발생하는 흔들림을 최소화합니다. 이 기술을 사용하면 픽셀이 오른쪽, 왼쪽, 위쪽 및 아래로 이동되고 효과에서 비디오 프레임 외부의 콘텐츠가 무엇인지 알 수 없으므로 안정화된 비디오가 원래 비디오에서 약간 잘립니다. 효과에 의해 수행되는 자르기를 최적으로 관리하도록 비디오 인코딩 설정을 조정할 수 있도록 유틸리티 함수가 제공됩니다.

이를 지원하는 디바이스에서 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를 호출하여 새 인코딩 속성을 설정합니다. 새 속성을 설정하기 전에 멤버 변수를 사용하여 초기 인코딩 속성을 저장하여 효과를 사용하지 않도록 설정할 때 설정을 다시 변경할 수 있습니다.

비디오 손떨림 보정 효과가 출력 비디오를 자르는 경우 권장되는 출력 인코딩 속성은 잘린 비디오의 크기입니다. 즉, 출력 해상도가 잘린 비디오 크기와 일치합니다. 권장 출력 속성을 사용하지 않는 경우 비디오는 초기 출력 크기와 일치하도록 확장되므로 시각적 충실도가 손실됩니다.

MediaEncodingProfile 개체의 Video 속성을 설정합니다. 새 속성을 설정하기 전에 멤버 변수를 사용하여 초기 인코딩 속성을 저장하여 효과를 사용하지 않도록 설정할 때 설정을 다시 변경할 수 있습니다.

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 값이 있습니다. 프로그래밍 방식으로 효과를 사용하거나 사용하지 않도록 설정하는 경우에도 이 이벤트가 발생합니다. 이 경우 그 이유는 프로그래밍 방식입니다.

일반적으로 이 이벤트를 사용하여 앱의 UI를 조정하여 비디오 안정화의 현재 상태 나타냅니다.

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;