Menangkap audio game, video, tangkapan layar, dan metadata

Artikel ini menjelaskan cara menangkap video game, audio, dan tangkapan layar, dan cara mengirimkan metadata yang akan disematkan sistem di media yang ditangkap dan disiarkan, memungkinkan aplikasi Anda dan lainnya untuk menciptakan pengalaman dinamis yang disinkronkan dengan acara gameplay.

Ada dua cara berbeda agar gameplay dapat ditangkap di aplikasi UWP. Pengguna dapat memulai pengambilan menggunakan UI sistem bawaan. Media yang ditangkap menggunakan teknik ini dicerna ke dalam ekosistem game Microsoft, dapat dilihat dan dibagikan melalui pengalaman pihak pertama seperti aplikasi Xbox, dan tidak secara langsung tersedia untuk aplikasi Anda atau pengguna. Bagian pertama dari artikel ini akan menunjukkan kepada Anda cara mengaktifkan dan menonaktifkan pengambilan aplikasi yang diterapkan sistem dan cara menerima pemberitahuan saat pengambilan aplikasi dimulai atau dihentikan.

Cara lain untuk menangkap media adalah dengan menggunakan API Windows. Media.AppRecording namespace. Jika pengambilan diaktifkan pada perangkat, aplikasi Anda dapat mulai menangkap gameplay dan kemudian, setelah beberapa waktu berlalu, Anda dapat menghentikan pengambilan, di mana titik media ditulis ke file. Jika pengguna telah mengaktifkan pengambilan historis, maka Anda juga dapat merekam gameplay yang telah terjadi dengan menentukan waktu mulai di masa lalu dan durasi untuk merekam. Kedua teknik ini menghasilkan file video yang dapat diakses oleh aplikasi Anda, dan tergantung di mana Anda memilih untuk menyimpan file, oleh pengguna. Bagian tengah artikel ini memandu Anda melalui implemenasi skenario ini.

Windows. Media.Capture namespace menyediakan API untuk membuat metadata yang menggambarkan gameplay yang ditangkap atau disiarkan. Ini dapat mencakup nilai teks atau numerik, dengan label teks yang mengidentifikasi setiap item data. Metadata dapat mewakili "peristiwa" yang terjadi pada satu saat, seperti ketika pengguna menyelesaikan putaran dalam permainan balap, atau dapat mewakili "keadaan" yang bertahan selama rentang waktu, seperti peta permainan saat ini yang dimainkan pengguna. Metadata ditulis ke cache yang dialokasikan dan dikelola untuk aplikasi Anda oleh sistem. Metadata disematkan ke dalam aliran siaran dan file video yang diambil, termasuk teknik pengambilan sistem bawaan atau pengambilan aplikasi khusus. Bagian terakhir dari artikel ini menunjukkan cara menulis metadata gameplay.

Catatan

Karena metadata gameplay dapat disematkan dalam file media yang berpotensi dibagikan melalui jaringan, di luar kendali pengguna, Anda tidak boleh menyertakan informasi yang dapat diidentifikasi secara pribadi atau data sensitif lainnya dalam metadata.

Mengaktifkan dan menonaktifkan pengambilan aplikasi sistem

Pengambilan aplikasi sistem dimulai oleh pengguna dengan UI sistem bawaan. File dicerna oleh ekosistem game Windows dan tidak tersedia untuk aplikasi Anda atau pengguna, kecuali melalui pengalaman pihak pertama seperti aplikasi Xbox. Aplikasi Anda dapat menonaktifkan dan mengaktifkan pengambilan aplikasi yang dimulai sistem, memungkinkan Anda mencegah pengguna menangkap konten atau gameplay tertentu.

Untuk mengaktifkan atau menonaktifkan pengambilan aplikasi sistem, cukup panggil metode statis AppCapture.SetAllowedAsync dan meneruskan false untuk menonaktifkan capture atau true untuk mengaktifkan capture.

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

Menerima notifikasi saat pengambilan dan penghentian aplikasi sistem dimulai

Untuk menerima pemberitahuan saat pengambilan aplikasi sistem dimulai atau diakhiri, pertama-tama dapatkan contoh kelas AppCapture dengan memanggil metode pabrik GetForCurrentView. Selanjutnya, daftarkan penangan untuk peristiwa CapturingChanged .

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

Di penangan untuk peristiwa CapturingChanged , Anda dapat memeriksa properti IsCapturingAudio dan IsCapturingVideo untuk menentukan apakah audio atau video ditangkap masing-masing. Anda mungkin ingin memperbarui UI aplikasi anda untuk menunjukkan status pengambilan saat ini.

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);
}

Menambahkan Ekstensi Desktop Windows untuk UWP ke aplikasi Anda

API untuk merekam audio dan video dan untuk menangkap tangkapan layar langsung dari aplikasi Anda, ditemukan di Windows. Media.AppRecording namespace, tidak termasuk dalam kontrak UNIVERSAL API. Untuk mengakses API, Anda harus menambahkan referensi ke Ekstensi Desktop Windows untuk UWP ke aplikasi Anda dengan langkah-langkah berikut.

  1. Di Visual Studio, di Penjelajah Solusi, perluas proyek UWP Anda dan klik kanan Referensi lalu pilih Tambahkan Referensi....
  2. Perluas simpul universal Windows dan pilih Ekstensi.
  3. Dalam daftar ekstensi, centang kotak centang di samping Ekstensi Desktop Windows untuk entri UWP yang cocok dengan build target untuk proyek Anda. Untuk fitur siaran aplikasi, versi harus 1709 atau lebih besar.
  4. Klik OK.

Dapatkan instance AppRecordingManager

Kelas AppRecordingManager adalah API pusat yang akan Anda gunakan untuk mengelola perekaman aplikasi. Dapatkan contoh kelas ini dengan memanggil metode pabrik GetDefault. Sebelum menggunakan salah satu API di Windows. Media.AppRecording namespace, Anda harus memeriksa keberadaannya di perangkat saat ini. API tidak tersedia pada perangkat yang menjalankan versi OS lebih awal dari Windows 10, versi 1709. Daripada memeriksa versi OS tertentu, gunakan metode ApiInformation.IsApiContractPresent untuk meminta Windows. Media.AppBroadcasting.AppRecordingContract versi 1.0. Jika kontrak ini ada, maka API perekaman tersedia di perangkat. Kode contoh dalam artikel ini memeriksa API sekali dan kemudian memeriksa apakah AppRecordingManager null sebelum operasi berikutnya.

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

Menentukan apakah aplikasi Anda saat ini dapat merekam

Ada beberapa alasan mengapa aplikasi Anda saat ini tidak dapat menangkap audio atau video, termasuk jika perangkat saat ini tidak memenuhi persyaratan perangkat keras untuk merekam atau jika aplikasi lain saat ini sedang menyiarkan. Sebelum memulai rekaman, Anda dapat memeriksa untuk melihat apakah aplikasi Anda saat ini dapat merekam. Panggil metode GetStatus dari objek AppRecordingManager dan kemudian periksa properti CanRecord dari objek AppRecordingStatus yang dikembalikan. Jika CanRecord mengembalikan false, artinya aplikasi Anda saat ini tidak dapat merekam, Anda dapat memeriksa properti Detail untuk menentukan alasannya. Tergantung pada alasannya, Anda mungkin ingin menampilkan status kepada pengguna atau menampilkan instruksi untuk mengaktifkan perekaman aplikasi.

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;
}

Memulai dan berhenti merekam aplikasi anda secara manual ke file

Setelah memverifikasi bahwa aplikasi Anda dapat merekam, Anda dapat memulai rekaman baru dengan memanggil metode StartRecordingToFileAsync dari objek AppRecordingManager .

Dalam contoh berikut, yang pertama kemudian memblokir eksekusi ketika tugas asinkron gagal. Yang kedua kemudian memblokir upaya untuk mengakses hasil tugas dan, jika hasilnya null, maka tugas telah selesai. Dalam kedua kasus, metode pembantu OnRecordingComplete , yang ditunjukkan di bawah ini, dipanggil untuk menangani hasilnya.

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();
        }
    });
}

Saat operasi perekaman selesai, periksa properti berhasil dari objek AppRecordingResult yang dikembalikan untuk menentukan apakah operasi rekaman berhasil. Jika demikian, Anda dapat memeriksa properti IsFileTruncated untuk menentukan apakah, untuk alasan penyimpanan, sistem dipaksa untuk memotong file yang diambil. Anda dapat memeriksa properti Durasi untuk menemukan durasi sebenarnya dari file yang direkam yang, jika file terpotong, mungkin lebih pendek dari durasi operasi perekaman.

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;
    }
}

Contoh berikut menunjukkan beberapa kode dasar untuk memulai dan menghentikan operasi perekaman yang ditunjukkan pada contoh sebelumnya.

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();
}

Merekam rentang waktu historis ke file

Jika pengguna telah mengaktifkan perekaman historis untuk aplikasi Anda di pengaturan sistem, Anda dapat merekam rentang waktu gameplay yang sebelumnya telah terjadi. Contoh sebelumnya dalam artikel ini menunjukkan cara mengonfirmasi bahwa aplikasi Anda saat ini dapat merekam gameplay. Ada pemeriksaan tambahan untuk menentukan apakah penangkapan historis diaktifkan. Sekali lagi, hubungi GetStatus dan periksa properti CanRecordTimeSpan dari objek AppRecordingStatus yang dikembalikan. Contoh ini juga mengembalikan properti HistoricalBufferDuration dari AppRecordingStatus yang akan digunakan untuk menentukan waktu mulai yang valid untuk operasi perekaman.

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;
}

Untuk menangkap rentang waktu historis, Anda harus menentukan waktu mulai untuk rekaman dan durasi. Waktu mulai disediakan sebagai struct DateTime . Waktu mulai harus waktu sebelum waktu saat ini, dalam panjang buffer rekaman historis. Untuk contoh ini, panjang buffer diambil sebagai bagian dari pemeriksaan untuk melihat apakah rekaman historis diaktifkan, yang ditunjukkan dalam contoh kode sebelumnya. Durasi rekaman historis disediakan sebagai penataan TimeSpan , yang juga harus sama dengan atau lebih kecil dari durasi buffer historis. Setelah Anda menentukan waktu dan durasi mulai yang Anda inginkan, hubungi RecordTimeSpanToFileAsync untuk memulai operasi perekaman.

Seperti merekam dengan awal dan henti manual, ketika rekaman historis selesai, Anda dapat memeriksa properti Berhasil dari objek AppRecordingResult yang dikembalikan untuk menentukan apakah operasi rekaman berhasil, dan Anda dapat memeriksa properti IsFileTruncated dan Durasi untuk menemukan durasi sebenarnya dari file yang direkam yang, jika file terpotong, mungkin lebih pendek dari durasi jendela waktu yang diminta.

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);
        }
    });

}

Contoh berikut menunjukkan beberapa kode dasar untuk memulai operasi catatan historis yang ditunjukkan pada contoh sebelumnya.

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

Menyimpan gambar tangkapan layar ke file

Aplikasi Anda dapat memulai tangkapan layar yang akan menyimpan konten saat ini dari jendela aplikasi ke satu file gambar atau ke beberapa file gambar dengan pengkodean gambar yang berbeda. Untuk menentukan pengkodean gambar yang ingin Anda gunakan, buat daftar string di mana masing-masing mewakili tipe gambar. Properti ImageEncodingSubtypes menyediakan string yang benar untuk setiap jenis gambar yang didukung, seperti MediaEncodingSubtypes.Png atau MediaEncodingSubtypes.JpegXr.

Mulai tangkapan layar dengan memanggil metode SaveScreenshotToFilesAsync dari objek AppRecordingManager . Parameter pertama untuk metode ini adalah StorageFolder di mana file gambar akan disimpan. Parameter kedua adalah awalan nama file di mana sistem akan menambahkan ekstensi untuk setiap jenis gambar yang disimpan, seperti ".png".

Parameter ketiga untuk SaveScreenshotToFilesAsync diperlukan agar sistem dapat melakukan konversi colorspace yang tepat jika jendela saat ini yang akan ditangkap menampilkan konten HDR. Jika konten HDR ada, parameter ini harus diatur ke AppRecordingSaveScreenshotOption.HdrContentVisible. Jika tidak, gunakan AppRecordingSaveScreenshotOption.None. Parameter terakhir untuk metode ini adalah daftar format gambar di mana layar harus ditangkap.

Ketika panggilan asinkron ke SaveScreenshotToFilesAsync selesai, ia mengembalikan objek AppRecordingSavedScreenshotInfo yang menyediakan nilai StorageFile dan MediaEncodingSubtypes terkait yang menunjukkan jenis gambar untuk setiap gambar yang disimpan.

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);
        }
    });
}

Contoh berikut menunjukkan beberapa kode dasar untuk memulai operasi tangkapan layar yang ditunjukkan pada contoh sebelumnya.

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

Menambahkan metadata game untuk pengambilan yang dimulai sistem dan aplikasi

Bagian berikut dari artikel ini menjelaskan cara memberikan metadata yang akan disematkan sistem ke dalam aliran MP4 dari gameplay yang ditangkap atau disiarkan. Metadata dapat disematkan di media yang ditangkap menggunakan UI sistem bawaan dan media yang ditangkap oleh aplikasi dengan AppRecordingManager. Metadata ini dapat diekstraksi oleh aplikasi Anda dan aplikasi lain selama pemutaran media untuk memberikan pengalaman kontekstual yang disinkronkan dengan gameplay yang ditangkap atau disiarkan.

Dapatkan contoh AppCaptureMetadataWriter

Kelas utama untuk mengelola metadata pengambilan aplikasi adalah AppCaptureMetadataWriter. Sebelum menginsialisasi instans kelas ini, gunakan metode ApiInformation.IsApiContractPresent untuk meminta Windows. Media.Capture.AppCaptureMetadataContract versi 1.0 untuk memverifikasi bahwa API tersedia di perangkat saat ini.

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

Menulis metadata ke cache sistem untuk aplikasi Anda

Setiap item metadata memiliki label string, mengidentifikasi item metadata, nilai data terkait yang dapat berupa string, bilangan bulat, atau nilai ganda, dan nilai dari pencacahan AppCaptureMetadataPriority yang menunjukkan prioritas relatif dari item data. Item metadata dapat dianggap sebagai "peristiwa", yang terjadi pada satu titik waktu, atau "status" yang mempertahankan nilai selama jendela waktu. Metadata ditulis ke cache memori yang dialokasikan dan dikelola untuk aplikasi Anda oleh sistem. Sistem memberlakukan batas ukuran pada cache memori metadata dan, ketika batas tercapai, akan membersihkan data berdasarkan prioritas yang dengannya setiap item metadata ditulis. Bagian selanjutnya dari artikel ini menunjukkan cara mengelola alokasi memori metadata aplikasi Anda.

Aplikasi biasa dapat memilih untuk menulis beberapa metadata di awal sesi pengambilan untuk memberikan beberapa konteks untuk data berikutnya. Untuk skenario ini disarankan agar Anda menggunakan data "peristiwa" instan. Contoh ini memanggil AddStringEvent, AddDoubleEvent, dan AddInt32Event untuk mengatur nilai instan untuk setiap tipe data.

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);
    }
}

Skenario umum untuk menggunakan data "status" yang bertahan dari waktu ke waktu adalah melacak peta permainan yang saat ini berada di dalam pemain. Contoh ini memanggil StartStringState untuk mengatur nilai status.

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

Panggil StopState untuk mencatat bahwa negara tertentu telah berakhir.

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

Anda dapat menimpa status dengan menetapkan nilai baru dengan label status yang ada.

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

Anda dapat mengakhiri semua status yang saat ini terbuka dengan memanggil StopAllStates.

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

Mengelola batas penyimpanan cache metadata

Metadata yang Anda tulis dengan AppCaptureMetadataWriter di-cache oleh sistem sampai ditulis ke aliran media terkait. Sistem menentukan batas ukuran untuk cache metadata setiap aplikasi. Setelah batas ukuran cache tercapai, sistem akan mulai membersihkan metadata yang di-cache. Sistem akan menghapus metadata yang ditulis dengan nilai prioritas AppCaptureMetadataPriority.Informational sebelum menghapus metadata dengan prioritas AppCaptureMetadataPriority.Important .

Kapan saja, Anda dapat memeriksa untuk melihat jumlah byte yang tersedia di cache metadata aplikasi Anda dengan memanggil RemainingStorageBytesAvailable. Anda dapat memilih untuk menetapkan ambang batas yang ditentukan aplikasi Anda sendiri setelah itu Anda dapat memilih untuk mengurangi jumlah metadata yang Anda tulis ke cache. Contoh berikut menunjukkan implementasi sederhana dari pola ini.

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);
    }
}

Menerima notifikasi saat sistem membersihkan metadata

Anda dapat mendaftar untuk menerima pemberitahuan ketika sistem mulai membersihkan metadata untuk aplikasi Anda dengan mendaftarkan penangan untuk acara MetadataPurged .

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

}

Dalam penangan untuk acara MetadataPurged , Anda dapat menjernihkan beberapa ruang di cache metadata dengan mengakhiri status prioritas rendah, Anda dapat menerapkan logika yang ditentukan aplikasi untuk mengurangi jumlah metadata yang Anda tulis ke cache, atau Anda tidak dapat melakukan apa-apa dan membiarkan sistem terus membersihkan cache berdasarkan prioritas yang ditulisnya.

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."));

}