Mengambil audio game, video, cuplikan layar, dan metadata

Artikel ini menjelaskan cara mengambil video game, audio, dan cuplikan layar, dan cara mengirimkan metadata yang akan disematkan sistem di media yang ditangkap dan disiarkan, memungkinkan aplikasi Anda dan orang lain untuk menciptakan pengalaman dinamis yang disinkronkan ke peristiwa 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 diserap 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 kepada 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 mengambil media adalah dengan menggunakan API namespace Windows.Media.AppRecording . Jika penangkapan diaktifkan di perangkat, aplikasi Anda dapat mulai menangkap gameplay dan kemudian, setelah beberapa waktu berlalu, Anda dapat menghentikan pengambilan, di mana 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 memandang Anda melalui implemenasi skenario ini.

Namespace Windows.Media.Capture menyediakan API untuk membuat metadata yang menjelaskan gameplay yang diambil atau disiarkan. Ini dapat mencakup teks atau nilai 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 "status" 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 tangkapan sistem bawaan atau teknik penangkapan aplikasi kustom. Bagian akhir artikel ini menunjukkan kepada Anda 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 identitas pribadi atau data lain yang berpotensi sensitif dalam metadata.

Mengaktifkan dan menonaktifkan pengambilan aplikasi sistem

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

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

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

Menerima pemberitahuan saat pengambilan aplikasi sistem dimulai dan berhenti

Untuk menerima pemberitahuan saat pengambilan aplikasi sistem dimulai atau berakhir, pertama-tama dapatkan instans kelas AppCapture dengan memanggil metode pabrik GetForCurrentView. Selanjutnya, daftarkan handler 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 handler untuk peristiwa CapturingChanged , Anda dapat memeriksa properti IsCapturingAudio dan IsCapturingVideo untuk menentukan apakah audio atau video masing-masing diambil. Anda mungkin ingin memperbarui UI aplikasi untuk menunjukkan status penangkapan 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 cuplikan layar langsung dari aplikasi Anda, yang ditemukan di namespace Windows.Media.AppRecording , tidak disertakan 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 di samping Ekstensi Desktop Windows untuk entri UWP yang cocok dengan build target untuk proyek Anda. Untuk fitur siaran aplikasi, versinya harus 1709 atau lebih tinggi.
  4. Klik OK.

Mendapatkan instans AppRecordingManager

Kelas AppRecordingManager adalah API pusat yang akan Anda gunakan untuk mengelola perekaman aplikasi. Dapatkan instans kelas ini dengan memanggil metode pabrik GetDefault. Sebelum menggunakan salah satu API di namespace Windows.Media.AppRecording , Anda harus memeriksa keberadaannya di perangkat saat ini. API tidak tersedia di perangkat yang menjalankan versi OS yang lebih lama dari Windows 10, versi 1709. Daripada memeriksa versi OS tertentu, gunakan metode ApiInformation.IsApiContractPresent untuk mengkueri Windows.Media.AppBroadcasting.AppRecordingContract versi 1.0. Jika kontrak ini ada, MAKA API perekaman tersedia di perangkat. Contoh kode dalam artikel ini memeriksa API sekali lalu 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 aplikasi Anda mungkin saat ini tidak dapat mengambil audio atau video, termasuk jika perangkat saat ini tidak memenuhi persyaratan perangkat keras untuk merekam atau jika aplikasi lain saat ini sedang disiarkan. Sebelum memulai perekaman, Anda dapat memeriksa untuk melihat apakah aplikasi Anda saat ini dapat merekam. Panggil metode GetStatus objek AppRecordingManager lalu periksa properti CanRecord dari objek AppRecordingStatus yang dikembalikan. Jika CanRecord mengembalikan false, yang berarti bahwa aplikasi Anda saat ini tidak dapat merekam, Anda dapat memeriksa properti Detail untuk menentukan alasannya. Bergantung 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, blok pertama kemudian dijalankan 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();
        }
    });
}

Ketika 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, karena 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 dipotong, 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 diperlihatkan dalam 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 rekaman historis untuk aplikasi Anda di pengaturan sistem, Anda dapat merekam rentang waktu gameplay yang sebelumnya telah ditranspirasi. Contoh sebelumnya dalam artikel ini menunjukkan cara mengonfirmasi bahwa aplikasi Anda saat ini dapat merekam gameplay. Ada pemeriksaan tambahan untuk menentukan apakah tangkapan historis diaktifkan. Sekali lagi, panggil 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 mengambil 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 ditampilkan dalam contoh kode sebelumnya. Durasi rekaman historis disediakan sebagai struct TimeSpan , yang juga harus sama dengan atau lebih kecil dari durasi buffer historis. Setelah Anda menentukan waktu dan durasi mulai yang diinginkan, panggil RecordTimeSpanToFileAsync untuk memulai operasi perekaman.

Seperti perekaman dengan mulai dan hentikan 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 Duration 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 rekaman historis yang diperlihatkan dalam 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 cuplikan layar ke file

Aplikasi Anda dapat memulai pengambilan cuplikan layar yang akan menyimpan konten jendela aplikasi saat ini ke satu file gambar atau ke beberapa file gambar dengan pengodean gambar yang berbeda. Untuk menentukan pengodean gambar yang ingin Anda gunakan, buat daftar string di mana masing-masing mewakili jenis 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 tempat file gambar akan disimpan. Parameter kedua adalah awalan nama file tempat 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 diambil menampilkan konten HDR. Jika konten HDR ada, parameter ini harus diatur ke AppRecordingSaveScreenshotOption.HdrContentVisible. Jika tidak, gunakan AppRecordingSaveScreenshotOption.None. Parameter akhir untuk metode ini adalah daftar format gambar tempat layar harus diambil.

Ketika panggilan asinkron ke SaveScreenshotToFilesAsync selesai, ia mengembalikan objek AppRecordingSavedScreenshotInfo yang menyediakan StorageFile dan nilai 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 cuplikan layar yang diperlihatkan dalam 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 menyediakan 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 diekstrak oleh aplikasi Anda dan aplikasi lain selama pemutaran media untuk memberikan pengalaman sadar kontekstual yang disinkronkan dengan gameplay yang diambil atau disiarkan.

Mendapatkan instans AppCaptureMetadataWriter

Kelas utama untuk mengelola metadata pengambilan aplikasi adalah AppCaptureMetadataWriter. Sebelum menginisialisasi instans kelas ini, gunakan metode ApiInformation.IsApiContractPresent untuk mengkueri 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 enumerasi AppCaptureMetadataPriority yang menunjukkan prioritas relatif 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 menghapus menyeluruh data berdasarkan prioritas yang ditulis setiap item metadata. Bagian berikutnya dari artikel ini menunjukkan cara mengelola alokasi memori metadata aplikasi Anda.

Aplikasi umum 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" seketika. Contoh ini memanggil AddStringEvent, AddDoubleEvent, dan AddInt32Event untuk mengatur nilai seketika untuk setiap jenis 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 merekam bahwa status tertentu telah berakhir.

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

Anda dapat menimpa status dengan mengatur nilai baru dengan label status yang sudah 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 hingga ditulis ke aliran media terkait. Sistem menentukan batas ukuran untuk cache metadata setiap aplikasi. Setelah batas ukuran cache tercapai, sistem akan mulai membersihkan metadata 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 mengatur 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 pemberitahuan saat sistem menghapus metadata

Anda dapat mendaftar untuk menerima pemberitahuan saat sistem mulai menghapus metadata untuk aplikasi Anda dengan mendaftarkan handler untuk peristiwa MetadataPurged .

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

}

Dalam handler untuk peristiwa MetadataPurged , Anda dapat membersihkan beberapa ruang di cache metadata dengan mengakhiri status berprioritas lebih rendah, Anda dapat menerapkan logika yang ditentukan aplikasi untuk mengurangi jumlah metadata yang Anda tulis ke cache, atau Anda tidak dapat melakukan apa pun 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."));

}