Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Neste guia rápido, aprenderá a criar uma aplicação básica de câmara WinUI 3 que exibe a pré-visualização da câmara. Em um aplicativo WinUI 3, você usa o controle MediaPlayerElement no namespace Microsoft.UI.Xaml.Controls para renderizar a visualização da câmera e a classe MediaCapture do WinRT para acessar o fluxo de visualização da câmera do dispositivo. O MediaCapture fornece APIs para executar uma ampla gama de tarefas relacionadas à câmera, como capturar fotos e vídeos e configurar o driver de dispositivo da câmera. Consulte os outros artigos nesta seção para obter detalhes sobre outros recursos do MediaCapture .
O código neste passo a passo é adaptado do exemplo MediaCapture WinUI 3 no github.
Sugestão
Para a versão UWP deste artigo, consulte Mostrar a pré-visualização da câmera na documentação da UWP.
Pré-requisitos
- Seu dispositivo deve ter o modo de desenvolvedor ativado. Para obter mais informações, consulte Configurações para desenvolvedores.
- Visual Studio 2022 ou posterior com a carga de trabalho para desenvolvimento de aplicações WinUI.
Criar um novo aplicativo WinUI 3
No Visual Studio, crie um novo projeto. Na caixa de diálogo Criar um novo projeto , defina o filtro de idioma como "C#" e o filtro de plataforma como "Windows" e, em seguida, selecione o modelo de projeto "Aplicativo em branco, empacotado (WinUI 3 na área de trabalho)".
Criar a interface do usuário
A interface do usuário simples para este exemplo inclui um controle MediaPlayerElement para exibir a visualização da câmera, um ComboBox que permite selecionar entre as câmeras do dispositivo e botões para inicializar a classe MediaCapture , iniciar e parar a visualização da câmera e redefinir a amostra. Também incluímos um TextBlock para exibir mensagens de status.
No arquivo MainWindow.xml do seu projeto, substitua o controle StackPanel padrão pelo seguinte XAML.
<Grid ColumnDefinitions="4*,*" ColumnSpacing="4">
<MediaPlayerElement x:Name="mpePreview" Grid.Row="0" Grid.Column="0" AreTransportControlsEnabled="False" ManipulationMode="None"/>
<StackPanel Orientation="Vertical" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Top">
<TextBlock Text="Status:" Margin="0,0,10,0"/>
<TextBlock x:Name="tbStatus" Text=""/>
<TextBlock Text="Preview Source:" Margin="0,0,10,0"/>
<ComboBox x:Name="cbDeviceList" HorizontalAlignment="Stretch" SelectionChanged="cbDeviceList_SelectionChanged"></ComboBox>
<Button x:Name="bStartMediaCapture" Content="Initialize MediaCapture" IsEnabled="False" Click="bStartMediaCapture_Click"/>
<Button x:Name="bStartPreview" Content="Start preview" IsEnabled="False" Click="bStartPreview_Click"/>
<Button x:Name="bStopPreview" Content="Stop preview" IsEnabled="False" Click="bStopPreview_Click"/>
<Button x:Name="bReset" Content="Reset" Click="bReset_Click" />
</StackPanel>
</Grid>
Atualizar a definição de classe MainWindow
O restante do código neste artigo será adicionado à definição de classe MainWindow no arquivo MainWindow.xaml.cs do seu projeto. Primeiro, adicione algumas variáveis de classe que persistirão durante todo o tempo de vida da janela. Estas variáveis incluem:
- Um DeviceInformationCollection que armazenará um objeto DeviceInformation para cada câmera disponível. O objeto DeviceInformation transmite informações como o identificador exclusivo e o nome amigável da câmera.
- Um objeto MediaCapture que lida com interações com o driver da câmera selecionada e permite que você recupere o fluxo de vídeo da câmera.
- Um objeto MediaFrameSource que representa uma fonte de quadros de mídia, como um fluxo de vídeo.
- Um booleano para monitorizar quando a pré-visualização da câmara está em execução. Algumas configurações da câmera não podem ser alteradas enquanto a visualização está em execução, por isso é uma boa prática acompanhar o estado da visualização da câmera.
private DeviceInformationCollection m_deviceList;
private MediaCapture m_mediaCapture;
private MediaFrameSource m_frameSource;
private MediaPlayer m_mediaPlayer;
private bool m_isPreviewing;
Preencher a lista de câmaras disponíveis
Em seguida, criaremos um método auxiliar para detetar as câmeras que estão presentes no dispositivo atual e preencher a ComboBox na interface do usuário com os nomes das câmeras, permitindo que o usuário selecione uma câmera para visualizar. O DeviceInformation.FindAllAsync permite que você consulte muitos tipos diferentes de dispositivos. Usamos MediaDevice.GetVideoCaptureSelector para recuperar o identificador que especifica que só queremos recuperar dispositivos de captura de vídeo.
private async void PopulateCameraList()
{
cbDeviceList.Items.Clear();
m_deviceList = await DeviceInformation.FindAllAsync(MediaDevice.GetVideoCaptureSelector());
if(m_deviceList.Count == 0)
{
tbStatus.Text = "No video capture devices found.";
return;
}
foreach (var device in m_deviceList)
{
cbDeviceList.Items.Add(device.Name);
bStartMediaCapture.IsEnabled = true;
}
}
Adicione uma chamada a esse método auxiliar para o construtor de classe MainWindow para que o ComboBox seja preenchido quando a janela for carregada.
public MainWindow()
{
this.InitializeComponent();
PopulateCameraList();
}
Inicializar o objeto MediaCapture
Inicialize o objeto MediaCapture chamando InitializeAsync, passando um objeto MediaCaptureInitializationSettings contendo os parâmetros de inicialização solicitados. Há muitos parâmetros de inicialização opcionais que permitem diferentes cenários. Consulte a página de referência da API para obter a lista completa. Neste exemplo simples, especificamos algumas configurações básicas, incluindo:
- A propriedade VideoDeviceId especifica o identificador exclusivo da câmera à qual o MediaCapture será anexado. Obtemos o ID do dispositivo a partir de DeviceInformationCollection, usando o índice selecionado da ComboBox.
- A propriedade SharingMode especifica se o aplicativo está solicitando acesso compartilhado e somente leitura à câmera, que permite visualizar e capturar a partir do fluxo de vídeo, ou controle exclusivo da câmera, que permite alterar a configuração da câmera. Várias aplicações podem ler a partir de uma câmara em simultâneo, mas apenas uma aplicação de cada vez pode ter controlo exclusivo.
- A propriedade StreamingCaptureMode especifica se queremos capturar vídeo, áudio ou áudio e vídeo.
- O MediaCaptureMemoryPreference nos permite solicitar o uso específico da memória da CPU para quadros de vídeo. O valor Auto permite que o sistema use a memória da GPU, se estiver disponível.
Antes de inicializar o objeto MediaCapture , chamamos o método AppCapability.CheckAccess para determinar se o usuário negou o acesso do nosso aplicativo à câmera nas Configurações do Windows.
Observação
O Windows permite que os usuários concedam ou neguem acesso à câmera do dispositivo nas Configurações do Windows, em Privacidade e Segurança -> Câmera. Ao inicializar o dispositivo de captura, os aplicativos devem verificar se têm acesso à câmera e lidar com o caso em que o acesso é negado pelo usuário. Para obter mais informações, consulte Manipular a configuração de privacidade da câmera do Windows.
A chamada InitializeAsync é feita de dentro de um bloco try para que possamos recuperar se a inicialização falhar. Os aplicativos devem lidar com a falha de inicialização normalmente. Neste exemplo simples, exibiremos apenas uma mensagem de erro em caso de falha.
private async void bStartMediaCapture_Click(object sender, RoutedEventArgs e)
{
if (m_mediaCapture != null)
{
tbStatus.Text = "MediaCapture already initialized.";
return;
}
// Supported in Windows Build 18362 and later
if(AppCapability.Create("Webcam").CheckAccess() != AppCapabilityAccessStatus.Allowed)
{
tbStatus.Text = "Camera access denied. Launching settings.";
bool result = await Windows.System.Launcher.LaunchUriAsync(new Uri("ms-settings:privacy-webcam"));
if (AppCapability.Create("Webcam").CheckAccess() != AppCapabilityAccessStatus.Allowed)
{
tbStatus.Text = "Camera access denied in privacy settings.";
return;
}
}
try
{
m_mediaCapture = new MediaCapture();
var mediaCaptureInitializationSettings = new MediaCaptureInitializationSettings()
{
VideoDeviceId = m_deviceList[cbDeviceList.SelectedIndex].Id,
SharingMode = MediaCaptureSharingMode.ExclusiveControl,
StreamingCaptureMode = StreamingCaptureMode.Video,
MemoryPreference = MediaCaptureMemoryPreference.Auto
};
await m_mediaCapture.InitializeAsync(mediaCaptureInitializationSettings);
tbStatus.Text = "MediaCapture initialized successfully.";
bStartPreview.IsEnabled = true;
}
catch (Exception ex)
{
tbStatus.Text = "Initialize media capture failed: " + ex.Message;
}
}
Inicializar a pré-visualização da câmara
Quando o usuário clica no botão Iniciar visualização, tentaremos criar um MediaFrameSource para um fluxo de vídeo do dispositivo de câmera com o qual o objeto MediaCapture foi inicializado. As fontes de quadros disponíveis são expostas pela propriedade MediaCapture.FrameSources .
Para encontrar uma fonte de quadro que contenha dados de vídeo a cores, em oposição a uma câmera de profundidade, por exemplo, procuramos uma fonte de quadro que tenha um SourceKind de Color. Alguns drivers de câmera fornecem um fluxo de visualização dedicado que é separado do fluxo de gravação. Para obter o fluxo de pré-visualização de vídeo, tentamos selecionar uma fonte de quadro que tenha um MediaStreamType de VideoPreview. Se nenhum fluxo de visualização for encontrado, podemos obter o fluxo de vídeo de gravação ao selecionar um MediaStreamType de VideoRecord. Se nenhuma dessas fontes de quadros estiver disponível, esse dispositivo de captura não poderá ser usado para visualização de vídeo.
Depois de selecionar uma fonte de quadro, criamos um novo objeto MediaPlayer que será renderizado pelo MediaPlayerElement em nossa interface do usuário. Definimos a propriedade Source do MediaPlayer como um novo objeto MediaSource que criamos a partir de nosso MediaFrameSource selecionado.
Use Reproduzir no objeto MediaPlayer para começar a renderizar o fluxo de vídeo.
private void bStartPreview_Click(object sender, RoutedEventArgs e)
{
m_frameSource = null;
// Find preview source.
// The preferred preview stream from a camera is defined by MediaStreamType.VideoPreview on the RGB camera (SourceKind == color).
var previewSource = m_mediaCapture.FrameSources.FirstOrDefault(source => source.Value.Info.MediaStreamType == MediaStreamType.VideoPreview
&& source.Value.Info.SourceKind == MediaFrameSourceKind.Color).Value;
if (previewSource != null)
{
m_frameSource = previewSource;
}
else
{
var recordSource = m_mediaCapture.FrameSources.FirstOrDefault(source => source.Value.Info.MediaStreamType == MediaStreamType.VideoRecord
&& source.Value.Info.SourceKind == MediaFrameSourceKind.Color).Value;
if (recordSource != null)
{
m_frameSource = recordSource;
}
}
if (m_frameSource == null)
{
tbStatus.Text = "No video preview or record stream found.";
return;
}
// Create MediaPlayer with the preview source
m_mediaPlayer = new MediaPlayer();
m_mediaPlayer.RealTimePlayback = true;
m_mediaPlayer.AutoPlay = false;
m_mediaPlayer.Source = MediaSource.CreateFromMediaFrameSource(m_frameSource);
m_mediaPlayer.MediaFailed += MediaPlayer_MediaFailed; ;
// Set the mediaPlayer on the MediaPlayerElement
mpePreview.SetMediaPlayer(m_mediaPlayer);
// Start preview
m_mediaPlayer.Play();
tbStatus.Text = "Start preview succeeded!";
m_isPreviewing = true;
bStartPreview.IsEnabled = false;
bStopPreview.IsEnabled = true;
}
Implemente um manipulador para o evento MediaFailed para que você possa manipular erros de renderização da visualização.
private void MediaPlayer_MediaFailed(MediaPlayer sender, MediaPlayerFailedEventArgs args)
{
tbStatus.Text = "MediaPlayer error: " + args.ErrorMessage;
}
Parar a pré-visualização da câmara
Para interromper a visualização da câmera, chame Pause no objeto MediaPlayer.
private void bStopPreview_Click(object sender, RoutedEventArgs e)
{
// Stop preview
m_mediaPlayer.Pause();
m_isPreviewing = false;
bStartPreview.IsEnabled = true;
bStopPreview.IsEnabled = false;
}
Reiniciar a aplicação
Para facilitar o teste do aplicativo de exemplo, adicione um método para redefinir o estado do aplicativo. Os aplicativos de câmera devem sempre descartar a câmera e os recursos associados quando a câmera não for mais necessária.
private void bReset_Click(object sender, RoutedEventArgs e)
{
if (m_mediaCapture != null)
{
m_mediaCapture.Dispose();
m_mediaCapture = null;
}
if(m_mediaPlayer != null)
{
m_mediaPlayer.Dispose();
m_mediaPlayer = null;
}
m_frameSource = null;
bStartMediaCapture.IsEnabled = false;
bStartPreview.IsEnabled = false;
bStopPreview.IsEnabled = false;
PopulateCameraList();
}
Windows developer