WinUI 3 앱에서 MediaCapture를 사용하여 기본 사진, 비디오 및 오디오 캡처
이 문서에서는 MediaCapture 클래스를 사용하여 사진과 비디오를 캡처하는 가장 간단한 방법을 보여줍니다. MediaCapture 클래스는 캡처 파이프라인에 대해 낮은 수준의 제어를 제공하고 고급 캡처 시나리오를 사용하도록 설정하는 강력한 API 집합을 노출하지만 이 문서는 앱에 기본 미디어 캡처를 빠르고 쉽게 추가할 수 있도록 하기 위한 것입니다. MediaCapture 제공하는 기능에 대한 자세한 내용은 카메라참조하세요.
MediaCapture 개체를 초기화합니다.
이 문서에서 설명하는 모든 캡처 메서드를 사용하려면 MediaCapture 개체를 초기화하는 첫 번째 단계가 필요합니다. 여기에는 개체 인스턴스화, 캡처 디바이스 선택, 초기화 매개 변수 설정, InitializeAsync호출 등이 포함됩니다. 일반적으로 카메라 앱은 MediaPlayerElement사용하여 UI에서 사진 또는 비디오를 캡처하는 동안 카메라 미리 보기를 표시합니다. MediaCapture를 초기화하고 XAML UI에서 미리 보기를 표시하는 방법에 대해 알고 싶다면, WinUI 3 앱에서 카메라 미리 보기 표시를 참조하세요. 이 문서의 코드 예제에서는 MediaCapture 초기화된 인스턴스가 이미 만들어졌다고 가정합니다.
SoftwareBitmap에 사진 캡처
SoftwareBitmap 클래스는 여러 기능에서 이미지의 일반적인 표현을 제공합니다. 앱에서 이미지를 캡처하여 파일에 저장하지 않고 즉시 사용하려면, 예를 들어 XAML에 표시하려는 경우, SoftwareBitmap로 캡처하는 것이 좋습니다. 나중에 디스크에 이미지를 저장할 수 있는 옵션이 있습니다.
SoftwareBitmap에 사진을 캡처하려면 LowLagPhotoCapture 클래스를 사용합니다. PrepareLowLagPhotoCaptureAsync호출하여 원하는 이미지 형식을 지정하는 ImageEncodingProperties 개체를 전달하여 이 클래스의 인스턴스를 가져옵니다. CreateUncompressed 지정된 픽셀 형식으로 압축되지 않은 인코딩을 만듭니다. CaptureAsync을 호출하여 사진 캡처를 시작하며, 이는 CapturedPhoto 개체를 반환합니다. Frame 속성에 먼저 접근한 다음, SoftwareBitmap 속성에 접근하여 SoftwareBitmap 가져옵니다.
CaptureAsync반복적으로 호출하여 여러 사진을 캡처할 수 있습니다. 캡처가 완료되면 FinishAsync 호출하여 LowLagPhotoCapture 세션을 종료하고 연결된 리소스를 해제합니다. FinishAsync호출한 후 사진 캡처를 다시 시작하려면 CaptureAsync호출하기 전에 PrepareLowLagPhotoCaptureAsync 다시 호출하여 캡처 세션을 다시 초기화해야 합니다.
// 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();
메모리 스트림에 사진 캡처
MediaCapture 사용하여 사진을 메모리 내 스트림으로 캡처한 다음 스트림에서 디스크의 파일로 사진을 트랜스코딩하는 데 사용할 수 있습니다.
InMemoryRandomAccessStream을 생성한 후, CapturePhotoToStreamAsync를 호출하여 스트림에 사진을 캡처합니다. 이때, 스트림과 함께 사용해야 할 이미지 형식을 지정하는 ImageEncodingProperties 객체를 전달합니다. 개체를 직접 초기화하여 사용자 지정 인코딩 속성을 만들 수 있지만 클래스는 일반적인 인코딩 형식에 대해 imageEncodingProperties.CreateJpeg
메모리 내의 스트림에서 이미지를 디코딩할 BitmapDecoder를 만듭니다. BitmapEncoder을 만들고, CreateForTranscodingAsync를 호출하여 이미지를 파일에 인코딩합니다.
필요에 따라 BitmapPropertySet 개체를 만든 다음 이미지 인코더에서 SetPropertiesAsync 호출하여 이미지 파일에 사진에 대한 메타데이터를 포함할 수 있습니다. 인코딩 속성에 대한 자세한 내용은 이미지 메타데이터참조하세요.
마지막으로 인코더 개체에서 FlushAsync 호출하여 메모리 내 스트림에서 파일로 사진을 트랜스코딩합니다.
// 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();
비디오 캡처
LowLagMediaRecording 클래스를 사용하여 앱에 비디오 캡처를 빠르게 추가합니다.
먼저 비디오를 캡처하는 동안 LowLagMediaRecording 유지해야 하므로 개체에 대한 클래스 변수를 선언합니다.
LowLagMediaRecording m_mediaRecording;
PrepareLowLagRecordToStorageFileAsync 호출하여 미디어 녹화를 초기화하고, 스토리지 파일 및 비디오 인코딩을 지정하는 MediaEncodingProfile 개체를 전달합니다. 클래스는 일반적인 비디오 인코딩 프로필을 만들기 위해 CreateMp4같은 정적 메서드를 제공합니다. StartAsync 호출하여 비디오 캡처를 시작합니다.
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();
비디오 녹화를 중지하려면 StopAsync호출합니다.
await m_mediaRecording.StopAsync();
추가 비디오를 캡처하려면 StartAsync 및 StopAsync를 계속 호출할 수 있습니다. 비디오 캡처가 완료되면 FinishAsync 호출하여 캡처 세션을 삭제하고 관련 리소스를 정리합니다. 이 호출 후에는 PrepareLowLagRecordToStorageFileAsync 다시 호출하여 StartAsync호출하기 전에 캡처 세션을 다시 초기화해야 합니다.
await m_mediaRecording.FinishAsync();
비디오를 캡처할 때 MediaCapture 개체의 RecordLimitationExceeded 이벤트에 대한 처리기를 등록해야 합니다. 이 이벤트는 현재 3시간 동안 단일 녹화에 대한 제한을 초과하면 운영 체제에서 발생합니다. 이벤트 처리기에서 StopAsync호출하여 기록을 완료해야 합니다.
private async void m_mediaCapture_RecordLimitationExceeded(MediaCapture sender)
{
await m_mediaRecording.StopAsync();
DispatcherQueue.TryEnqueue(() =>
{
tbStatus.Text = "Record limitation exceeded.";
});
}
PauseAsync 호출한 다음 ResumeAsync호출하여 비디오 녹화를 일시 중지한 다음 별도의 출력 파일을 만들지 않고 녹화를 다시 시작할 수 있습니다.
await m_mediaRecording.PauseAsync(Windows.Media.Devices.MediaCapturePauseBehavior.ReleaseHardwareResources);
await m_mediaRecording.ResumeAsync();
PauseWithResultAsync 호출하면 MediaCapturePauseResult 개체가 반환됩니다. LastFrame 속성은 마지막 프레임을 나타내는 VideoFrame 개체입니다. XAML에서 프레임을 표시하려면 비디오 프레임의 SoftwareBitmap 표현을 가져옵니다. 현재 미리 곱한 알파 채널 또는 빈 알파 채널이 있는 BGRA8 형식의 이미지만 지원되므로 필요한 경우 변환 호출하여 올바른 형식을 가져옵니다. PauseWithResultAsync 기록된 총 시간을 추적해야 하는 경우 이전 세그먼트에 녹화된 비디오의 기간도 반환합니다.
StopWithResultAsync호출하여 비디오를 중지할 때 결과 프레임을 가져올 수도 있습니다.
캡처한 비디오 파일 재생 및 편집
파일에 비디오를 캡처한 후에는 파일을 로드하고 앱의 UI 내에서 재생할 수 있습니다. 이 작업은 MediaPlayerElement XAML 컨트롤 및 연결된 MediaPlayer사용하여 수행할 수 있습니다. XAML 페이지에서 미디어를 재생하는 방법에 대한 자세한 내용은 MediaPlayer로 오디오 및 비디오 재생하기를 참조하세요.
[TBD - MediaComposition 프레임워크가 WinUI에 지원/권장되는가요?]
CreateFromFileAsync호출하여 비디오 파일에서 MediaClip 개체를 만들 수도 있습니다. MediaCompositionMediaClip 개체의 시퀀스 정렬, 비디오 길이 트리밍, 레이어 만들기, 배경 음악 추가 및 비디오 효과 적용과 같은 기본 비디오 편집 기능을 제공합니다. 미디어 컴퍼지션 작업에 대한 자세한 내용은 미디어 컴퍼지션 및 편집참조하세요.
오디오 녹음
비디오를 캡처하기 위해 위에 표시된 것과 동일한 기술을 사용하여 앱에 오디오 캡처를 빠르게 추가할 수 있습니다. PrepareLowLagRecordToStorageFileAsync을(를) 호출하여 캡처 세션을 초기화하고, 이 예제에서는 CreateMp3 정적 메서드로 생성한 MediaEncodingProfile을(를) 파일과 함께 전달합니다. 녹음/녹화를 시작하려면 StartAsync호출합니다.
[TBD - 이 코드는 '요청이 현재 상태에서 유효하지 않습니다.'를 throw합니다.
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();
StopAsync 호출하여 오디오 녹음을 중지합니다.
await m_mediaRecording.StopAsync();
StartAsync 및 StopAsync를 여러 번 호출하여 여러 오디오 파일을 녹음할 수 있습니다. 오디오 캡처가 완료되면 FinishAsync 호출하여 캡처 세션을 삭제하고 연결된 리소스를 정리합니다. 이 호출 후에는 PrepareLowLagRecordToStorageFileAsync 다시 호출하여 StartAsync호출하기 전에 캡처 세션을 다시 초기화해야 합니다.
시스템에서 오디오 캡처 스트림의 오디오 수준이 변경될 때 이를 감지하고 대응하는 방법에 대한 정보는 시스템에 의한 오디오 수준 변경 감지 및 대응을 참조하세요.
Windows developer