MediaFrameSourceGroup을 사용하여 다양한 소스로부터 캡처Capture from multiple sources using MediaFrameSourceGroup

이 문서에서는 여러 소스의 비디오를 여러 개의 포함 된 비디오 트랙을 포함 하는 단일 파일로 동시에 캡처하는 방법을 보여 줍니다.This article shows you how to capture video from multiple sources simultaneously to a single file with multiple embedded video tracks. RS3 부터는 단일 MediaEncodingProfile 에 대해 여러 videostreamdescriptor 개체를 지정할 수 있습니다.Starting with RS3, you can specify multiple VideoStreamDescriptor objects for a single MediaEncodingProfile. 이렇게 하면 여러 스트림을 동시에 단일 파일로 인코딩할 수 있습니다.This enables you to encode multiple streams simultaneously to a single file. 이 작업에서 인코딩된 비디오 스트림은 현재 장치에서 동시에 사용할 수 있는 카메라 집합을 지정 하는 단일 Mediaframesourcegroup 에 포함 되어야 합니다.The video streams that are encoded in this operation must be included in a single MediaFrameSourceGroup which specifies a set of cameras on the current device that can be used at the same time.

MediaFrameReader 클래스에서 Mediaf esourcegroup 을 사용 하 여 여러 카메라를 사용 하는 실시간 컴퓨터 비전 시나리오를 사용 하는 방법에 대 한 자세한 내용은 MediaFrameReader를 사용 하 여 미디어 프레임 처리를 참조 하세요.For information on using MediaFrameSourceGroup with the MediaFrameReader class to enable real-time computer vision scenarios that use multiple cameras, see Process media frames with MediaFrameReader.

이 문서의 나머지 부분에서는 두 컬러 카메라의 비디오를 여러 비디오 트랙을 포함 하는 단일 파일로 기록 하는 단계를 안내 합니다.The rest of this article will walk you through the steps of recording video from two color cameras to a single file with multiple video tracks.

사용 가능한 센서 그룹 찾기Find available sensor groups

Mediafsimulataneously Esourcegroup 은 액세스할 수 있는 프레임 원본 (일반적으로 카메라)의 컬렉션을 나타냅니다.A MediaFrameSourceGroup represents a collection of frame sources, typically cameras, that can be accessed simulataneously. 사용 가능한 프레임 소스 그룹 집합은 각 장치 마다 다르며,이 예제의 첫 번째 단계는 사용 가능한 프레임 원본 그룹 목록을 가져오고 시나리오에 필요한 카메라를 포함 하는 항목을 찾는 것입니다 .이 경우에는 두 가지 컬러 카메라가 필요 합니다.The set of available frame source groups is different for each device, so the first step in this example is to get the list of available frame source groups and finding one that contains the necessary cameras for the scenario, which in this case requires two color cameras.

MediafFindAllAsync 메서드는 현재 장치에서 사용할 수 있는 모든 소스 그룹을 반환 합니다.The MediaFrameSourceGroup.FindAllAsync method returns all source groups available on the current device. 반환 된 각 Mediaframesourcegroup 에는 그룹의 각 프레임 원본을 설명 하는 Mediaframesourcegroup 개체의 목록이 있습니다.Each returned MediaFrameSourceGroup has a list of MediaFrameSourceInfo objects that describes each frame source in the group. Linq 쿼리를 사용 하 여 전면 패널 및 후면에 하나씩 두 개의 컬러 카메라를 포함 하는 원본 그룹을 찾을 수 있습니다.A Linq query is used to find a source group that contains two color cameras, one on the front panel and one on the back. 선택한 Mediaframesourcegroup 및 각 컬러 카메라의 Mediaframesourcegroup 를 포함 하는 익명 개체가 반환 됩니다.An anonymous object is returned that contains the selected MediaFrameSourceGroup and the MediaFrameSourceInfo for each color camera. Linq 구문을 사용 하는 대신 각 그룹을 반복 하 고 각 Mediaframesourceinfo 를 사용 하 여 요구 사항을 충족 하는 그룹을 찾을 수 있습니다.Instead of using Linq syntax, you could instead loop through each group, and then each MediaFrameSourceInfo to look for a group that meets your requirements.

모든 장치에는 두 개의 컬러 카메라가 포함 된 원본 그룹이 포함 되지 않으므로 비디오를 캡처하기 전에 원본 그룹이 있는지 확인 해야 합니다.Note that not every device will contain a source group that contains two color cameras, so you should check to make sure that a source group was found before trying to capture video.

var sensorGroups = await MediaFrameSourceGroup.FindAllAsync();

var foundGroup = sensorGroups.Select(g => new
{
    group = g,
    color1 = g.SourceInfos.Where(info => info.SourceKind == MediaFrameSourceKind.Color && info.DeviceInformation.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Front).FirstOrDefault(),
    color2 = g.SourceInfos.Where(info => info.SourceKind == MediaFrameSourceKind.Color && info.DeviceInformation.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Back).FirstOrDefault()
}).Where(g => g.color1 != null && g.color2 != null).FirstOrDefault();

if (foundGroup == null)
{
    Debug.WriteLine("No groups found.");
    return;
}

MediaCapture 개체를 초기화 합니다.Initialize the MediaCapture object

MediaCapture 클래스는 UWP 앱의 대부분 오디오, 비디오 및 사진 캡처 작업에 사용 되는 기본 클래스입니다.The MediaCapture class is the primary class that is used for most audio, video, and photo capture operations in UWP apps. 초기화 매개 변수를 포함 하는 MediaCaptureInitializationSettings 개체를 전달 하 여 InitializeAsync 를 호출 하 여 개체를 초기화 합니다.Initialize the object by calling InitializeAsync, passing in a MediaCaptureInitializationSettings object that contains initialization parameters. 이 예제에서 지정 된 유일한 설정은 sourcegroup 속성입니다 .이 속성은 이전 코드 예제에서 검색 된 Mediaframesourcegroup 로 설정 됩니다.In this example, the only specified setting is the SourceGroup property, which is set to the MediaFrameSourceGroup that was retrieved in the previous code example.

미디어 캡처를 위해 MediaCapture 및 기타 UWP 앱 기능으로 수행할 수 있는 다른 작업에 대 한 자세한 내용은 카메라를 참조 하세요.For information on other operations you can perform with MediaCapture and other UWP app features for capturing media, see Camera.

var settings = new MediaCaptureInitializationSettings()
{
    SourceGroup = foundGroup.group
};

mediaCapture = new MediaCapture();
await mediaCapture.InitializeAsync(settings);

MediaEncodingProfile 만들기Create a MediaEncodingProfile

MediaEncodingProfile 클래스는 캡처된 오디오 및 비디오를 파일에 쓸 때 인코딩해야 하는 방법을 미디어 캡처 파이프라인에 알려 줍니다.The MediaEncodingProfile class tells the media capture pipeline how captured audio and video should be encoded as they are written to a file. 일반적인 캡처 및 트랜스 코딩 시나리오의 경우이 클래스는 CreateaviCreateMp3 와 같은 일반적인 프로필을 만들기 위한 정적 메서드 집합을 제공 합니다.For typical capture and transcoding scenarios, this class provides a set of static methods for creating common profiles, like CreateAvi and CreateMp3. 이 예제에서 인코딩 프로필은 Mpeg4 컨테이너와 H264 비디오 인코딩을 사용 하 여 수동으로 만듭니다.For this example, an encoding profile is manually created using an Mpeg4 container and H264 video encoding. 비디오 인코딩 설정은 VideoEncodingProperties 개체를 사용 하 여 지정 합니다.Video encoding settings are specified using a VideoEncodingProperties object. 이 시나리오에서 사용 되는 각 컬러 카메라에 대해 Videostreamdescriptor 개체가 구성 됩니다.For each color camera used in this scenario, a VideoStreamDescriptor object is configured. 이 설명자는 인코딩을 지정 하는 VideoEncodingProperties 개체를 사용 하 여 생성 됩니다.The descriptor is constructed with the VideoEncodingProperties object specifying the encoding. 비디오 StreamdescriptorLabel 속성은 스트림에 캡처되는 미디어 프레임 원본의 ID로 설정 해야 합니다.The Label property of the VideoStreamDescriptor must be set to the ID of the media frame source that will be captured to the stream. 캡처 파이프라인이 각 카메라에 사용 해야 하는 스트림 설명자와 인코딩 속성을 파악 하는 방법입니다.This is how the capture pipeline knows which stream descriptor and encoding properties should be used for each camera. 프레임 원본의 ID는 이전 섹션에서 Mediaframesourceinfo 을 선택 했을 때 찾은 Mediaframesourceinfo 개체에 의해 노출 됩니다.The ID of the frame source is exposed by the MediaFrameSourceInfo objects that were found in the previous section, when a MediaFrameSourceGroup was selected.

Windows 10 버전 1709부터 Setvideotracks 을 호출 하 여 MediaEncodingProfile 에 여러 encoding 속성을 설정할 수 있습니다.Starting with Windows 10, version 1709, you can set multiple encoding properties on a MediaEncodingProfile by calling SetVideoTracks. Getvideotracks 을 호출 하 여 비디오 스트림 설명자 목록을 검색할 수 있습니다.You can retrieve the list of video stream descriptors by calling GetVideoTracks. 단일 스트림 설명자를 저장 하는 Video 속성을 설정 하면 setvideotracks 을 호출 하 여 설정한 설명자 목록이 지정한 단일 설명자를 포함 하는 목록으로 바뀝니다.Note that if you set the Video property, which stores a single stream descriptor, the descriptor list you set by calling SetVideoTracks will be replaced with a list containing the single descriptor you specified.

var profile = new MediaEncodingProfile();
profile.Container = new ContainerEncodingProperties();
profile.Container.Subtype = MediaEncodingSubtypes.Mpeg4;

List<VideoStreamDescriptor> streams = new List<VideoStreamDescriptor>();

var encodeProps = VideoEncodingProperties.CreateH264();
encodeProps.Subtype = MediaEncodingSubtypes.H264;
var stream1Desc = new VideoStreamDescriptor(encodeProps);
stream1Desc.Label = foundGroup.color1.Id;
streams.Add(stream1Desc);

var encodeProps2 = VideoEncodingProperties.CreateH264();
encodeProps2.Subtype = MediaEncodingSubtypes.H264;
var stream2Desc = new VideoStreamDescriptor(encodeProps2);
stream2Desc.Label = foundGroup.color2.Id;
streams.Add(stream2Desc);

profile.SetVideoTracks(streams);
profile.Audio = null;

미디어 파일의 시간 제한 메타 데이터 인코딩Encode timed metadata in media files

Windows 10, 버전 1803부터 오디오 및 비디오 외에도, 데이터 형식이 지원 되는 미디어 파일로 시간 제한 된 메타 데이터를 인코딩할 수 있습니다.Starting with Windows 10, version 1803, in addition to audio and video you can encode timed metadata into a media file for which the data format is supported. 예를 들어 GoPro 메타 데이터 (gpmd)를 MP4 파일에 저장 하 여 비디오 스트림과 상관 관계가 지정 된 지리적 위치를 전달할 수 있습니다.For example, GoPro metadata (gpmd) can be stored in MP4 files to convey the geographic location correlated with a video stream.

인코딩 메타 데이터는 오디오 또는 비디오 인코딩에 대 한 병렬 패턴을 사용 합니다.Encoding metadata uses a pattern that is parallel to encoding audio or video. TimedMetadataEncodingProperties 클래스는 비디오에 대 한 VideoEncodingProperties 와 같은 메타 데이터의 형식, 하위 형식 및 인코딩 속성을 설명 합니다.The TimedMetadataEncodingProperties class describes the type, subtype and encoding properties of the metadata, like VideoEncodingProperties does for video. TimedMetadataStreamDescriptor 는 비디오 스트림에 대 한 videostreamdescriptor 와 마찬가지로 메타 데이터 스트림을 식별 합니다.The TimedMetadataStreamDescriptor identifies a metadata stream, just as the VideoStreamDescriptor does for video streams.

다음 예제에서는 TimedMetadataStreamDescriptor 개체를 초기화 하는 방법을 보여 줍니다.The following example shows how to intialize a TimedMetadataStreamDescriptor object. 먼저 TimedMetadataEncodingProperties 개체가 생성 되 고 하위 형식이 스트림에 포함 될 메타 데이터의 형식을 식별 하는 GUID로 설정 됩니다.First, a TimedMetadataEncodingProperties object is created and the Subtype is set to a GUID that identifies the type of metadata that will be included in the stream. 이 예제에서는 GoPro 메타 데이터 (gpmd)에 대해 GUID를 사용 합니다.This example uses the GUID for GoPro metadata (gpmd). Setformatuserdata 메서드를 호출 하 여 서식 지정 데이터를 설정 합니다.The SetFormatUserData method is called to set format-specific data. MP4 파일의 경우 형식 관련 데이터는 stsd (SampleDescription box)에 저장 됩니다.For MP4 files, the format-specific data is stored in the SampleDescription box (stsd). 그런 다음 인코딩 속성에서 새 TimedMetadataStreamDescriptor 을 만듭니다.Next, a new TimedMetadataStreamDescriptor is created from the encoding properties. 레이블이름 속성은 인코딩할 스트림을 식별 하도록 설정 됩니다.The Label and Name properties are set to identify the stream to be encoded.

           TimedMetadataEncodingProperties encodingProperties = new TimedMetadataEncodingProperties
           {
               Subtype = "{67706D64-BF10-48B4-BC18-593DC1DB950F}"
           };

           byte[] streamDescriptionData = GetStreamDescriptionDataForGpmdEncodingSubtype();
           encodingProperties.SetFormatUserData(streamDescriptionData);

           TimedMetadataStreamDescriptor descriptor = new TimedMetadataStreamDescriptor(encodingProperties)
           {
               Name = "GPS Info",
               Label = "GPS Info"
           };

MediaEncodingProfile 를 호출 하 여 메타 데이터 스트림 설명자를 인코딩 프로필에 추가 합니다.Call MediaEncodingProfile.SetTimedMetadataTracks to add the metadata stream descriptor to the encoding profile. 다음 예제에서는 두 개의 비디오 스트림 설명자, 하나의 오디오 스트림 설명자 및 1 개의 시간이 지정 된 메타 데이터 스트림 설명자를 사용 하 고 스트림을 인코딩하는 데 사용할 수 있는 MediaEncodingProfile 를 반환 하는 도우미 메서드를 보여 줍니다.The following example shows a helper method that takes two video stream descriptors, one audio stream descriptor, and one timed metadata stream descriptor and returns a MediaEncodingProfile that can be used to encode the streams.

public MediaEncodingProfile CreateProfileForTranscoder(VideoStreamDescriptor videoStream1, VideoStreamDescriptor videoStream2, AudioStreamDescriptor audioStream, TimedMetadataStreamDescriptor timedMetadataStream)
{
    ContainerEncodingProperties container = new ContainerEncodingProperties()
    {
        Subtype = MediaEncodingSubtypes.Mpeg4
    };

    MediaEncodingProfile profile = new MediaEncodingProfile()
    {
        Container = container
    };


    VideoStreamDescriptor encodingVideoStream1 = videoStream1.Copy();
    encodingVideoStream1.EncodingProperties.Subtype = MediaEncodingSubtypes.H264;
    encodingVideoStream1.Label = videoStream1.Name;

    VideoStreamDescriptor encodingVideoStream2 = videoStream2.Copy();
    encodingVideoStream2.EncodingProperties.Subtype = MediaEncodingSubtypes.H264;
    encodingVideoStream2.Label = videoStream2.Name;

    AudioStreamDescriptor encodingAudioStream = audioStream.Copy();
    encodingAudioStream.EncodingProperties.Subtype = MediaEncodingSubtypes.Ac3;
    encodingAudioStream.Label = audioStream.Name;

    TimedMetadataStreamDescriptor encodingTimedMetadataStream = timedMetadataStream.Copy();

    profile.SetTimedMetadataTracks(new TimedMetadataStreamDescriptor[] { encodingTimedMetadataStream });
    profile.SetVideoTracks(new VideoStreamDescriptor[] { encodingVideoStream1, encodingVideoStream2 });
    profile.SetAudioTracks(new AudioStreamDescriptor[] { encodingAudioStream });
    return profile;
}

다중 스트림 MediaEncodingProfile를 사용 하 여 기록Record using the multi-stream MediaEncodingProfile

이 예제의 마지막 단계에서는 StartRecordToStorageFileAsync 를 호출 하 고 캡처된 미디어가 작성 된 StorageFile 을 전달 하 고 이전 코드 예제에서 만든 MediaEncodingProfile 을 호출 하 여 비디오 캡처를 시작 합니다.The final step in this example is to initiate video capture by calling StartRecordToStorageFileAsync, passing in the StorageFile to which the captured media is written, and the MediaEncodingProfile created in the previous code example. 몇 초 동안 대기한 후에는 Stoprecordasync 를 호출 하 여 기록이 중지 됩니다.After waiting a few seconds, the recording is stopped with a call to StopRecordAsync.

var recordFile = await Windows.Storage.KnownFolders.CameraRoll.CreateFileAsync("record.mp4", Windows.Storage.CreationCollisionOption.GenerateUniqueName);
await mediaCapture.StartRecordToStorageFileAsync(profile, recordFile);
await Task.Delay(8000);
await mediaCapture.StopRecordAsync();

작업이 완료 되 면 파일 내의 별도 스트림으로 인코딩된 각 카메라에서 캡처된 비디오가 포함 된 비디오 파일이 생성 됩니다.When the operation is complete, a video file will have been created that contains the video captured from each camera encoded as a separate stream within the file. 여러 비디오 트랙을 포함 하는 미디어 파일을 재생 하는 방법에 대 한 자세한 내용은 미디어 항목, 재생 목록 및 트랙을 참조 하세요.For information on playing media files containing multiple video tracks, see Media items, playlists, and tracks.