Erfassen von mehreren Quellen mit „MediaFrameSourceGroup“Capture from multiple sources using MediaFrameSourceGroup

In diesem Artikel wird gezeigt, wie Sie Videos aus mehreren Quellen gleichzeitig in einer einzelnen Datei mit mehreren eingebetteten Videospuren erfassen.This article shows you how to capture video from multiple sources simultaneously to a single file with multiple embedded video tracks. Beginnend mit RS3 können Sie mehrere videostreamdescriptor -Objekte für ein einzelnes mediaencodingprofile-Objekt angeben.Starting with RS3, you can specify multiple VideoStreamDescriptor objects for a single MediaEncodingProfile. Dies ermöglicht es Ihnen, mehrere Streams gleichzeitig in einer einzelnen Datei zu codieren.This enables you to encode multiple streams simultaneously to a single file. Die in diesem Vorgang codierten Videostreams müssen in einer einzelnen mediaframesourcegroup enthalten sein, die eine Reihe von Kameras auf dem aktuellen Gerät angibt, die gleichzeitig verwendet werden können.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.

Informationen zur Verwendung von mediaframesourcegroup mit der mediaframereader -Klasse, um Szenarios in Echtzeit-Maschinelles sehen mit mehreren Kameras zu ermöglichen, finden Sie unter Verarbeiten von Medien Frames mit 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.

Der restliche Artikel führt Sie durch die Schritte zum Aufzeichnen von Videos von zwei Farbkameras in eine einzelne Datei mit mehreren Videospuren.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.

Suchen nach verfügbaren Sensor GruppenFind available sensor groups

Eine mediaframesourcegroup stellt eine Auflistung von Frame Quellen dar (in der Regel Kameras), auf die simuliert werden kann.A MediaFrameSourceGroup represents a collection of frame sources, typically cameras, that can be accessed simulataneously. Der Satz verfügbarer Frame Quell Gruppen unterscheidet sich für jedes Gerät. der erste Schritt in diesem Beispiel besteht darin, die Liste der verfügbaren Frame Quell Gruppen zu ermitteln und eine zu suchen, die die für das Szenario erforderlichen Kameras enthält. in diesem Fall sind zwei Farbkameras erforderlich.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.

Die mediaframesourcegroup. findallasync -Methode gibt alle auf dem aktuellen Gerät verfügbaren Quell Gruppen zurück.The MediaFrameSourceGroup.FindAllAsync method returns all source groups available on the current device. Jede zurückgegebene mediaframesourcegroup enthält eine Liste von mediaframesourceinfo -Objekten, die jede Frame Quelle in der Gruppe beschreibt.Each returned MediaFrameSourceGroup has a list of MediaFrameSourceInfo objects that describes each frame source in the group. Eine LINQ-Abfrage wird verwendet, um eine Quell Gruppe zu suchen, die zwei Farbkameras enthält, eine auf dem Vordergrund und eine auf der Rückseite.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. Ein anonymes Objekt, das die ausgewählte mediaframesourcegroup und die mediaframesourceinfo für jede Farbkamera enthält, wird zurückgegeben.An anonymous object is returned that contains the selected MediaFrameSourceGroup and the MediaFrameSourceInfo for each color camera. Anstatt die LINQ-Syntax zu verwenden, können Sie stattdessen die einzelnen Gruppen durchlaufen und dann alle mediaframesourceingefo -Elemente suchen, um nach einer Gruppe zu suchen, die Ihre Anforderungen erfüllt.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.

Beachten Sie, dass nicht jedes Gerät eine Quell Gruppe mit zwei Farbkameras enthalten wird. Daher sollten Sie überprüfen, ob eine Quell Gruppe gefunden wurde, bevor Sie versuchen, Video aufzuzeichnen.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;
}

Initialisieren des MediaCapture-ObjektsInitialize the MediaCapture object

Die mediacapture -Klasse ist die primäre Klasse, die für die meisten audiovorgänge, Video-und Foto Erfassungs Vorgänge in UWP-Apps verwendet wird.The MediaCapture class is the primary class that is used for most audio, video, and photo capture operations in UWP apps. Initialisieren Sie das-Objekt durch Aufrufen von initializeasync, und übergeben Sie ein mediacaptureinitializationsettings -Objekt, das Initialisierungs Parameter enthält.Initialize the object by calling InitializeAsync, passing in a MediaCaptureInitializationSettings object that contains initialization parameters. In diesem Beispiel ist die einzige angegebene Einstellung die sourcegroup -Eigenschaft, die auf die mediaframesourcegroup festgelegt wird, die im vorherigen Codebeispiel abgerufen wurde.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.

Informationen zu anderen Vorgängen, die Sie mit mediacapture und anderen UWP-App-Features für die Erfassung von Medien ausführen können, finden Sie unter Kamera.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);

Erstellen eines mediaencodingprofileCreate a MediaEncodingProfile

Die Media encodingprofile -Klasse teilt der Medien Erfassungs Pipeline mit, wie erfasste Audiodaten und Videos beim Schreiben in eine Datei codiert werden sollen.The MediaEncodingProfile class tells the media capture pipeline how captured audio and video should be encoded as they are written to a file. Für typische Aufzeichnungs-und Transcodierungs Szenarien stellt diese Klasse einen Satz statischer Methoden zum Erstellen allgemeiner Profile bereit, wie z. b. " kreateavi " und " CreateMp3".For typical capture and transcoding scenarios, this class provides a set of static methods for creating common profiles, like CreateAvi and CreateMp3. In diesem Beispiel wird ein Codierungs Profil manuell mithilfe eines MPEG4-Containers und der H264 Video-Codierung erstellt.For this example, an encoding profile is manually created using an Mpeg4 container and H264 video encoding. Video Codierungs Einstellungen werden mithilfe eines videoencodingproperties -Objekts angegeben.Video encoding settings are specified using a VideoEncodingProperties object. Für jede Farbkamera, die in diesem Szenario verwendet wird, wird ein videostreamdescriptor -Objekt konfiguriert.For each color camera used in this scenario, a VideoStreamDescriptor object is configured. Der Deskriptor wird mit dem videoencodingproperties -Objekt erstellt, das die Codierung angibt.The descriptor is constructed with the VideoEncodingProperties object specifying the encoding. Die Label -Eigenschaft von videostreamdescriptor muss auf die ID der Medien Frame Quelle festgelegt werden, die im Stream aufgezeichnet wird.The Label property of the VideoStreamDescriptor must be set to the ID of the media frame source that will be captured to the stream. Auf diese Weise weiß die Aufzeichnungs Pipeline, welche Datenstrom Deskriptoren und Codierungs Eigenschaften für die einzelnen Kamera verwendet werden sollen.This is how the capture pipeline knows which stream descriptor and encoding properties should be used for each camera. Die ID der Frame Quelle wird von den mediaframesourceinfo -Objekten, die im vorherigen Abschnitt gefunden wurden, bei Auswahl von " mediaframesourcegroup " verfügbar gemacht.The ID of the frame source is exposed by the MediaFrameSourceInfo objects that were found in the previous section, when a MediaFrameSourceGroup was selected.

Ab Windows 10, Version 1709, können Sie mehrere Codierungs Eigenschaften für ein mediaencodingprofile festlegen, indem Sie setvideotracks aufrufen.Starting with Windows 10, version 1709, you can set multiple encoding properties on a MediaEncodingProfile by calling SetVideoTracks. Sie können die Liste der videostreamdeskriptoren abrufen, indem Sie getvideotracks aufrufen.You can retrieve the list of video stream descriptors by calling GetVideoTracks. Beachten Sie Folgendes: Wenn Sie die Video -Eigenschaft festlegen, die einen einzelnen Datenstrom Deskriptor speichert, wird die durch den Aufruf von setvideotrack festgelegte deskriptorliste durch eine Liste ersetzt, die den einzelnen Deskriptor enthält, den Sie angegeben haben.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;

Codieren von zeitgesteuerten Metadaten in MediendateienEncode timed metadata in media files

Ab Windows 10, Version 1803, können Sie zusätzlich zu Audiodaten und Video zeitgesteuerte Metadaten in eine Mediendatei codieren, für die das Datenformat unterstützt wird.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. Beispielsweise kann die Datei "GoPro Metadata" (gpmd) in MP4-Dateien gespeichert werden, um den geografischen Standort zu übermitteln, der mit einem Videostream korreliertFor example, GoPro metadata (gpmd) can be stored in MP4 files to convey the geographic location correlated with a video stream.

Codierungs Metadaten verwenden ein Muster, das für die Codierung von Audiodaten oder Videos parallel ist.Encoding metadata uses a pattern that is parallel to encoding audio or video. Die TimedMetadataEncodingProperties -Klasse beschreibt den Typ, den Untertyp und die Codierungs Eigenschaften der Metadaten, wie z. b. videoencodingproperties für Video.The TimedMetadataEncodingProperties class describes the type, subtype and encoding properties of the metadata, like VideoEncodingProperties does for video. Der TimedMetadataStreamDescriptor identifiziert einen Metadatenstream, ebenso wie der videostreamdescriptor für Videostreams.The TimedMetadataStreamDescriptor identifies a metadata stream, just as the VideoStreamDescriptor does for video streams.

Im folgenden Beispiel wird gezeigt, wie ein TimedMetadataStreamDescriptor -Objekt initialisiert wird.The following example shows how to intialize a TimedMetadataStreamDescriptor object. Zuerst wird ein TimedMetadataEncodingProperties -Objekt erstellt, und der Untertyp wird auf eine GUID festgelegt, die den Typ der Metadaten identifiziert, die in den Stream eingeschlossen werden.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. In diesem Beispiel wird die GUID für die GoPro-Metadaten (gpmd) verwendet.This example uses the GUID for GoPro metadata (gpmd). Die setformatuserdata -Methode wird aufgerufen, um Format spezifische Daten festzulegen.The SetFormatUserData method is called to set format-specific data. Bei MP4-Dateien werden die Format spezifischen Daten im Feld sampledescription (sampledescription Box, STSD) gespeichert.For MP4 files, the format-specific data is stored in the SampleDescription box (stsd). Anschließend wird ein neues TimedMetadataStreamDescriptor aus den Codierungs Eigenschaften erstellt.Next, a new TimedMetadataStreamDescriptor is created from the encoding properties. Die Eigenschaften " Label " und " Name " werden festgelegt, um den zu codierenden Stream zu identifizieren.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"
           };

Aufrufen von mediaencodingprofile. SetTimedMetadataTracks , um den metadatenstreamdeskriptor zum Codierungs Profil hinzuzufügen.Call MediaEncodingProfile.SetTimedMetadataTracks to add the metadata stream descriptor to the encoding profile. Das folgende Beispiel zeigt eine Hilfsmethode, die zwei videostreamdeskriptoren, einen audiostreamdeskriptor und einen zeitgesteuerten metadatenstreamdeskriptor annimmt und ein mediaencodingprofile -Objekt zurückgibt, das zum Codieren der Streams verwendet werden kann.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;
}

Aufzeichnen mit dem Multistream mediaencodingprofileRecord using the multi-stream MediaEncodingProfile

Der letzte Schritt in diesem Beispiel besteht darin, die Video Erfassung durch Aufrufen von startrecordtostoragefileasync und durch Übergabe der storagefile-Datei , in die das erfasste Medium geschrieben wird, und des im vorherigen Codebeispiel erstellten mediaencodingprofile zu initiieren.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. Nachdem Sie einige Sekunden gewartet haben, wird die Aufzeichnung mit einem Aufrufen von stoprecordasync beendet.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();

Wenn der Vorgang abgeschlossen ist, wird eine Videodatei erstellt, die das Video enthält, das von den einzelnen Kameras als separater Stream in der Datei codiert wurde.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. Informationen zur Wiedergabe von Mediendateien, die mehrere Videospuren enthalten, finden Sie unter Medienelemente, Wiedergabelisten und Spuren.For information on playing media files containing multiple video tracks, see Media items, playlists, and tracks.