ゲームのオーディオ、ビデオ、スクリーンショット、メタデータのキャプチャCapture game audio, video, screenshots, and metadata

この記事では、ゲームのビデオ、オーディオ、スクリーン ショットをキャプチャする方法や、キャプチャおよびブロードキャストされるメディアにシステムが埋め込むメタデータを送信して、アプリや他のユーザーがゲームプレイのイベントに同期する動的なエクスペリエンスを作成できるようにする方法について説明します。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.

UWP アプリでゲームプレイをキャプチャするには、2 つの方法があります。There are two different ways that gameplay can be captured in a UWP app. ユーザーは、組み込みのシステム UI を使用してキャプチャを開始できます。The user can initiate capture using the built-in system UI. この手法を使用してキャプチャされたメディアは、Microsoft ゲーム エコシステムに取り込まれ、XBox アプリなど、ファースト パーティのエクスペリエンスを通して表示、共有されます。アプリやユーザーが、直接使用することはできません。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. この記事の最初のセクションでは、システムに実装されたアプリのキャプチャを有効または無効にする方法と、アプリのキャプチャが開始または停止されたときに通知を受信する方法を示します。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.

メディアをキャプチャするもう 1 つの方法は、Windows.Media.AppRecording 名前空間の API を使用する方法です。The other way to capture media is to use the APIs of the Windows.Media.AppRecording namespace. デバイスでキャプチャが有効になっている場合、アプリはゲームプレイのキャプチャを開始し、しばらく時間が経過した後、キャプチャを停止できます。その時点で、メディアはファイルに書き込まれます。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. ユーザーが履歴のキャプチャを有効にしている場合、過去の開始時刻と記録の継続時間を指定することによって、既に発生したゲームプレイも記録できます。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. これらのいずれの手法でも、アプリでアクセスできるビデオ ファイルが生成されます。また、ファイルを保存するために選択した場所によっては、ユーザーがアクセスできるビデオ ファイルが生成されます。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. この記事の中ほどのセクションでは、これらのシナリオを実装する手順について説明します。The middle sections of this article walk you through the implemenation of these scenarios.

Windows.Media.Capture 名前空間は、キャプチャまたはブロードキャストされるゲームプレイを説明するメタデータを作成するための API を提供します。The Windows.Media.Capture namespace provides APIs for creating metadata that describes the gameplay being captured or broadcast. これには、テキストや数値を、各データ項目を識別するテキスト ラベルと共に含めることができます。This can include text or numeric values, with a text label identifying each data item. メタデータは、1 つの時点で発生する "イベント" (ユーザーがレーシング ゲームでコースを走り終えたときなど) を表すことができます。また、一定期間保持される "状態" (ユーザーがプレイしている現在のゲーム マップなど) を表すこともできます。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. メタデータは、システムによってアプリ用に割り当てられて管理されるキャッシュに書き込まれます。The metadata is written to a cache that is allocated and managed for your app by the system. メタデータは、組み込みのシステム キャプチャとカスタム アプリによるキャプチャのいずれの手法でも、ブロードキャスト ストリームやキャプチャしたビデオ ファイルに埋め込まれます。The metadata is embedded into broadcast streams and captured video files, including both the built-in system capture or custom app capture techniques. この記事の最後のセクションでは、ゲームプレイのメタデータを書き込む方法について説明します。The final sections of this article show you how to write gameplay metadata.

注意

ゲームプレイのメタデータは、潜在的に、ネットワーク上でユーザーの制御の範囲外で共有できるメディア ファイルに埋め込まれる可能性があるため、個人を特定できる情報やその他の潜在的な機密データをメタデータに含めないでください。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.

システムによるアプリのキャプチャを有効または無効にするEnable and disable system app capture

システムによるアプリのキャプチャは、ユーザーによって、組み込みのシステム UI を使用して開始されます。System app capture is initiated by the user with the built-in system UI. ファイルは、Windows ゲーム エコシステムによって取り込まれ、アプリやユーザーが使用することはできません。ただし、Xbox アプリなどのファースト パーティ エクスペリエンスによる場合は例外です。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. アプリでは、システムによって開始されるアプリのキャプチャを無効または有効にすることができ、ユーザーが特定のコンテンツやゲームプレイをキャプチャできないように設定できます。Your app can disable and enable system-initiated app capture, allowing you to prevent the user from capturing certain content or gameplay.

システムによるアプリのキャプチャを有効または無効にするには、静的メソッド AppCapture.SetAllowedAsync を呼び出して、キャプチャを無効にする場合は false を、キャプチャを有効にする場合は true を渡すだけです。To 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);

システムによるアプリのキャプチャが開始および停止したときに通知を受信するReceive notifications when system app capture starts and stops

システムによるアプリのキャプチャが開始または終了されたときに通知を受信するには、最初に、ファクトリ メソッド GetForCurrentView を呼び出すことによって、AppCapture クラスのインスタンスを取得します。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. 次に、CapturingChanged イベントのハンドラーを登録します。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);

CapturingChanged イベントのハンドラーで、IsCapturingAudio プロパティと IsCapturingVideo プロパティを調べて、それぞれオーディオまたはビデオがキャプチャされているかどうかを確認できます。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. 現在のキャプチャの状態を示すために、アプリの UI を更新することが必要になる場合があります。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);
}

UWP 用の Windows デスクトップ拡張機能をアプリに追加するAdd the Windows Desktop Extensions for the UWP to your app

アプリから直接、オーディオとビデオを記録するための API やスクリーンショットをキャプチャするための API は、Windows.Media.AppRecording 名前空間にあり、ユニバーサル API コントラクトには含まれていません。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. この API にアクセスするには、次の手順に従って、UWP 用の Windows デスクトップ拡張機能への参照をアプリに追加する必要があります。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. Visual Studio のソリューション エクスプローラーで、UWP プロジェクトを展開し、[参照] を右クリックして、[参照の追加] を選択します。In Visual Studio, in Solution Explorer, expand your UWP project and right-click References and then select Add Reference....
  2. [ユニバーサル Windows] ノードを展開し、[拡張機能] を選択します。Expand the Universal Windows node and select Extensions.
  3. 拡張機能の一覧で、プロジェクトのターゲット ビルドに一致する [Windows Desktop Extensions for the UWP] エントリの横にあるチェック ボックスをオンにします。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. アプリのブロードキャスト機能を使用するには、バージョンが 1709 以上である必要があります。For the app broadcast features, the version must be 1709 or greater.
  4. [OK] をクリックします。Click OK.

AppRecordingManager のインスタンスを取得するGet an instance of AppRecordingManager

AppRecordingManager クラスは、アプリの記録を管理するために使用する中心的な API です。The AppRecordingManager class is the central API you will use to manage app recording. ファクトリ メソッド GetDefault を呼び出すことによって、このクラスのインスタンスを取得します。Get an instance of this class by calling the factory method GetDefault. Windows.Media.AppRecording名前空間の API のいずれかを使用する前に、現在のデバイスでこれらが存在することを確認する必要があります。Before using any of the APIs in the Windows.Media.AppRecording namespace, you should check for their presence on the current device. この API は、Windows 10 バージョン 1709 より前のバージョンの OS を実行しているデバイスでは利用できません。The APIs are not available on devices running an OS version earlier than Windows 10, version 1709. 特定の OS バージョンを確認するのではなく、ApiInformation.IsApiContractPresent メソッドで、Windows.Media.AppBroadcasting.AppRecordingContract バージョン 1.0 を照会します。Rather than check for a specific OS version, use the ApiInformation.IsApiContractPresent method to query for the Windows.Media.AppBroadcasting.AppRecordingContract version 1.0. このコントラクトが存在する場合は、デバイスで記録 API を利用できます。If this contract is present, then the recording APIs are available on the device. この記事のコード例では、API を 1 回確認し、それ以降の操作の前に、AppRecordingManager が null であるかどうかを確認します。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();
}

アプリが現在記録できるかどうかを確認するDetermine if your app can currently record

現在、アプリでオーディオやビデオをキャプチャできない場合は、いくつかの原因があります。たとえば、現在のデバイスが記録のハードウェア要件を満たしていない場合や、別のアプリが現在ブロードキャストしている場合です。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. 記録を開始する前に、アプリが現在記録できるかどうかを確認できます。Before initiating a recording, you can check to see if your app is currently able to record. AppRecordingManager オブジェクトの GetStatus メソッドを呼び出して、返された AppRecordingStatus オブジェクトの CanRecord プロパティを確認します。Call the GetStatus method of the AppRecordingManager object and then check the CanRecord property of the returned AppRecordingStatus object. 場合CanRecord返しますfalse、アプリが現在記録できないことを意味を確認できます、 詳細 を決定するプロパティ理由です。If CanRecord returns false, meaning that your app can't currently record, you can check the Details property to determine the reason. 理由に応じて、ユーザーに対してステータスを表示したり、アプリの記録を有効にするための手順を示したりすることができます。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;
}

ファイルへのアプリの記録を手動で開始および停止するManually start and stop recording your app to a file

アプリが記録できることを確認した後、AppRecordingManager オブジェクトの StartRecordingToFileAsync メソッドを呼び出すことによって、新しい記録を開始することができます。After verifying that your app is able to record, you can start a new recording by calling the StartRecordingToFileAsync method of the AppRecordingManager object.

次の例で、最初の then ブロックは、非同期タスクが失敗したときに実行されます。In the following example, the first then block executes when the asynchronous task fails. 2 番目の then ブロックは、タスクの結果へのアクセスを試行します。結果が null の場合、タスクは完了しています。The second then block attempts to access the result of the task and, if the result is null, then the task has completed. いずれの場合も、次に示す OnRecordingComplete ヘルパー メソッドが呼び出されて、結果が処理されます。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();
        }
    });
}

記録操作が完了したら、返された AppRecordingResult オブジェクトの Succeeded プロパティを確認して、記録操作が成功したかどうかを判断します。When the recording operation completes, check the Succeeded property of the returned AppRecordingResult object to determine if the record operation was successful. 成功している場合、IsFileTruncated プロパティを確認して、記憶域上の理由から、システムがキャプチャされたファイルを強制的に切り詰めたかどうかを判断できます。If so, you can check the IsFileTruncated property to determine if, for storage reasons, the system was forced to truncate the captured file. Duration プロパティを確認して、記録されたファイルの実際の継続時間を検出できます。ファイルが切り詰められている場合、実際の継続時間は記録操作の継続時間よりも短い場合があります。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;
    }
}

次の例では、前の例で示した記録操作を開始および停止するためのいくつかの基本的なコードを示します。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();
}

履歴の期間をファイルに記録するRecord a historical time span to a file

ユーザーが、システムの設定でアプリの履歴の記録を有効にしている場合、既に経過したゲームプレイの期間を記録できます。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. この記事の前の例では、アプリが現在ゲームプレイを記録できることを確認する方法を示しました。A previous example in this article showed how to confirm that your app can currently record gameplay. 履歴のキャプチャが有効になっているかどうかを判断するには、追加の確認を行います。There is an additional check to determine if historical capture is enabled. もう一度 GetStatus を呼び出して、返された AppRecordingStatus オブジェクトの CanRecordTimeSpan プロパティを確認します。Once again, call GetStatus and check the CanRecordTimeSpan property of the returned AppRecordingStatus object. この例では、AppRecordingStatusHistoricalBufferDuration プロパティも返されます。このプロパティは、記録操作の有効な開始時刻を確認するために使用されます。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;
}

履歴の期間をキャプチャするには、記録の開始時刻と継続時間を指定する必要があります。To capture a historical timespan, you must specify a start time for the recording and a duration. 開始時刻は、DateTime 構造体として提供されます。The start time is provided as a DateTime struct. 開始時刻は、記録バッファーの長さの範囲内で、現在の時刻よりも前の時刻である必要があります。The start time must be a time before the current time, within the length of the historical recording buffer. この例では、バッファーの長さは、前のコード例に示されている、履歴の記録が有効になっているかどうかの確認の一環として取得されます。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. 履歴の記録の継続時間は、TimeSpan 構造体として提供されます。これも、履歴のバッファーの継続時間以下である必要があります。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. 目的の開始時刻と継続時間を確認したら、RecordTimeSpanToFileAsync を呼び出して、記録操作を開始します。Once you have determined your desired start time and duration, call RecordTimeSpanToFileAsync to start the recording operation.

手動で記録を開始および停止する場合と同様に、履歴の記録が完了したときに、返された AppRecordingResult オブジェクトの Succeeded プロパティを確認して、記録操作が成功したかどうかを判断できます。また、IsFileTruncated プロパティと Duration プロパティを確認して、記録されたファイルの実際の継続時間を検出できます。ファイルが切り詰められている場合、実際の継続時間は要求された継続時間よりも短い場合があります。Like 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);
        }
    });

}

次の例では、前の例で示した履歴の記録操作を開始するためのいくつかの基本的なコードを示します。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);
});

スクリーンショットの画像をファイルに保存するSave screenshot images to files

アプリでスクリーンショットのキャプチャを開始できます。アプリのウィンドウの現在の内容を、1 つの画像ファイルに保存することも、異なる画像エンコードで複数の画像ファイルに保存することもできます。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. 使用する画像エンコードを指定するには、それぞれが画像の種類を表す文字列の一覧を作成します。To specify the image encodings you would like to use, create a list of strings where each represents an image type. ImageEncodingSubtypes のプロパティは、サポートされている画像の種類ごとに、適切な文字列 (MediaEncodingSubtypes.PngMediaEncodingSubtypes.JpegXr など) を提供します。The properties of the ImageEncodingSubtypes provide the correct string for each supported image type, such as MediaEncodingSubtypes.Png or MediaEncodingSubtypes.JpegXr.

画面キャプチャを開始するには、AppRecordingManager オブジェクトの SaveScreenshotToFilesAsync メソッドを呼び出します。Initiate screen capture by calling the SaveScreenshotToFilesAsync method of the AppRecordingManager object. このメソッドの最初のパラメーターは、画像ファイルの保存場所を示す StorageFolder です。The first parameter to this method is a StorageFolder where the image files will be saved. 2 番目のパラメーターは、システムが、保存される各画像の種類の拡張子 (".png" など) を追加する、ファイル名のプレフィックスです。The second parameter is a filename prefix to which the system will append the extension for each image type saved, such as ".png".

SaveScreenshotToFilesAsync の 3 番目のパラメーターは、キャプチャされる現在のウィンドウが HDR コンテンツを表示している場合に、システムが適切な色空間変換を実行できるようにするために必要です。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. HDR コンテンツが存在する場合は、このパラメーターを AppRecordingSaveScreenshotOption.HdrContentVisible に設定する必要があります。If HDR content is present, this parameter should be set to AppRecordingSaveScreenshotOption.HdrContentVisible. それ以外の場合は、AppRecordingSaveScreenshotOption.None を使用します。Otherwise, use AppRecordingSaveScreenshotOption.None. このメソッドの最後のパラメーターは、画面をキャプチャするか画像形式の一覧です。The final parameter to the method is the list of image formats to which the screen should be captured.

SaveScreenshotToFilesAsync の非同期呼び出しが完了すると、AppRecordingSavedScreenshotInfo オブジェクトが返されます。このオブジェクトは、StorageFile と、保存された各画像の種類を示す MediaEncodingSubtypes 値を提供します。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);
        }
    });
}

次の例では、前の例で示したスクリーンショットの操作を開始するためのいくつかの基本的なコードを示します。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");

システムやアプリによるキャプチャのゲーム メタデータを追加するAdd game metadata for system and app-initiated capture

この記事の以下のセクションでは、キャプチャまたはブロードキャストされるゲームプレイの MP4 ストリームにシステムが埋め込むメタデータを提供する方法について説明します。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. メタデータは、組み込みのシステム UI を使用してキャプチャされたメディアや、AppRecordingManager を使用してアプリでキャプチャされたメディアに埋め込むことができます。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. このメタデータを、メディアの再生中にアプリや他のアプリで抽出して、キャプチャまたはブロードキャストされたゲームプレイと同期する、コンテキストに対応したエクスペリエンスを提供することができます。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.

AppCaptureMetadataWriter のインスタンスを取得するGet an instance of AppCaptureMetadataWriter

アプリのキャプチャ メタデータを管理するためのプライマリ クラスは、AppCaptureMetadataWriter です。The primary class for managing app capture metadata is AppCaptureMetadataWriter. このクラスのインスタンスを初期化する前に、ApiInformation.IsApiContractPresent メソッドを使用して、Windows.Media.Capture.AppCaptureMetadataContract バージョン 1.0 を照会し、この API が現在のデバイスで利用できることを確認します。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();
}

アプリのシステム キャッシュにメタデータを書き込むWrite metadata to the system cache for your app

各メタデータ項目には 1 つのラベルがあり、メタデータ項目、関連するデータ値 (文字列、整数、または double 型の値)、データ項目の相対的な優先順位を示す AppCaptureMetadataPriority 列挙の値が識別されます。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. メタデータ項目は、ある時点で発生する "イベント" またはある時間枠で値を維持する "状態" と見なすことができます。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. メタデータは、システムによってアプリ用に割り当てられて管理されるメモリ キャッシュに書き込まれます。Metadata is written to a memory cache that is allocated and managed for your app by the system. システムは、メタデータのメモリ キャッシュにサイズ制限を適用し、制限に達すると、各メタデータに書き込まれている優先順位に基づいてデータを削除します。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. この記事の次のセクションでは、アプリのメタデータのメモリ割り当てを管理する方法を示します。The next section of this article shows how to manage your app's metadata memory allocation.

一般的なアプリでは、キャプチャ セッションの最初に特定のメタデータを書き込んで、以降のデータのコンテキストを提供することを選択できます。A typical app may choose to write some metadata at the beginning of the capture session to provide some context for the subsequent data. このシナリオでは、瞬間的な "イベント" データを使用することをお勧めします。For this scenario it is recommended that you use instantaneous "event" data. この例では、 AddStringEventAddDoubleEvent 、および AddInt32Event を呼び出して、各データ型の瞬間的な値を設定します。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);
    }
}

一定時間継続する "状態" データを使用する一般的なシナリオとして、プレイヤーが現在プレイしているゲーム マップの追跡があります。A common scenario for using "state" data that persists over time is to track the game map that the player is currently within. この例では、StartStringState を呼び出して状態の値を設定します。This example calls StartStringState to set the state value.

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

特定の状態が終了したことを記録するには、StopState を呼び出します。Call StopState to record that a particular state has ended.

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

状態は、既存の状態ラベルを持つ新しい値を設定して上書きできます。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);
}

StopAllStates を呼び出すことによって、現在開いているすべての状態を終了できます。You can end all currently open states by calling StopAllStates.

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

メタデータ キャッシュの記憶域の制限を管理するManage metadata cache storage limit

AppCaptureMetadataWriter を使用して書き込むメタデータは、関連付けられているメディア ストリームに書き込まれるまで、システムによってキャッシュされます。The metadata that you write with AppCaptureMetadataWriter is cached by the system until it is written to the associated media stream. システムでは、各アプリのメタデータ キャッシュのサイズ制限を定義しています。The system defines a size limit for each app's metadata cache. キャッシュのサイズ制限に達すると、システムはキャッシュされたメタデータの削除を開始します。Once the cache size limit has been reached, the system will begin purging cached metadata. 記述されたメタデータが削除 AppCaptureMetadataPriority.Informational 優先度の値を使用してメタデータを削除する前に、 AppCaptureMetadataPriority.Important 優先順位。The system will delete metadata that was written with AppCaptureMetadataPriority.Informational priority value before deleting metadata with the AppCaptureMetadataPriority.Important priority.

いつでも、RemainingStorageBytesAvailable を呼び出すことによって、アプリのメタデータ キャッシュで利用可能なバイト数を確認できます。At any point, you can check to see the number of bytes available in your app's metadata cache by calling RemainingStorageBytesAvailable. 独自のアプリで定義されたしきい値を設定することを選択し、その後でキャッシュに書き込むメタデータの量を減らすことを選択できます。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. 次の例は、このパターンの簡単な実装を示しています。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);
    }
}

システムがメタデータを削除するときに通知を受け取るReceive notifications when the system purges metadata

ハンドラーを登録することによって、アプリのメタデータを削除、システムの開始時に通知を受信登録することができます、 MetadataPurged イベント。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);

}

MetadataPurged イベントのハンドラーで、優先順位の低い状態を終了してメタデータ キャッシュの空き容量を増やすことも、キャッシュに書き込むメタデータの量を削減するためにアプリで定義されたロジックを実装することも、何もせずに書き込み時の優先順位に基づいてシステムによるキャッシュの削除を継続することもできます。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."));

}