Aufzeichnen von Screenshots sowie Audio-, Video- und Metadaten eines SpielsCapture game audio, video, screenshots, and metadata

In diesem Artikel wird beschrieben, wie Sie Spiele Videos, Audiodateien und Screenshots erfassen und Metadaten übermitteln, die das System in erfasste und Broadcast Medien einbettet, sodass Ihre APP und andere dynamische Umgebungen erstellen können, die mit den Spielereignissen synchronisiert werden.This article describes how to capture game video, audio, and screenshots, and how to submit metadata that the system will embed in captured and broadcast media, allowing your app and others to create dynamic experiences that are synchronized to gameplay events.

Es gibt zwei verschiedene Möglichkeiten, wie das-Spiel in einer UWP-App aufgezeichnet werden kann.There are two different ways that gameplay can be captured in a UWP app. Der Benutzer kann die Erfassung mithilfe der integrierten Benutzeroberfläche des Systems initiieren.The user can initiate capture using the built-in system UI. Medien, die mit dieser Technik aufgezeichnet werden, werden in das Microsoft Gaming-Ökosystem aufgenommen und können über die erstmaligen Benutzererfahrung, wie z. b. die Xbox-APP, angezeigt und freigegeben werden und sind nicht direkt für Ihre APP oder Benutzer verfügbar.Media that is captured using this technique is ingested into the Microsoft gaming ecosystem, can be viewed and shared through first-party experiences such as the Xbox app, and is not directly availble to your app or to users. In den ersten Abschnitten dieses Artikels erfahren Sie, wie Sie die vom System implementierte App-Erfassung aktivieren und deaktivieren und wie Sie Benachrichtigungen empfangen, wenn die APP-Erfassung startet oder beendet wird.The first sections of this article will show you how to enable and disable system-implemented app capture and how to receive notifications when app capture starts or stops.

Die andere Möglichkeit zum Erfassen von Medien besteht darin, die APIs des Windows. Media. apprecording -Namespace zu verwenden.The other way to capture media is to use the APIs of the Windows.Media.AppRecording namespace. Wenn die Erfassung auf dem Gerät aktiviert ist, kann Ihre APP mit dem Erfassen des Spiels beginnen, und nach einiger Zeit können Sie die Erfassung abbrechen. an diesem Punkt wird das Medium in eine Datei geschrieben.If capturing is enabled on the device, your app can start capturing gameplay and then, after some time has passed, you can stop the capture, at which point the media is written to a file. Wenn der Benutzer die Verlaufs Erfassung aktiviert hat, können Sie auch das bereits aufgetretene Spiel aufzeichnen, indem Sie eine Startzeit in der Vergangenheit und eine zu erfassende Dauer angeben.If the user has enabled historical capture, then you can also record gameplay that has already occured by specifying a start time in the past and a duration to record. Beide Verfahren führen zu einer Videodatei, auf die von ihrer App zugegriffen werden kann, und abhängig davon, wo die Dateien vom Benutzer gespeichert werden.Both of these techniques produce an video file that can be accessed by your app, and depending on where you choose to save the files, by the user. In den mittleren Abschnitten dieses Artikels werden Sie durch die Implementierung dieser Szenarien geführt.The middle sections of this article walk you through the implemenation of these scenarios.

Der Windows. Media. Capture -Namespace stellt APIs zum Erstellen von Metadaten bereit, die das erfasste oder übertragene Spielelement beschreiben.The Windows.Media.Capture namespace provides APIs for creating metadata that describes the gameplay being captured or broadcast. Dies kann Text-oder numerische Werte mit einer Text Bezeichnung enthalten, die die einzelnen Datenelemente identifiziert.This can include text or numeric values, with a text label identifying each data item. Metadaten können ein Ereignis darstellen, das zu einem bestimmten Zeitpunkt auftritt, z. b. wenn der Benutzer eine Runde in einem Renn Spiel beendet oder einen "Zustand" darstellen kann, der über einen bestimmten Zeitraum beibehalten wird, z. b. die aktuelle Spiel Zuordnung, in der der Benutzer abgespielt wird.Metadata can represent an "event" which occurs at a single moment, such as when the user finishes a lap in a racing game, or it can represent a "state" that persists over a span of time, such as the current game map the user is playing in. Die Metadaten werden in einen Cache geschrieben, der vom System für Ihre APP zugewiesen und verwaltet wird.The metadata is written to a cache that is allocated and managed for your app by the system. Die Metadaten werden in Broadcast Datenströme und erfasste Videodateien eingebettet, einschließlich integrierter System Erfassungs Verfahren oder benutzerdefinierter App-Erfassungs Verfahren.The metadata is embedded into broadcast streams and captured video files, including both the built-in system capture or custom app capture techniques. In den letzten Abschnitten dieses Artikels wird erläutert, wie Sie die Metadaten des-Spiels schreiben.The final sections of this article show you how to write gameplay metadata.

Hinweis

Da die Metadaten des Spiels in Mediendateien eingebettet werden können, die potenziell über das Netzwerk freigegeben werden können, sollten Sie keine personenbezogenen Informationen oder andere potenziell sensible Daten in die Metadaten einschließen.Because the gameplay metadata can be embedded in media files that can potentially be shared over the network, out of the user's control, you should not include personally identifiable information or other potentially sensitive data in the metadata.

Aktivieren und Deaktivieren der System-App-ErfassungEnable and disable system app capture

Die System-App-Erfassung wird vom Benutzer mit der integrierten Benutzeroberfläche des Systems initiiert.System app capture is initiated by the user with the built-in system UI. Die Dateien werden vom Windows-Gaming-Ökosystem erfasst und sind für Ihre APP oder den Benutzer nicht verfügbar, außer für die erstmaligen Benutzererfahrung wie die Xbox-app.The files are ingested by the Windows gaming ecosystem and is not available to your app or the user, except for through first party experiences like the Xbox app. Ihre APP kann die vom System initiierte App-Erfassung deaktivieren und aktivieren, sodass Sie verhindern können, dass der Benutzer bestimmte Inhalte oder ein bestimmtes Spiel erfassen kann.Your app can disable and enable system-initiated app capture, allowing you to prevent the user from capturing certain content or gameplay.

Um die System-App-Erfassung zu aktivieren oder zu deaktivieren , rufen Sie einfach die statische Methode " appcapture. abtallowedasync " auf, und übergeben Sie " false ", um die Erfassung zu deaktivierenTo enable or disable system app capture, simply call the static method AppCapture.SetAllowedAsync and passing false to disable capture or true to enable capture.

Windows::Media::Capture::AppCapture::SetAllowedAsync(allowed);

Benachrichtigungen empfangen, wenn die System-App-Erfassung gestartet und beendet wirdReceive notifications when system app capture starts and stops

Um eine Benachrichtigung zu erhalten, wenn die System-App-Erfassung beginnt oder endet, rufen Sie zuerst eine Instanz der appcapture -Klasse ab, indem Sie die Factorymethode getforcurrentview aufrufen.To receive a notification when system app capture begins or ends, first get an instance of the AppCapture class by calling the factory method GetForCurrentView. Registrieren Sie als nächstes einen Handler für das capturingchanged -Ereignis.Next, register a handler for the CapturingChanged event.

Windows::Media::Capture::AppCapture^ appCapture = Windows::Media::Capture::AppCapture::GetForCurrentView();
appCapture->CapturingChanged +=
    ref new TypedEventHandler<Windows::Media::Capture::AppCapture^, Platform::Object^>(this, &App::OnCapturingChanged);

Im-Handler für das capturingchanged -Ereignis können Sie die Eigenschaften iscapturingaudiound iscapturingvideo überprüfen, um festzustellen, ob Audiodaten bzw. Video aufgezeichnet werden.In the handler for the CapturingChanged event, you can check the IsCapturingAudio and the IsCapturingVideo properties to determine if audio or video are being captured respectively. Möglicherweise möchten Sie die Benutzeroberfläche Ihrer APP aktualisieren, um den aktuellen Erfassungs Status anzugeben.You may want to update your app's UI to indicate the current capturing status.

void App::OnCapturingChanged(Windows::Media::Capture::AppCapture^ sender, Platform::Object^ args)
{
    Platform::String^ captureStatusText = "";
    if (sender->IsCapturingAudio)
    {
        captureStatusText += "Capturing audio.";
    }
    if (sender->IsCapturingVideo)
    {
        captureStatusText += "Capturing video.";
    }
    UpdateStatusText(captureStatusText);
}

Hinzufügen der Windows-Desktop Erweiterungen für die UWP zu Ihrer APPAdd the Windows Desktop Extensions for the UWP to your app

Die APIs zum Aufzeichnen von Audiodaten und Videos sowie zum Erfassen von Screenshots direkt aus der APP, die im Windows. Media. apprecording -Namespace enthalten sind, sind nicht im universellen API-Vertrag enthalten.The APIs for recording audio and video and for capturing screenshots directly from your app, found in the Windows.Media.AppRecording namespace, are not included in the Universal API contract. Um auf die APIs zuzugreifen, müssen Sie mit den folgenden Schritten einen Verweis auf die Windows-Desktop Erweiterungen für die UWP zu Ihrer APP hinzufügen.To access the APIs, you must add a reference to the Windows Desktop Extensions for the UWP to your app with the following steps.

  1. Erweitern Sie in Visual Studio in Projektmappen-Explorerdas UWP-Projekt, klicken Sie mit der rechten Maustaste auf Verweise , und wählen Sie dann Verweis hinzufügen... aus.In Visual Studio, in Solution Explorer, expand your UWP project and right-click References and then select Add Reference....
  2. Erweitern Sie den Knoten Universal Windows , und wählen Sie Erweiterungenaus.Expand the Universal Windows node and select Extensions.
  3. Aktivieren Sie in der Liste der Erweiterungen das Kontrollkästchen neben den Windows-Desktop Erweiterungen für den UWP- Eintrag, der mit dem Zielbuild für Ihr Projekt übereinstimmt.In the list of extensions check the checkbox next to the Windows Desktop Extensions for the UWP entry that matches the target build for your project. Für die APP-Broadcast Features muss die Version 1709 oder höher sein.For the app broadcast features, the version must be 1709 or greater.
  4. Klicken Sie auf OK.Click OK.

Rufen Sie eine Instanz von apprecordingmanager ab.Get an instance of AppRecordingManager

Die apprecordingmanager -Klasse ist die zentrale API, die Sie zum Verwalten der APP-Aufzeichnung verwenden werden.The AppRecordingManager class is the central API you will use to manage app recording. Rufen Sie eine Instanz dieser Klasse ab, indem Sie die Factorymethode GetDefault aufrufen.Get an instance of this class by calling the factory method GetDefault. Bevor Sie eine der APIs im Windows. Media. apprecording -Namespace verwenden, sollten Sie überprüfen, ob Sie auf dem aktuellen Gerät vorhanden sind.Before using any of the APIs in the Windows.Media.AppRecording namespace, you should check for their presence on the current device. Die APIs sind nicht auf Geräten verfügbar, auf denen eine ältere Betriebssystemversion als Windows 10, Version 1709, ausgeführt wird.The APIs are not available on devices running an OS version earlier than Windows 10, version 1709. Anstatt eine bestimmte Betriebssystemversion zu überprüfen, verwenden Sie die Methode apiinformation. isapikontratpresent , um die Windows. Media. appbroadcasting. apprecordingcontract -Version 1,0 abzufragen.Rather than check for a specific OS version, use the ApiInformation.IsApiContractPresent method to query for the Windows.Media.AppBroadcasting.AppRecordingContract version 1.0. Wenn dieser Vertrag vorhanden ist, sind die Aufzeichnungs-APIs auf dem Gerät verfügbar.If this contract is present, then the recording APIs are available on the device. Der Beispielcode in diesem Artikel prüft einmal die APIs und überprüft dann, ob apprecordingmanager vor nachfolgenden Vorgängen NULL ist.The example code in this article checks for the APIs once and then checks if the AppRecordingManager is null before subsequent operations.

if (Windows::Foundation::Metadata::ApiInformation::IsApiContractPresent(
    "Windows.Media.AppRecording.AppRecordingContract", 1, 0))
{
    m_appRecordingManager = AppRecordingManager::GetDefault();
}

Ermitteln, ob Ihre APP zurzeit Daten aufzeichnen kannDetermine if your app can currently record

Es gibt mehrere Gründe, warum Ihre APP derzeit nicht in der Lage ist, Audiodaten oder Videos zu erfassen. Dies umfasst u. a., ob das aktuelle Gerät die Hardwareanforderungen für die Aufzeichnung nicht erfüllt oder ob derzeit eine andere APP sendet.There are several reasons that your app may not currently be able to capture audio or video, including if the current device doesn't meet the hardware requirements for recording or if another app is currently broadcasting. Vor dem Initiieren einer Aufzeichnung können Sie überprüfen, ob Ihre APP aktuell aufgezeichnet werden kann.Before initiating a recording, you can check to see if your app is currently able to record. Rufen Sie die GetStatus -Methode des apprecordingmanager -Objekts auf, und überprüfen Sie dann die canrecord -Eigenschaft des zurückgegebenen apprecordingstatus -Objekts.Call the GetStatus method of the AppRecordingManager object and then check the CanRecord property of the returned AppRecordingStatus object. Wenn canrecord falsezurückgibt, was bedeutet, dass Ihre APP derzeit nicht aufzeichnen kann, können Sie die Details -Eigenschaft überprüfen, um die Ursache zu ermitteln.If CanRecord returns false, meaning that your app can't currently record, you can check the Details property to determine the reason. Abhängig von der Ursache können Sie den Status des Benutzers anzeigen oder Anweisungen zum Aktivieren der APP-Aufzeichnung anzeigen.Depending on the reason, you may want to display the status to the user or show instructions for enabling app recording.

bool App::CanRecord()
{

    if (m_appRecordingManager == nullptr)
    {
        return false;
    }

    AppRecordingStatus^ recordingStatus = m_appRecordingManager->GetStatus();

    if (!recordingStatus->CanRecord)
    {
        AppRecordingStatusDetails^ details = recordingStatus->Details;
    
        if (details->IsAnyAppBroadcasting)
        {
            UpdateStatusText("Another app is currently broadcasting.");
            return false;
        }

        if (details->IsCaptureResourceUnavailable)
        {
            UpdateStatusText("The capture resource is currently unavailable.");
            return false;
        }

        if (details->IsGameStreamInProgress)
        {
            UpdateStatusText("A game stream is currently in progress.");
            return false;
        }

        if (details->IsGpuConstrained)
        {
            // Typically, this means that the GPU software does not include an H264 encoder
            UpdateStatusText("The GPU does not support app recording.");
            return false;
        }

        
        if (details->IsAppInactive)
        {
            // Broadcasting can only be started when the application's window is the active window.
            UpdateStatusText("The app window to be recorded is not active.");
            return false;
        }

        if (details->IsBlockedForApp)
        {
            UpdateStatusText("Recording is blocked for this app.");
            return false;
        }

        if (details->IsDisabledByUser)
        {
            UpdateStatusText("The user has disabled GameBar in Windows Settings.");
            return false;
        }

        if (details->IsDisabledBySystem)
        {
            UpdateStatusText("Recording is disabled by the system.");
            return false;
        }

        
        return false;
    }


    return true;
}

Manuelles Starten und Anhalten der Aufzeichnung ihrer app in einer DateiManually start and stop recording your app to a file

Nachdem Sie überprüft haben, dass Ihre APP aufzeichnen kann, können Sie eine neue Aufzeichnung starten, indem Sie die startrecordingtofileasync -Methode des apprecordingmanager -Objekts aufrufen.After verifying that your app is able to record, you can start a new recording by calling the StartRecordingToFileAsync method of the AppRecordingManager object.

Im folgenden Beispiel wird der erste Then -Block ausgeführt, wenn die asynchrone Aufgabe fehlschlägt.In the following example, the first then block executes when the asynchronous task fails. Der zweite dann -Block versucht, auf das Ergebnis der Aufgabe zuzugreifen, und wenn das Ergebnis NULL ist, wurde die Aufgabe abgeschlossen.The second then block attempts to access the result of the task and, if the result is null, then the task has completed. In beiden Fällen wird die Hilfsmethode onrecordingcomplete , wie unten gezeigt, aufgerufen, um das Ergebnis zu verarbeiten.In both cases, the OnRecordingComplete helper method, shown below, is called to handle the result.

void App::StartRecordToFile(Windows::Storage::StorageFile^ file)
{

    if (m_appRecordingManager == nullptr)
    {
        return;
    }

    if (!CanRecord())
    {
        return;
    }


    // Start a recording operation to record starting from 
    // now until the operation fails or is cancelled. 
    m_recordOperation = m_appRecordingManager->StartRecordingToFileAsync(file);

    create_task(m_recordOperation).then(
        [this](AppRecordingResult^ result)
    {
        OnRecordingComplete();
    }).then([this](task<void> t)
    {
        try
        {
            t.get();
        }
        catch (const task_canceled&)
        {
            OnRecordingComplete();
        }
    });
}

Wenn der Aufzeichnungs Vorgang abgeschlossen ist, überprüfen Sie die Eigenschaft erfolgreich des zurückgegebenen apprecordingresult -Objekts, um zu bestimmen, ob der Daten Satz Vorgang erfolgreich war.When the recording operation completes, check the Succeeded property of the returned AppRecordingResult object to determine if the record operation was successful. Wenn dies der Fall ist, können Sie die Eigenschaft " isfiletruncated " überprüfen, um zu ermitteln, ob das System aus Speicher Gründen gezwungen wurde, die erfasste Datei abzuschneiden.If so, you can check the IsFileTruncated property to determine if, for storage reasons, the system was forced to truncate the captured file. Sie können die Duration -Eigenschaft überprüfen, um die tatsächliche Dauer der aufgezeichneten Datei zu ermitteln, die, wenn die Datei abgeschnitten ist, möglicherweise kürzer als die Dauer des Aufzeichnungs Vorgangs ist.You can check the Duration property to discover the actual duration of the recorded file which, if the file is truncated, may be shorter than the duration of the recording operation.

void App::OnRecordingComplete()
{
    if (m_recordOperation)
    {
        auto result = m_recordOperation->GetResults();

        if (result->Succeeded)
        {
            Windows::Foundation::TimeSpan duration = result->Duration;
            boolean isTruncated = result->IsFileTruncated;

            UpdateStatusText("Recording completed.");
        }
        else
        {
            // If the recording failed, ExtendedError 
            // can be retrieved and used for diagnostic purposes 
            HResult extendedError = result->ExtendedError;
            LogTelemetryMessage("Error during recording: " + extendedError);
        }

        m_recordOperation = nullptr;
    }
}

Die folgenden Beispiele zeigen einen grundlegenden Code zum Starten und Beenden des Aufzeichnungs Vorgangs, der im vorherigen Beispiel gezeigt wurde.The following examples show some basic code for starting and stopping the recording operation shown in the previous example.

StorageFolder^ storageFolder = ApplicationData::Current->LocalFolder;
concurrency::create_task(storageFolder->CreateFileAsync("recordtofile_example.mp4", CreationCollisionOption::ReplaceExisting)).then(
    [this](StorageFile^ file)
{
    StartRecordToFile(file);
});
void App::FinishRecordToFile()
{
    m_recordOperation->Cancel();
}

Aufzeichnen einer historischen Zeitspanne in einer DateiRecord a historical time span to a file

Wenn der Benutzer die Verlaufs Aufzeichnung für Ihre APP in den Systemeinstellungen aktiviert hat, können Sie eine Zeitspanne des zuvor erstellenden Spiels aufzeichnen.If the user has enabled historical recording for your app in the system settings, you can record a time span of gameplay that has previously transpired. In einem vorherigen Beispiel in diesem Artikel wurde gezeigt, wie Sie sicherstellen können, dass Ihre APP aktuell ein Spiel aufzeichnen kann.A previous example in this article showed how to confirm that your app can currently record gameplay. Es gibt eine zusätzliche Überprüfung, um zu bestimmen, ob die Verlaufs Erfassung aktiviert ist.There is an additional check to determine if historical capture is enabled. Rufen Sie erneut GetStatus auf, und überprüfen Sie die canrecordtimespan -Eigenschaft des zurückgegebenen apprecordingstatus -Objekts.Once again, call GetStatus and check the CanRecordTimeSpan property of the returned AppRecordingStatus object. In diesem Beispiel wird auch die historicalbufferduration -Eigenschaft von apprecordingstatus zurückgegeben, die verwendet wird, um eine gültige Startzeit für den Aufzeichnungs Vorgang zu bestimmen.This example also returns the HistoricalBufferDuration property of the AppRecordingStatus which will be used to determine a valid start time for the recording operation.

bool App::CanRecordTimeSpan(TimeSpan &historicalDurationBuffer)
{

    if (m_appRecordingManager == nullptr)
    {
        return false;
    }

    AppRecordingStatus^ recordingStatus = m_appRecordingManager->GetStatus();
    if (recordingStatus->Details->IsTimeSpanRecordingDisabled)
    {
        UpdateStatusText("Historical time span recording is disabled by the system.");
        return false;
    }

    historicalDurationBuffer = recordingStatus->HistoricalBufferDuration;

    return true;
}

Zum Erfassen eines historischen Zeitraums müssen Sie eine Startzeit für die Aufzeichnung und eine Dauer angeben.To capture a historical timespan, you must specify a start time for the recording and a duration. Die Startzeit wird als DateTime -Struktur bereitgestellt.The start time is provided as a DateTime struct. Die Startzeit muss eine Uhrzeit vor der aktuellen Uhrzeit innerhalb der Länge des Verlaufs Aufzeichnungs Puffers sein.The start time must be a time before the current time, within the length of the historical recording buffer. In diesem Beispiel wird die Pufferlänge als Teil der Überprüfung abgerufen, um festzustellen, ob die historische Aufzeichnung aktiviert ist. Dies wird im obigen Codebeispiel veranschaulicht.For this example, the buffer length is retrieved as part of the check to see if historical recording is enabled, which is shown in the previous code example. Die Dauer der Verlaufs Aufzeichnung wird als TimeSpan -Struktur bereitgestellt, die auch gleich oder kleiner als die Dauer des Verlaufs Puffers sein sollte.The duration of the historical recording is provided as TimeSpan struct, which should also be equal to or smaller than the duration of the historical buffer. Nachdem Sie die gewünschte Startzeit und die gewünschte Dauer festgelegt haben, können Sie recordtimespandefileasync aufrufen, um den Aufzeichnungs Vorgang zu starten.Once you have determined your desired start time and duration, call RecordTimeSpanToFileAsync to start the recording operation.

Wie bei der Aufzeichnung mit manuellem starten und anhalten, wenn eine Verlaufs Aufzeichnung abgeschlossen ist, können Sie die Eigenschaft erfolgreich des zurückgegebenen apprecordingresult -Objekts überprüfen, um zu ermitteln, ob der Daten Satz Vorgang erfolgreich war, und Sie können die Eigenschaft isfiletruncated und Duration überprüfen, um die tatsächliche Dauer der aufgezeichneten Datei zu ermitteln. wenn die Datei abgeschnitten ist, kann die Dauer des angeforderten Zeitfensters kürzer seinLike recording with manual start and stop, when a historical recording completes, you can check the Succeeded property of the returned AppRecordingResult object to determine if the record operation was successful, and you can check the IsFileTruncated and Duration property to discover the actual duration of the recorded file which, if the file is truncated, may be shorter than the duration of the requested time window.

void App::RecordTimeSpanToFile(Windows::Storage::StorageFile^ file)
{


    if (m_appRecordingManager == nullptr)
    {
        return;
    }

    if (!CanRecord())
    {
        return;
    }

    Windows::Foundation::TimeSpan historicalBufferDuration;
    if (!CanRecordTimeSpan(historicalBufferDuration))
    {
        return;
    }
    

    AppRecordingStatus^ recordingStatus = m_appRecordingManager->GetStatus();
    
    Windows::Globalization::Calendar^ calendar = ref new Windows::Globalization::Calendar();
    calendar->SetToNow();

    Windows::Foundation::DateTime nowTime = calendar->GetDateTime();

    int secondsToRecord = min(30, historicalBufferDuration.Duration / 10000000);
    calendar->AddSeconds(-1 * secondsToRecord);

    Windows::Foundation::DateTime  startTime = calendar->GetDateTime();

    Windows::Foundation::TimeSpan duration;

    duration.Duration = nowTime.UniversalTime - startTime.UniversalTime;

    create_task(m_appRecordingManager->RecordTimeSpanToFileAsync(startTime, duration, file)).then(
        [this](AppRecordingResult^ result)
    {
        if (result->Succeeded)
        {
            Windows::Foundation::TimeSpan duration = result->Duration;
            boolean isTruncated = result->IsFileTruncated;
            UpdateStatusText("Recording completed.");
        }
        else
        {
            // If the recording failed, ExtendedError
            // can be retrieved and used for diagnostic purposes
            HResult extendedError = result->ExtendedError;
            LogTelemetryMessage("Error during recording: " + extendedError);
        }
    });

}

Das folgende Beispiel zeigt einen grundlegenden Code zum Initiieren des Verlaufs Daten Satz Vorgangs, der im vorherigen Beispiel gezeigt wurde.The following example shows some basic code for initiating the historical record operation shown in the previous example.

StorageFolder^ storageFolder = ApplicationData::Current->LocalFolder;
concurrency::create_task(storageFolder->CreateFileAsync("recordtimespantofile_example.mp4", CreationCollisionOption::ReplaceExisting)).then(
    [this](StorageFile^ file)
{
    RecordTimeSpanToFile(file);
});

Screenshot-Bilder in Dateien speichernSave screenshot images to files

Ihre APP kann eine Screenshot-Erfassung initiieren, bei der der aktuelle Inhalt des App-Fensters in einer Bilddatei oder in mehreren Bilddateien mit unterschiedlichen Bild Codierungen gespeichert wird.Your app can initiate a screenshot capture that will save the current contents of the app's window to one image file or to multiple image files with different image encodings. Um die Bild Codierungen anzugeben, die Sie verwenden möchten, erstellen Sie eine Liste von Zeichen folgen, in denen jedes einen Bildtyp darstellt.To specify the image encodings you would like to use, create a list of strings where each represents an image type. Die Eigenschaften von imageencodingsubtypes geben die richtige Zeichenfolge für jeden unterstützten Bildtyp an, z. b. MediaEncodingSubtypes.Png oder mediaencodingsubtypes. jpgxr.The properties of the ImageEncodingSubtypes provide the correct string for each supported image type, such as MediaEncodingSubtypes.Png or MediaEncodingSubtypes.JpegXr.

Initiieren Sie die Bildschirmaufnahme, indem Sie die savescreenshottofilesasync -Methode des apprecordingmanager -Objekts aufrufen.Initiate screen capture by calling the SaveScreenshotToFilesAsync method of the AppRecordingManager object. Der erste Parameter für diese Methode ist ein storagefolder-Ordner , in dem die Bilddateien gespeichert werden.The first parameter to this method is a StorageFolder where the image files will be saved. Der zweite Parameter ist ein Dateinamen Präfix, an das das System die Erweiterung für jeden gespeicherten Bildtyp anfügt (z. b. ". png").The second parameter is a filename prefix to which the system will append the extension for each image type saved, such as ".png".

Der dritte Parameter für saveskreenshotdefilesasync ist erforderlich, damit das System in der Lage ist, die ordnungsgemäße colorspace-Konvertierung durchzuführen, wenn das aktuelle Fenster, das aufgezeichnet werden soll, HDR-Inhalt anzeigt.The third parameter to SaveScreenshotToFilesAsync is necessary for the system to be able to do the proper colorspace conversion if the current window to be captured is displaying HDR content. Wenn HDR-Inhalt vorhanden ist, sollte dieser Parameter auf apprecordingsaveskreenshotoption. hdrcontentvisiblefestgelegt werden.If HDR content is present, this parameter should be set to AppRecordingSaveScreenshotOption.HdrContentVisible. Verwenden Sie andernfalls apprecordingsaveskreenshotoption. None.Otherwise, use AppRecordingSaveScreenshotOption.None. Der letzte Parameter für die-Methode ist die Liste der Bildformate, in denen der Bildschirm aufgezeichnet werden soll.The final parameter to the method is the list of image formats to which the screen should be captured.

Wenn der asynchrone Aufrufen von saveskreenshottofilesasync abgeschlossen ist, gibt er ein apprecordingsavedscreenshotinfo -Objekt zurück, das den storagefile -und den zugehörigen mediaencodingsubtypes -Wert bereitstellt, der den Bildtyp für jedes gespeicherte Bild angibt.When the asynchronous call to SaveScreenshotToFilesAsync completes, it returns a AppRecordingSavedScreenshotInfo object that provides the StorageFile and associated MediaEncodingSubtypes value indicating the image type for each saved image.

void App::SaveScreenShotToFiles(Windows::Storage::StorageFolder^ folder, Platform::String^ filenamePrefix)
{

    if (m_appRecordingManager == nullptr)
    {
        return;
    }


    Windows::Foundation::Collections::IVectorView<Platform::String^>^ supportedFormats = 
        m_appRecordingManager->SupportedScreenshotMediaEncodingSubtypes;

    
    Platform::Collections::Vector<Platform::String^>^ requestedFormats = 
        ref new Platform::Collections::Vector<Platform::String^>();

    for (Platform::String^ format : requestedFormats)
    {
        if (format == Windows::Media::MediaProperties::MediaEncodingSubtypes::Png)
        {
            requestedFormats->Append(format);
        }
        else if (format == Windows::Media::MediaProperties::MediaEncodingSubtypes::JpegXr)
        {
            requestedFormats->Append(format);
        }
    }


    create_task(m_appRecordingManager->SaveScreenshotToFilesAsync(folder, filenamePrefix, AppRecordingSaveScreenshotOption::None,
        requestedFormats->GetView())).then(
            [this](AppRecordingSaveScreenshotResult^ result)
    {
        if (result->Succeeded)
        {
            Windows::Foundation::Collections::IVectorView<AppRecordingSavedScreenshotInfo^>^ returnedScreenshots = result->SavedScreenshotInfos;

            for (AppRecordingSavedScreenshotInfo^ screenshotInfo : returnedScreenshots)
            {
                Windows::Storage::StorageFile^ file = screenshotInfo->File;
                Platform::String^ type = screenshotInfo->MediaEncodingSubtype;
            }
        }
        else
        {
            // If the recording failed, ExtendedError 
            // can be retrieved and used for diagnostic purposes 
            HResult extendedError = result->ExtendedError;
            LogTelemetryMessage("Error during screenshot: " + extendedError);
        }
    });
}

Das folgende Beispiel zeigt einen grundlegenden Code zum Initiieren des Screenshot-Vorgangs, der im vorherigen Beispiel gezeigt wurde.The following example shows some basic code for initiating the screenshot operation shown in the previous example.

StorageFolder^ storageFolder = ApplicationData::Current->LocalFolder;
SaveScreenShotToFiles(storageFolder, "screen_capture");

Hinzufügen von Spiel Metadaten für die von System und App initiierte ErfassungAdd game metadata for system and app-initiated capture

In den folgenden Abschnitten dieses Artikels wird beschrieben, wie Metadaten bereitgestellt werden, die das System in den MP4-Datenstrom des aufgezeichneten oder Broadcast-Spiels einbettet.The following sections of this article describe how to provide metadata that the system will embed into the MP4 stream of captured or broadcast gameplay. Metadaten können in Medien eingebettet werden, die mit der integrierten Systembenutzer Oberfläche und den von der APP mit apprecordingmanageraufgezeichneten Medien aufgezeichnet werden.Metadata can be embedded in media that is captured using the built-in system UI and media that is captured by the app with AppRecordingManager. Diese Metadaten können von Ihrer APP und anderen apps während der Medienwiedergabe extrahiert werden, um kontextabhängige Funktionen bereitzustellen, die mit dem erfassten oder Broadcast-Spiel synchronisiert werden.This metadata can be extracted by your app and other apps during media playback in order to provide contextually-aware experiences that are synchronized with the captured or broadcast gameplay.

Eine Instanz von AppCaptureMetadataWriter erhaltenGet an instance of AppCaptureMetadataWriter

Die primäre Klasse für die Verwaltung von App Capture-Metadaten ist AppCaptureMetadataWriter.The primary class for managing app capture metadata is AppCaptureMetadataWriter. Verwenden Sie vor dem Initialisieren einer Instanz dieser Klasse die apiinformation. isapikonpresent -Methode, um die Windows. Media. Capture. AppCaptureMetadataContract -Version 1,0 abzufragen und zu überprüfen, ob die API auf dem aktuellen Gerät verfügbar ist.Before initializing an instance of this class, use the ApiInformation.IsApiContractPresent method to query for the Windows.Media.Capture.AppCaptureMetadataContract version 1.0 to verify that the API is available on the current device.

if (Windows::Foundation::Metadata::ApiInformation::IsApiContractPresent("Windows.Media.Capture.AppCaptureMetadataContract", 1, 0))
{
    m_appCaptureMetadataWriter = ref new AppCaptureMetadataWriter();
}

Schreiben von Metadaten in den System Cache für Ihre APPWrite metadata to the system cache for your app

Jedes Metadatenelement verfügt über eine Zeichen folgen Bezeichnung, die das Metadatenelement identifiziert, einen zugeordneten Datenwert, der eine Zeichenfolge, eine ganze Zahl oder einen Double-Wert sein kann, und einen Wert aus der AppCaptureMetadataPriority -Enumeration, der die relative Priorität des Datenelements angibt.Each metadata item has a string label, identifying the metadata item, an associated data value which can be a string, an integer, or a double value, and a value from the AppCaptureMetadataPriority enumeration indicating the relative priority of the data item. Ein Metadatenelement kann entweder als "Ereignis" angesehen werden, das zu einem bestimmten Zeitpunkt auftritt, oder ein "State", das einen Wert über ein Zeitfenster verwaltet.A metadata item can either be considered an "event", which occurs at a single point in time, or a "state" which maintains a value over a time window. Metadaten werden in einen Speicher Cache geschrieben, der vom System für Ihre APP zugewiesen und verwaltet wird.Metadata is written to a memory cache that is allocated and managed for your app by the system. Das System erzwingt eine Größenbeschränkung für den metadatenarbeitsspeicher-Cache und löscht, wenn der Grenzwert erreicht wird, Daten basierend auf der Priorität, mit der die einzelnen Metadatenelemente geschrieben wurden.The system enforces a size limit on the metadata memory cache and, when the limit is reached, will purge data based on the priority with which each metadata item was written. Im nächsten Abschnitt dieses Artikels wird erläutert, wie Sie die Metadaten-Speicher Belegung Ihrer APP verwalten.The next section of this article shows how to manage your app's metadata memory allocation.

Eine typische App kann am Anfang der Erfassungs Sitzung einige Metadaten schreiben, um einen Kontext für die nachfolgenden Daten bereitzustellen.A typical app may choose to write some metadata at the beginning of the capture session to provide some context for the subsequent data. Für dieses Szenario wird empfohlen, dass Sie sofortige Ereignisdaten verwenden.For this scenario it is recommended that you use instantaneous "event" data. In diesem Beispiel werden addstringevent, adddoubleevent und AddInt32Event aufgerufen, um sofortige Werte für jeden Datentyp festzulegen.This example calls AddStringEvent, AddDoubleEvent, and AddInt32Event to set instantaneous values for each data type.

void App::StartSession(Platform::String^ sessionId, double averageFps, int resolutionWidth, int resolutionHeight)
{
    if (m_appCaptureMetadataWriter != nullptr)
    {
        m_appCaptureMetadataWriter->AddStringEvent("sessionId", sessionId, AppCaptureMetadataPriority::Informational);
        m_appCaptureMetadataWriter->AddDoubleEvent("averageFps", averageFps, AppCaptureMetadataPriority::Informational);
        m_appCaptureMetadataWriter->AddInt32Event("resolutionWidth", resolutionWidth, AppCaptureMetadataPriority::Informational);
        m_appCaptureMetadataWriter->AddInt32Event("resolutionHeight", resolutionHeight, AppCaptureMetadataPriority::Informational);
    }
}

Ein häufiges Szenario für die Verwendung von "State"-Daten, die im Laufe der Zeit beibehalten werden, besteht darin, die Spiel Zuordnung zu verfolgen, in der sich der SpielerA common scenario for using "state" data that persists over time is to track the game map that the player is currently within. In diesem Beispiel wird startstringstate aufgerufen, um den Statuswert festzulegen.This example calls StartStringState to set the state value.

void App::StartMap(Platform::String^ mapName)
{
    m_appCaptureMetadataWriter->StartStringState("map", mapName, AppCaptureMetadataPriority::Important);
}

Ruft den stopstate auf, um aufzuzeichnen, dass ein bestimmter Zustand beendet wurde.Call StopState to record that a particular state has ended.

void App::EndMap(Platform::String^ mapName)
{
    m_appCaptureMetadataWriter->StopState("map");
}

Sie können einen Zustand überschreiben, indem Sie einen neuen Wert mit einer vorhandenen Zustands Bezeichnung festlegen.You can overwrite a state by setting a new value with an existing state label.

void App::LevelUp(int newLevel)
{
    m_appCaptureMetadataWriter->StartInt32State("currentLevel", newLevel, AppCaptureMetadataPriority::Important);
}

Sie können alle gegenwärtig geöffneten Zustände beenden, indem Sie stopallstates aufrufen.You can end all currently open states by calling StopAllStates.

void App::RaceComplete()
{
    m_appCaptureMetadataWriter->StopAllStates();
}

Speicherlimit für Metadatencache verwaltenManage metadata cache storage limit

Die Metadaten, die Sie mit AppCaptureMetadataWriter schreiben, werden vom System zwischengespeichert, bis Sie in den zugehörigen Mediendaten Strom geschrieben werden.The metadata that you write with AppCaptureMetadataWriter is cached by the system until it is written to the associated media stream. Das System definiert eine Größenbeschränkung für den Metadatencache jeder app.The system defines a size limit for each app's metadata cache. Nachdem die Cache Größenbeschränkung erreicht wurde, beginnt das System mit der Löschung von zwischengespeicherten Metadaten.Once the cache size limit has been reached, the system will begin purging cached metadata. Das System löscht Metadaten, die mit dem Prioritätswert AppCaptureMetadataPriority. Information geschrieben wurden, bevor Metadaten mit dem AppCaptureMetadataPriority-Wert gelöscht werden . wichtige Priorität.The system will delete metadata that was written with AppCaptureMetadataPriority.Informational priority value before deleting metadata with the AppCaptureMetadataPriority.Important priority.

Sie können jederzeit überprüfen, ob die Anzahl der im Metadatencache ihrer App verfügbaren Bytes durch Aufrufen von " restingstoragebytesavailable" angezeigt wird.At any point, you can check to see the number of bytes available in your app's metadata cache by calling RemainingStorageBytesAvailable. Sie können auch einen eigenen, von der APP definierten Schwellenwert festlegen, nach dem Sie die Menge der Metadaten, die Sie in den Cache schreiben, reduzieren können.You can choose to set your own app-defined threshold after which you can choose to reduce the amount of metadata that you write to the cache. Das folgende Beispiel zeigt eine einfache Implementierung dieses Musters.The following example shows a simple implementation of this pattern.

void App::CheckMetadataStorage()
{
    INT64 storageRemaining = m_appCaptureMetadataWriter->RemainingStorageBytesAvailable;

    if (storageRemaining < m_myLowStorageLevelInBytes)
    {
        m_writeLowPriorityMetadata = false;
    }
}
void App::ComboExecuted(Platform::String^ comboName)
{
    if (m_writeLowPriorityMetadata)
    {
        m_appCaptureMetadataWriter->AddStringEvent("combo", comboName, AppCaptureMetadataPriority::Informational);
    }
}

Benachrichtigungen empfangen, wenn das System Metadaten löschtReceive notifications when the system purges metadata

Sie können sich registrieren, um eine Benachrichtigung zu erhalten, wenn das System mit dem Löschen von Metadaten für Ihre APP beginnt, indem Sie einen Handler für das MetadataPurged -Ereignis registrieren.You can register to receive a notification when the system begins purging metadata for your app by registering a handler for the MetadataPurged event.

if (m_appCaptureMetadataWriter != nullptr)
{
    m_appCaptureMetadataWriter->MetadataPurged += 
        ref new TypedEventHandler<AppCaptureMetadataWriter^, Platform::Object^>(this, &App::OnMetadataPurged);

}

Im-Handler für das MetadataPurged -Ereignis können Sie einen gewissen Raum im Metadatencache löschen, indem Sie den Status der niedrigeren Priorität beenden. Sie können APP-definierte Logik implementieren, um die Menge der Metadaten zu verringern, die Sie in den Cache schreiben, oder Sie können nichts tun, und das System kann den Cache weiterhin basierend auf der Priorität bereinigen, mit der er geschrieben wurde.In the handler for the MetadataPurged event, you can clear up some room in the metadata cache by ending lower-priority states, you can implement app-defined logic for reducing the amount of metadata you write to the cache, or you can do nothing and let the system continue to purge the cache based on the priority with which it was written.

void App::OnMetadataPurged(Windows::Media::Capture::AppCaptureMetadataWriter^ sender, Platform::Object^ args)
{
    // Reduce metadata by stopping a low-priority state.
    //m_appCaptureMetadataWriter->StopState("map");

    // Reduce metadata by stopping all states.
    //m_appCaptureMetadataWriter->StopAllStates();

    // Change app-specific behavior to write less metadata.
    //m_writeLowPriorityMetadata = false;

    // Take no action. Let the system purge data as needed. Record event for telemetry.
    OutputDebugString(TEXT("Low-priority metadata purged."));

}