Capturar audio para juegos, vídeo, capturas de pantalla y metadatos
En este artículo se describe cómo capturar vídeo de juego, audio y capturas de pantalla, y cómo enviar metadatos que el sistema insertará en medios capturados y de difusión, lo que permite a la aplicación y a otros crear experiencias dinámicas que se sincronizan con eventos de juego.
Hay dos maneras diferentes de capturar el juego en una aplicación para UWP. El usuario puede iniciar la captura mediante la interfaz de usuario del sistema integrada. Los medios que se capturan con esta técnica se ingieren en el ecosistema de juegos de Microsoft, se pueden ver y compartir a través de experiencias de primera entidad, como la aplicación Xbox, y no está directamente disponible para la aplicación o para los usuarios. En las primeras secciones de este artículo se muestra cómo habilitar y deshabilitar la captura de aplicaciones implementadas por el sistema y cómo recibir notificaciones cuando se inicia o detiene la captura de aplicaciones.
La otra manera de capturar medios es usar las API del espacio de nombres Windows.Media.AppRecording. Si la captura está habilitada en el dispositivo, la aplicación puede empezar a capturar el juego y, después de pasar algún tiempo, puedes detener la captura, en cuyo momento el medio se escribe en un archivo. Si el usuario ha habilitado la captura histórica, también puedes grabar el juego que ya se ha producido especificando una hora de inicio en el pasado y una duración para grabar. Ambas técnicas generan un archivo de vídeo al que puede acceder la aplicación y, en función de dónde elija guardar los archivos, por parte del usuario. Las secciones centrales de este artículo le guiarán por la implementación de estos escenarios.
El espacio de nombres Windows.Media.Capture proporciona API para crear metadatos que describen el juego que se captura o se transmite. Esto puede incluir valores numéricos o de texto, con una etiqueta de texto que identifica cada elemento de datos. Los metadatos pueden representar un "evento" que se produce en un solo momento, como cuando el usuario termina una vuelta en un juego de carreras, o puede representar un "estado" que persiste durante un intervalo de tiempo, como el mapa de juego actual en el que el usuario está jugando. Los metadatos se escriben en una memoria caché asignada y administrada para la aplicación por el sistema. Los metadatos se insertan en secuencias de difusión y archivos de vídeo capturados, incluidas las técnicas integradas de captura del sistema o captura de aplicaciones personalizadas. En las secciones finales de este artículo se muestra cómo escribir metadatos de juego.
Nota:
Dado que los metadatos del juego se pueden incrustar en archivos multimedia que pueden compartirse a través de la red, fuera del control del usuario, no debe incluir información de identificación personal u otros datos potencialmente confidenciales en los metadatos.
Habilitación y deshabilitación de la captura de aplicaciones del sistema
El usuario inicia la captura de aplicaciones del sistema con la interfaz de usuario del sistema integrada. Los archivos se ingieren en el ecosistema de juegos de Windows y no están disponibles para la aplicación o el usuario, excepto en experiencias de primera entidad como el aplicación Xbox. La aplicación puede deshabilitar y habilitar la captura de aplicaciones iniciada por el sistema, lo que te permite impedir que el usuario capture cierto contenido o juego.
Para habilitar o deshabilitar la captura de aplicaciones del sistema, simplemente llame al método estático AppCapture.SetAllowedAsync y pase false para deshabilitar la captura o true para habilitar la captura.
Windows::Media::Capture::AppCapture::SetAllowedAsync(allowed);
Recibir notificaciones cuando se inicia y detiene la captura de aplicaciones del sistema
Para recibir una notificación cuando la captura de la aplicación del sistema comienza o finaliza, primero obtenga una instancia de la clase AppCapture llamando al método factory GetForCurrentView. A continuación, registre un controlador para el evento CaptureingChanged.
Windows::Media::Capture::AppCapture^ appCapture = Windows::Media::Capture::AppCapture::GetForCurrentView();
appCapture->CapturingChanged +=
ref new TypedEventHandler<Windows::Media::Capture::AppCapture^, Platform::Object^>(this, &App::OnCapturingChanged);
En el controlador del evento CaptureingChanged, puede comprobar las propiedades IsCapturingAudio y IsCapturingVideo para determinar si se capturan audio o vídeo respectivamente. Es posible que quiera actualizar la interfaz de usuario de la aplicación para indicar el estado de captura actual.
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);
}
Agregar las extensiones de escritorio de Windows para UWP a la aplicación
Las API para grabar audio y vídeo y para capturar capturas de pantalla directamente desde la aplicación, que se encuentran en el espacio de nombres Windows.Media.AppRecording , no se incluyen en el contrato de API universal. Para acceder a las API, debes agregar una referencia a las extensiones de escritorio de Windows para UWP a la aplicación con los pasos siguientes.
- En Visual Studio, en Explorador de soluciones, expanda el proyecto de UWP y haga clic con el botón derecho en Referencias y, a continuación, seleccione Agregar referencia....
- Expanda el nodo Universal Windows y seleccione Extensiones.
- En la lista de extensiones, active la casilla situada junto a las Extensiones de escritorio de Windows para la entrada de UWP que coincida con la compilación de destino del proyecto. Para las características de difusión de la aplicación, la versión debe ser 1709 o superior.
- Haga clic en OK.
Obtener una instancia de AppRecordingManager
La clase AppRecordingManager es la API central que usará para administrar la grabación de aplicaciones. Obtenga una instancia de esta clase llamando al método de fábrica GetDefault. Antes de usar cualquiera de las API en el espacio de nombres Windows.Media.AppRecording , debe comprobar su presencia en el dispositivo actual. Las API no están disponibles en los dispositivos que ejecutan una versión del sistema operativo anterior a Windows 10, versión 1709. En lugar de comprobar si hay una versión específica del sistema operativo, use el método ApiInformation.IsApiContractPresent para consultar la versión 1.0 de Windows.Media.AppBroadcasting.AppRecordingContract. Si este contrato está presente, las API de grabación están disponibles en el dispositivo. El código de ejemplo de este artículo comprueba las API una vez y, a continuación, comprueba si AppRecordingManager es null antes de las operaciones posteriores.
if (Windows::Foundation::Metadata::ApiInformation::IsApiContractPresent(
"Windows.Media.AppRecording.AppRecordingContract", 1, 0))
{
m_appRecordingManager = AppRecordingManager::GetDefault();
}
Determinar si la aplicación puede registrar actualmente
Hay varias razones por las que es posible que la aplicación no pueda capturar audio o vídeo actualmente, incluido si el dispositivo actual no cumple los requisitos de hardware para la grabación o si otra aplicación está transmitiendo actualmente. Antes de iniciar una grabación, puedes comprobar si la aplicación puede grabar actualmente. Llame al método GetStatus del objeto AppRecordingManager y, a continuación, compruebe la propiedad CanRecord del objeto AppRecordingStatus devuelto. Si CanRecord devuelve false, lo que significa que la aplicación no puede registrar actualmente, puedes comprobar la propiedad Details para determinar el motivo. Según el motivo, es posible que desee mostrar el estado al usuario o mostrar instrucciones para habilitar la grabación de la aplicación.
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;
}
Iniciar y detener manualmente la grabación de la aplicación en un archivo
Después de comprobar que la aplicación puede grabar, puedes iniciar una nueva grabación llamando al método StartRecordingToFileAsync del objeto AppRecordingManager.
En el ejemplo siguiente, el primer bloque se ejecuta cuando se produce un error en la tarea asincrónica. El segundo bloque intenta acceder al resultado de la tarea y, si el resultado es null, la tarea se ha completado. En ambos casos, se llama al método auxiliar OnRecordingComplete , que se muestra a continuación, para controlar el resultado.
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();
}
});
}
Cuando se complete la operación de grabación, compruebe la propiedad Succeeded del objeto AppRecordingResult devuelto para determinar si la operación de registro se realizó correctamente. Si es así, puede comprobar la propiedad IsFileTruncated para determinar si, por motivos de almacenamiento, el sistema se vio obligado a truncar el archivo capturado. Puede comprobar la propiedad Duration para detectar la duración real del archivo grabado que, si el archivo está truncado, puede ser menor que la duración de la operación de grabación.
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;
}
}
En los ejemplos siguientes se muestra código básico para iniciar y detener la operación de grabación que se muestra en el ejemplo anterior.
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();
}
Registrar un intervalo de tiempo histórico en un archivo
Si el usuario ha habilitado la grabación histórica de la aplicación en la configuración del sistema, puedes grabar un intervalo de tiempo de juego que haya transcurrido anteriormente. En un ejemplo anterior de este artículo se muestra cómo confirmar que la aplicación puede grabar el juego actualmente. Hay una comprobación adicional para determinar si la captura histórica está habilitada. Una vez más, llame a GetStatus y compruebe la propiedad CanRecordTimeSpan del objeto AppRecordingStatus devuelto. En este ejemplo también se devuelve la propiedad HistoricalBufferDuration de AppRecordingStatus que se usará para determinar una hora de inicio válida para la operación de grabación.
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;
}
Para capturar un intervalo de tiempo histórico, debe especificar una hora de inicio para la grabación y una duración. La hora de inicio se proporciona como una estructura DateTime . La hora de inicio debe ser una hora antes de la hora actual, dentro del período del búfer de grabación histórico. En este ejemplo, la longitud del búfer se recupera como parte de la comprobación para ver si la grabación histórica está habilitada, que se muestra en el ejemplo de código anterior. La duración de la grabación histórica se proporciona como estructura TimeSpan , que también debe ser igual o menor que la duración del búfer histórico. Una vez que haya determinado la hora de inicio y la duración deseadas, llame a RecordTimeSpanToFileAsync para iniciar la operación de grabación.
Al igual que la grabación con inicio y detención manual, cuando se completa una grabación histórica, puede comprobar la propiedad Succeeded del objeto AppRecordingResult devuelto para determinar si la operación de registro se realizó correctamente y puede comprobar la propiedad IsFileTruncated y Duration para detectar la duración real del archivo grabado que, si el archivo está truncado, puede ser menor que la duración de la hora solicitada. ventana.
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);
}
});
}
En el ejemplo siguiente se muestra código básico para iniciar la operación de registro histórico que se muestra en el ejemplo anterior.
StorageFolder^ storageFolder = ApplicationData::Current->LocalFolder;
concurrency::create_task(storageFolder->CreateFileAsync("recordtimespantofile_example.mp4", CreationCollisionOption::ReplaceExisting)).then(
[this](StorageFile^ file)
{
RecordTimeSpanToFile(file);
});
Guardar imágenes de captura de pantalla en archivos
La aplicación puede iniciar una captura de pantalla que guardará el contenido actual de la ventana de la aplicación en un archivo de imagen o en varios archivos de imagen con diferentes codificaciones de imágenes. Para especificar las codificaciones de imagen que desea usar, cree una lista de cadenas donde cada una representa un tipo de imagen. Las propiedades de imageEncodingSubtypes proporcionan la cadena correcta para cada tipo de imagen admitido, como MediaEncodingSubtypes.Png o MediaEncodingSubtypes.JpegXr.
Inicie la captura de pantalla llamando al método SaveScreenshotToFilesAsync del objeto AppRecordingManager. El primer parámetro de este método es storageFolder donde se guardarán los archivos de imagen. El segundo parámetro es un prefijo de nombre de archivo al que el sistema anexará la extensión para cada tipo de imagen guardado, como ".png".
El tercer parámetro para SaveScreenshotToFilesAsync es necesario para que el sistema pueda realizar la conversión de espacio de colores adecuada si la ventana actual que se va a capturar muestra contenido HDR. Si el contenido HDR está presente, este parámetro debe establecerse en AppRecordingSaveScreenshotOption.HdrContentVisible. De lo contrario, use AppRecordingSaveScreenshotOption.None. El parámetro final del método es la lista de formatos de imagen a los que se debe capturar la pantalla.
Cuando se completa la llamada asincrónica a SaveScreenshotToFilesAsync, devuelve un objeto AppRecordingSavedScreenshotInfo que proporciona storageFile y el valor MediaEncodingSubtypes asociado que indica el tipo de imagen para cada imagen guardada.
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);
}
});
}
En el ejemplo siguiente se muestra código básico para iniciar la operación de captura de pantalla que se muestra en el ejemplo anterior.
StorageFolder^ storageFolder = ApplicationData::Current->LocalFolder;
SaveScreenShotToFiles(storageFolder, "screen_capture");
Adición de metadatos de juego para la captura iniciada por el sistema y la aplicación
En las secciones siguientes de este artículo se describe cómo proporcionar metadatos que el sistema insertará en la secuencia MP4 de juego capturado o de difusión. Los metadatos se pueden incrustar en medios que se capturan mediante la interfaz de usuario del sistema integrada y los medios capturados por la aplicación con AppRecordingManager. La aplicación y otras aplicaciones pueden extraer estos metadatos durante la reproducción multimedia con el fin de proporcionar experiencias contextualmente conscientes de que se sincronizan con el juego capturado o de difusión.
Obtención de una instancia de AppCaptureMetadataWriter
La clase principal para administrar metadatos de captura de aplicaciones es AppCaptureMetadataWriter. Antes de inicializar una instancia de esta clase, use el método ApiInformation.IsApiContractPresent para consultar la versión 1.0 de Windows.Media.Capture.AppCaptureMetadataContract para comprobar que la API está disponible en el dispositivo actual.
if (Windows::Foundation::Metadata::ApiInformation::IsApiContractPresent("Windows.Media.Capture.AppCaptureMetadataContract", 1, 0))
{
m_appCaptureMetadataWriter = ref new AppCaptureMetadataWriter();
}
Escritura de metadatos en la memoria caché del sistema para la aplicación
Cada elemento de metadatos tiene una etiqueta de cadena, que identifica el elemento de metadatos, un valor de datos asociado que puede ser una cadena, un entero o un valor doble, y un valor de la enumeración AppCaptureMetadataPriority que indica la prioridad relativa del elemento de datos. Un elemento de metadatos puede considerarse un "evento", que se produce en un único momento o en un "estado" que mantiene un valor a lo largo de un período de tiempo. Los metadatos se escriben en una memoria caché asignada y administrada para la aplicación por el sistema. El sistema aplica un límite de tamaño en la caché de memoria de metadatos y, cuando se alcanza el límite, purgará los datos en función de la prioridad con la que se escribió cada elemento de metadatos. En la siguiente sección de este artículo se muestra cómo administrar la asignación de memoria de metadatos de la aplicación.
Una aplicación típica puede optar por escribir algunos metadatos al principio de la sesión de captura para proporcionar algún contexto para los datos posteriores. Para este escenario, se recomienda usar datos instantáneos de "evento". En este ejemplo se llama a AddStringEvent, AddDoubleEvent y AddInt32Event para establecer valores instantáneos para cada tipo de datos.
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);
}
}
Un escenario común para usar datos de "estado" que se conservan con el tiempo es realizar un seguimiento del mapa del juego que el jugador está actualmente dentro. En este ejemplo se llama a StartStringState para establecer el valor de estado.
void App::StartMap(Platform::String^ mapName)
{
m_appCaptureMetadataWriter->StartStringState("map", mapName, AppCaptureMetadataPriority::Important);
}
Llame a StopState para registrar que ha finalizado un estado determinado.
void App::EndMap(Platform::String^ mapName)
{
m_appCaptureMetadataWriter->StopState("map");
}
Puede sobrescribir un estado estableciendo un nuevo valor con una etiqueta de estado existente.
void App::LevelUp(int newLevel)
{
m_appCaptureMetadataWriter->StartInt32State("currentLevel", newLevel, AppCaptureMetadataPriority::Important);
}
Puede finalizar todos los estados abiertos actualmente llamando a StopAllStates.
void App::RaceComplete()
{
m_appCaptureMetadataWriter->StopAllStates();
}
Administración del límite de almacenamiento en caché de metadatos
El sistema almacena en caché los metadatos que se escriben con AppCaptureMetadataWriter hasta que se escriben en la secuencia multimedia asociada. El sistema define un límite de tamaño para la caché de metadatos de cada aplicación. Una vez alcanzado el límite de tamaño de caché, el sistema comenzará a purgar los metadatos almacenados en caché. El sistema eliminará los metadatos escritos con el valor de prioridad AppCaptureMetadataPriority.Informational antes de eliminar metadatos con la prioridad AppCaptureMetadataPriority.Important.
En cualquier momento, puedes comprobar el número de bytes disponibles en la caché de metadatos de la aplicación llamando a RemainingStorageBytesAvailable. Puede elegir establecer su propio umbral definido por la aplicación después del cual puede optar por reducir la cantidad de metadatos que escriba en la memoria caché. En el ejemplo siguiente se muestra una implementación sencilla de este patrón.
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);
}
}
Recibir notificaciones cuando el sistema purga los metadatos
Puede registrarse para recibir una notificación cuando el sistema comienza a purgar los metadatos de la aplicación registrando un controlador para el evento MetadataPurged.
if (m_appCaptureMetadataWriter != nullptr)
{
m_appCaptureMetadataWriter->MetadataPurged +=
ref new TypedEventHandler<AppCaptureMetadataWriter^, Platform::Object^>(this, &App::OnMetadataPurged);
}
En el controlador del evento MetadataPurged , puede borrar alguna sala en la caché de metadatos finalizando los estados de prioridad inferior, puede implementar lógica definida por la aplicación para reducir la cantidad de metadatos que escribe en la memoria caché, o bien puede hacer nada y dejar que el sistema continúe purgando la caché en función de la prioridad con la que se escribió.
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."));
}
Temas relacionados