Capturar áudio de jogo, vídeo, capturas de tela e metadados
Este artigo descreve como capturar vídeo, áudio e capturas de tela do jogo e como enviar metadados que o sistema incorporará na mídia capturada e transmitida, permitindo que seu aplicativo e outras pessoas criem experiências dinâmicas sincronizadas com eventos de jogo.
Há duas maneiras diferentes de capturar a jogabilidade em um aplicativo UWP. O usuário pode iniciar a captura usando a interface do usuário interna do sistema. A mídia capturada usando essa técnica é ingerida no ecossistema de jogos da Microsoft, pode ser exibida e compartilhada por meio de experiências próprias, como o aplicativo Xbox, e não está disponível diretamente para seu aplicativo ou para os usuários. As primeiras seções deste artigo mostrarão como habilitar e desabilitar a captura de aplicativos implementada pelo sistema e como receber notificações quando a captura de aplicativos for iniciada ou interrompida.
A outra maneira de capturar mídia é usar as APIs do namespace Windows.Media.AppRecording. Se a captura estiver habilitada no dispositivo, seu aplicativo poderá começar a capturar o jogo e, depois de algum tempo, você poderá interromper a captura, momento em que a mídia é gravada em um arquivo. Se o usuário tiver ativado a captura histórica, você também poderá gravar a jogabilidade que já ocorreu especificando uma hora de início no passado e uma duração para gravar. Ambas as técnicas produzem um arquivo de vídeo que pode ser acessado pelo seu aplicativo e, dependendo de onde você escolher salvar os arquivos, pelo usuário. As seções intermediárias deste artigo orientam você na implementação desses cenários.
O namespace Windows.Media.Capture fornece APIs para criar metadados que descrevem a jogabilidade que está sendo capturada ou transmitida. Isso pode incluir valores numéricos ou de texto, com um rótulo de texto identificando cada item de dados. Os metadados podem representar um "evento" que ocorre em um único momento, como quando o usuário termina uma volta em um jogo de corrida, ou podem representar um "estado" que persiste por um período de tempo, como o mapa do jogo atual em que o usuário está jogando. Os metadados são gravados em um cache alocado e gerenciado para seu aplicativo pelo sistema. Os metadados são incorporados em fluxos de transmissão e arquivos de vídeo capturados, incluindo a captura do sistema integrado ou técnicas de captura de aplicativo personalizadas. As seções finais deste artigo mostram como escrever metadados de jogabilidade.
Observação
Como os metadados do jogo podem ser incorporados em arquivos de mídia que podem ser compartilhados pela rede, fora do controle do usuário, você não deve incluir informações de identificação pessoal ou outros dados potencialmente confidenciais nos metadados.
Habilitar e desabilitar a captura de aplicativos do sistema
A captura do aplicativo do sistema é iniciada pelo usuário com a interface do usuário do sistema integrada. Os arquivos são ingeridos pelo ecossistema de jogos do Windows e não estão disponíveis para seu aplicativo ou usuário, exceto por meio de experiências próprias, como o aplicativo Xbox. Seu aplicativo pode desabilitar e habilitar a captura de aplicativo iniciada pelo sistema, permitindo que você impeça que o usuário capture determinado conteúdo ou jogabilidade.
Para habilitar ou desabilitar a captura de aplicativos do sistema, basta chamar o método estático AppCapture.SetAllowedAsync e passar false para desabilitar a captura ou true para habilitar a captura.
Windows::Media::Capture::AppCapture::SetAllowedAsync(allowed);
Receba notificações quando a captura do aplicativo do sistema for iniciada e interrompida
Para receber uma notificação quando a captura do aplicativo do sistema começar ou terminar, primeiro obtenha uma instância da classe AppCapture chamando o método de fábrica GetForCurrentView. Em seguida, registre um manipulador para o evento 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);
No manipulador do evento CapturingChanged, você pode verificar as propriedades IsCapturingAudio e IsCapturingVideo para determinar se o áudio ou o vídeo estão sendo capturados, respectivamente. Talvez você queira atualizar a interface do usuário do seu aplicativo para indicar o status de captura atual.
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);
}
Adicionar as extensões da área de trabalho do Windows para a UWP ao seu aplicativo
As APIs para gravação de áudio e vídeo e para captura de tela diretamente do seu aplicativo, encontradas no namespace Windows.Media.AppRecording , não estão incluídas no contrato da API Universal. Para acessar as APIs, você deve adicionar uma referência às Extensões da Área de Trabalho do Windows para a UWP ao seu aplicativo com as etapas a seguir.
- No Visual Studio, no Gerenciador de Soluções, expanda seu projeto UWP e clique com o botão direito do mouse em Referências e selecione Adicionar Referência....
- Expanda o nó Universal do Windows e selecione Extensões.
- Na lista de extensões, marque a caixa de seleção ao lado das Extensões da Área de Trabalho do Windows para a entrada UWP que corresponde ao build de destino do seu projeto. Para os recursos de transmissão do aplicativo, a versão deve ser 1709 ou superior.
- Clique em OK.
Obter uma instância do AppRecordingManager
A classe AppRecordingManager é a API central que você usará para gerenciar a gravação do aplicativo. Obtenha uma instância dessa classe chamando o método de fábrica GetDefault. Antes de usar qualquer uma das APIs no namespace Windows.Media.AppRecording , você deve verificar sua presença no dispositivo atual. As APIs não estão disponíveis em dispositivos que executam uma versão do sistema operacional anterior ao Windows 10, versão 1709. Em vez de verificar se há uma versão específica do sistema operacional, use o método ApiInformation.IsApiContractPresent para consultar o Windows.Media.AppBroadcasting.AppRecordingContract versão 1.0. Se esse contrato estiver presente, as APIs de gravação estarão disponíveis no dispositivo. O código de exemplo neste artigo verifica as APIs uma vez e, em seguida, verifica se o AppRecordingManager é nulo antes das operações subsequentes.
if (Windows::Foundation::Metadata::ApiInformation::IsApiContractPresent(
"Windows.Media.AppRecording.AppRecordingContract", 1, 0))
{
m_appRecordingManager = AppRecordingManager::GetDefault();
}
Determinar se seu aplicativo pode gravar no momento
Há vários motivos pelos quais seu aplicativo pode não ser capaz de capturar áudio ou vídeo no momento, incluindo se o dispositivo atual não atender aos requisitos de hardware para gravação ou se outro aplicativo estiver transmitindo no momento. Antes de iniciar uma gravação, você pode verificar se seu aplicativo pode gravar no momento. Chame o método GetStatus do objeto AppRecordingManager e verifique a propriedade CanRecord do objeto AppRecordingStatus retornado. Se CanRecord retornar false, o que significa que seu aplicativo não pode gravar no momento, você poderá verificar a propriedade Details para determinar o motivo. Dependendo do motivo, você pode exibir o status para o usuário ou mostrar instruções para habilitar a gravação do aplicativo.
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 e parar manualmente a gravação do app em um arquivo
Depois de verificar se seu aplicativo é capaz de gravar, você pode iniciar uma nova gravação chamando o método StartRecordingToFileAsync do objeto AppRecordingManager.
No exemplo a seguir, o primeiro bloco then é executado quando a tarefa assíncrona falha. O segundo bloco tenta acessar o resultado da tarefa e, se o resultado for nulo, a tarefa foi concluída. Em ambos os casos, o método auxiliar OnRecordingComplete , mostrado abaixo, é chamado para lidar com o 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();
}
});
}
Quando a operação de gravação for concluída, verifique a propriedade Succeeded do objeto AppRecordingResult retornado para determinar se a operação de gravação foi bem-sucedida. Nesse caso, você pode verificar a propriedade IsFileTruncated para determinar se, por motivos de armazenamento, o sistema foi forçado a truncar o arquivo capturado. Você pode verificar a propriedade Duração para descobrir a duração real do arquivo gravado que, se o arquivo estiver truncado, pode ser menor do que a duração da operação de gravação.
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;
}
}
Os exemplos a seguir mostram alguns códigos básicos para iniciar e parar a operação de gravação mostrada no exemplo 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 um período de tempo histórico em um arquivo
Se o usuário tiver habilitado a gravação histórica do seu aplicativo nas configurações do sistema, você poderá gravar um período de tempo do jogo que ocorreu anteriormente. Um exemplo anterior neste artigo mostrou como confirmar se seu aplicativo pode gravar jogos no momento. Há uma verificação adicional para determinar se a captura histórica está habilitada. Mais uma vez, chame GetStatus e verifique a propriedade CanRecordTimeSpan do objeto AppRecordingStatus retornado. Este exemplo também retorna a propriedade HistoricalBufferDuration do AppRecordingStatus, que será usada para determinar uma hora de início válida para a operação de gravação.
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 um período de tempo histórico, você deve especificar uma hora de início para a gravação e uma duração. A hora de início é fornecida como um struct DateTime . A hora de início deve ser uma hora anterior à hora atual, dentro do comprimento do buffer de gravação histórica. Para este exemplo, o comprimento do buffer é recuperado como parte da verificação para ver se a gravação histórica está habilitada, o que é mostrado no exemplo de código anterior. A duração da gravação histórica é fornecida como estrutura TimeSpan , que também deve ser igual ou menor que a duração do buffer histórico. Depois de determinar a hora de início e a duração desejadas, chame RecordTimeSpanToFileAsync para iniciar a operação de gravação.
Assim como a gravação com início e parada manuais, quando uma gravação histórica é concluída, você pode verificar a propriedade Succeeded do objeto AppRecordingResult retornado para determinar se a operação de gravação foi bem-sucedida e pode verificar as propriedades IsFileTruncated e Duration para descobrir a duração real do arquivo gravado que, se o arquivo estiver truncado, pode ser menor do que a duração do tempo solicitado janela.
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);
}
});
}
O exemplo a seguir mostra algum código básico para iniciar a operação de registro histórico mostrada no exemplo anterior.
StorageFolder^ storageFolder = ApplicationData::Current->LocalFolder;
concurrency::create_task(storageFolder->CreateFileAsync("recordtimespantofile_example.mp4", CreationCollisionOption::ReplaceExisting)).then(
[this](StorageFile^ file)
{
RecordTimeSpanToFile(file);
});
Salvar imagens de captura de tela em arquivos
Seu aplicativo pode iniciar uma captura de tela que salvará o conteúdo atual da janela do aplicativo em um arquivo de imagem ou em vários arquivos de imagem com diferentes codificações de imagem. Para especificar as codificações de imagem que você gostaria de usar, crie uma lista de strings em que cada uma representa um tipo de imagem. As propriedades do ImageEncodingSubtypes fornecem a cadeia de caracteres correta para cada tipo de imagem com suporte, como MediaEncodingSubtypes.Png ou MediaEncodingSubtypes.JpegXr.
Inicie a captura de tela chamando o método SaveScreenshotToFilesAsync do objeto AppRecordingManager. O primeiro parâmetro para esse método é um StorageFolder onde os arquivos de imagem serão salvos. O segundo parâmetro é um prefixo de nome de arquivo ao qual o sistema anexará a extensão para cada tipo de imagem salvo, como ".png".
O terceiro parâmetro para SaveScreenshotToFilesAsync é necessário para que o sistema possa fazer a conversão de espaço de cores adequada se a janela atual a ser capturada estiver exibindo conteúdo HDR. Se houver conteúdo HDR, esse parâmetro deverá ser definido como AppRecordingSaveScreenshotOption.HdrContentVisible. Caso contrário, use AppRecordingSaveScreenshotOption.None. O parâmetro final para o método é a lista de formatos de imagem para os quais a tela deve ser capturada.
Quando a chamada assíncrona para SaveScreenshotToFilesAsync é concluída, ela retorna um objeto AppRecordingSavedScreenshotInfo que fornece o valor StorageFile e MediaEncodingSubtypes associado, indicando o tipo de imagem para cada imagem salva.
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);
}
});
}
O exemplo a seguir mostra algum código básico para iniciar a operação de captura de tela mostrada no exemplo anterior.
StorageFolder^ storageFolder = ApplicationData::Current->LocalFolder;
SaveScreenShotToFiles(storageFolder, "screen_capture");
Adicionar metadados de jogo para captura iniciada pelo sistema e pelo aplicativo
As seções a seguir deste artigo descrevem como fornecer metadados que o sistema incorporará ao fluxo MP4 do jogo capturado ou transmitido. Os metadados podem ser inseridos na mídia capturada usando a interface do usuário do sistema integrada e na mídia capturada pelo aplicativo com AppRecordingManager. Esses metadados podem ser extraídos pelo seu aplicativo e outros aplicativos durante a reprodução de mídia para fornecer experiências contextuais que são sincronizadas com o jogo capturado ou transmitido.
Obter uma instância de AppCaptureMetadataWriter
A classe principal para gerenciar metadados de captura de aplicativo é AppCaptureMetadataWriter. Antes de inicializar uma instância dessa classe, use o método ApiInformation.IsApiContractPresent para consultar o Windows.Media.Capture.AppCaptureMetadataContract versão 1.0 para verificar se a API está disponível no dispositivo atual.
if (Windows::Foundation::Metadata::ApiInformation::IsApiContractPresent("Windows.Media.Capture.AppCaptureMetadataContract", 1, 0))
{
m_appCaptureMetadataWriter = ref new AppCaptureMetadataWriter();
}
Gravar metadados no cache do sistema para seu aplicativo
Cada item de metadados tem um rótulo de cadeia de caracteres, identificando o item de metadados, um valor de dados associado que pode ser uma cadeia de caracteres, um inteiro ou um valor duplo e um valor da enumeração AppCaptureMetadataPriority indicando a prioridade relativa do item de dados. Um item de metadados pode ser considerado um "evento", que ocorre em um único ponto no tempo, ou um "estado" que mantém um valor em uma janela de tempo. Os metadados são gravados em um cache de memória que é alocado e gerenciado para seu aplicativo pelo sistema. O sistema impõe um limite de tamanho no cache de memória de metadados e, quando o limite for atingido, limpará os dados com base na prioridade com a qual cada item de metadados foi gravado. A próxima seção deste artigo mostra como gerenciar a alocação de memória de metadados do seu aplicativo.
Um aplicativo típico pode optar por gravar alguns metadados no início da sessão de captura para fornecer algum contexto para os dados subsequentes. Para esse cenário, é recomendável usar dados instantâneos de "evento". Este exemplo chama AddStringEvent, AddDoubleEvent e AddInt32Event para definir valores instantâneos para cada tipo de dados.
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);
}
}
Um cenário comum para usar dados de "estado" que persistem ao longo do tempo é rastrear o mapa do jogo em que o jogador está no momento. Este exemplo chama StartStringState para definir o valor do estado.
void App::StartMap(Platform::String^ mapName)
{
m_appCaptureMetadataWriter->StartStringState("map", mapName, AppCaptureMetadataPriority::Important);
}
Chame StopState para registrar que um determinado estado terminou.
void App::EndMap(Platform::String^ mapName)
{
m_appCaptureMetadataWriter->StopState("map");
}
Você pode substituir um estado definindo um novo valor com um rótulo de estado existente.
void App::LevelUp(int newLevel)
{
m_appCaptureMetadataWriter->StartInt32State("currentLevel", newLevel, AppCaptureMetadataPriority::Important);
}
Você pode encerrar todos os estados abertos no momento chamando StopAllStates.
void App::RaceComplete()
{
m_appCaptureMetadataWriter->StopAllStates();
}
Gerenciar limite de armazenamento em cache de metadados
Os metadados que você grava com AppCaptureMetadataWriter são armazenados em cache pelo sistema até que sejam gravados no fluxo de mídia associado. O sistema define um limite de tamanho para o cache de metadados de cada aplicativo. Depois que o limite de tamanho do cache for atingido, o sistema começará a limpar os metadados armazenados em cache. O sistema excluirá os metadados que foram gravados com o valor de prioridade AppCaptureMetadataPriority.Informational antes de excluir metadados com a prioridade AppCaptureMetadataPriority.Important.
A qualquer momento, você pode verificar o número de bytes disponíveis no cache de metadados do aplicativo chamando RemainingStorageBytesAvailable. Você pode optar por definir seu próprio limite definido pelo aplicativo, após o qual pode optar por reduzir a quantidade de metadados gravados no cache. O exemplo a seguir mostra uma implementação simples desse padrão.
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);
}
}
Receba notificações quando o sistema limpar metadados
Você pode se registrar para receber uma notificação quando o sistema começar a limpar metadados para seu aplicativo registrando um manipulador para o evento MetadataPpurged.
if (m_appCaptureMetadataWriter != nullptr)
{
m_appCaptureMetadataWriter->MetadataPurged +=
ref new TypedEventHandler<AppCaptureMetadataWriter^, Platform::Object^>(this, &App::OnMetadataPurged);
}
No manipulador do evento MetadataPpurged , você pode liberar espaço no cache de metadados encerrando estados de prioridade mais baixa, implementar lógica definida pelo aplicativo para reduzir a quantidade de metadados gravados no cache ou não pode fazer nada e permitir que o sistema continue a limpar o cache com base na prioridade com a qual ele foi gravado.
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."));
}
Tópicos relacionados