TOC

This article has been localized into Portuguese by the community.

Áudio e Vídeo:

Criando um player de Áudio e Vídeo

Como conclusão dos últimos capítulos sobre reprodução de áudio e vídeo, decidi criar uma amostra mais completa, onde aproveitamos o fato de que as classes MediaPlayer / MediaElement podem lidar com áudio e vídeo.

Vou usar os conceitos usados nos artigos sobre reprodução de áudio e vídeo e combiná-los com vários controles que já discutimos anteriormente neste artigo e transformá-los em um WPF Media Player. O resultado será algo parecido com isto:

Mas isso é apenas quando reproduz arquivos de áudio / MP3. Depois que um vídeo é carregado, a interface se expande automaticamente para mostrar o conteúdo do vídeo dentro da janela:

Deixe-me contar um pouco sobre como essa coisa foi construída. No final, você pode ver todo o código-fonte, pronto para você brincar.

A interface

A interface foi dividida em três áreas verticais: A parte superior, onde a barra de ferramentas está localizada, o meio, onde o vídeo (se um arquivo de vídeo é carregado) é mostrado, e a parte inferior, onde encontramos uma barra de status, completa com um status de tempo, um Controle deslizante para ver e controlar o progresso e um ProgressBar para mostrar o volume. Todos os controles usados aqui foram explicados anteriormente no tutorial, então não vamos nos concentrar muito nisso.

Observe o uso de comandos do WPF, em vez de clicar em eventos para os botões. Isso nos permite reutilizar facilmente a funcionalidade, caso desejemos adicionar, por exemplo, um menu principal ou um menu de contexto com algumas das mesmas funcionalidades. Também torna mais fácil para nós ativar e desativar a funcionalidade, dependendo do estado atual do player.

Observe também que definimos a propriedade MediaElement Stretch como None e o Window SizeToContentMode como WidthAndHeight . Isto é o que mantém a janela no tamanho mínimo necessário para mostrar a interface, assim como o vídeo, se estiver jogando.

Para mostrar o volume, usamos um controle ProgressBar no canto inferior direito. Isso não permite que o usuário controle o volume, mas apenas reflete a propriedade Volume no controle MediaElement, por meio de uma ligação de dados clássica. Nós implementamos um truque pequeno, mas legal para permitir que o usuário controle o volume de qualquer maneira - mais sobre isso abaixo.

O código

Em Code-behind, nós reutilizamos várias técnicas já usadas em nossos exemplos anteriores. Por exemplo, nós iniciamos um DispatcherTimer e o deixamos marcar a cada segundo, para mostrar o progresso atual da reprodução na interface. No evento Tick do cronômetro, atualizamos o controle Slider , definindo Mínimo , Máximo e atual Valor de acordo com para o arquivo que está sendo reproduzido e conectando-se ao evento ValueChanged no controle deslizante, usamos isso para atualizar o rótulo que mostra o andamento da reprodução atual em horas, minutos e segundos.

O controle Slider também permite que o usuário pule para outra parte do arquivo, simplesmente arrastando o "polegar" para outro local. Nós lidamos com isso implementando eventos para DragStarted e DragCompleted - o primeiro a definir uma variável ( userIsDraggingSlider ) que informa ao cronômetro para não atualizar o Deslize enquanto arrasta e o segundo para pular para a parte designada quando o usuário soltar o botão do mouse.

Existem os manipuladores CanExecute e Executed para os quatro comandos que usamos e especialmente os de Pause e Stop são interessantes. Por nós não podermos pegar o estado atual do controle MediaElement, temos que manter a trilha do estado atual nós mesmos. Isto é feito com uma variável local chamada mediaPlayerIsPlaying, que nós regularmente verificaremos para ver se os botões Pause e Stop devem ser habilitados.

O último detalhe que você deve notar é o evento Grid_MouseWheel . O Grid principal cobre a janela inteira, então, ao assinar este evento, nós somos notificados quando o usuário rola a roda. Quando isso acontece, como um pequeno truque, aumentamos ou diminuímos o volume, dependendo da direção (obtemos isso observando a propriedade Delta, que é negativa ao rolar para baixo e positiva ao rolar para cima). Isso é imediatamente refletido na interface do usuário, onde um controle ProgressBar é vinculado à propriedade Volume do MediaElement.

O código fonte completo

Com toda a teoria por trás do exemplo descrito, aqui está o código-fonte completo:

<Window x:Class="WpfTutorialSamples.Audio_and_Video.AudioVideoPlayerCompleteSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WPF Media Player" Height="300" Width="300"
        MinWidth="300" SizeToContent="WidthAndHeight">
    <Window.CommandBindings>
        <CommandBinding Command="ApplicationCommands.Open" CanExecute="Open_CanExecute" Executed="Open_Executed" />
        <CommandBinding Command="MediaCommands.Play" CanExecute="Play_CanExecute" Executed="Play_Executed" />
        <CommandBinding Command="MediaCommands.Pause" CanExecute="Pause_CanExecute" Executed="Pause_Executed" />
        <CommandBinding Command="MediaCommands.Stop" CanExecute="Stop_CanExecute" Executed="Stop_Executed" />
    </Window.CommandBindings>
    <Grid MouseWheel="Grid_MouseWheel">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <ToolBar>
            <Button Command="ApplicationCommands.Open">
                <Image Source="/WpfTutorialSamples;component/Images/folder.png" />
            </Button>
            <Separator />
            <Button Command="MediaCommands.Play">
                <Image Source="/WpfTutorialSamples;component/Images/control_play_blue.png" />
            </Button>
            <Button Command="MediaCommands.Pause">
                <Image Source="/WpfTutorialSamples;component/Images/control_pause_blue.png" />
            </Button>
            <Button Command="MediaCommands.Stop">
                <Image Source="/WpfTutorialSamples;component/Images/control_stop_blue.png" />
            </Button>
        </ToolBar>

        <MediaElement Name="mePlayer" Grid.Row="1" LoadedBehavior="Manual" Stretch="None" />

        <StatusBar Grid.Row="2">
            <StatusBar.ItemsPanel>
                <ItemsPanelTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                    </Grid>
                </ItemsPanelTemplate>
            </StatusBar.ItemsPanel>
            <StatusBarItem>
                <TextBlock Name="lblProgressStatus">00:00:00</TextBlock>
            </StatusBarItem>
            <StatusBarItem Grid.Column="1" HorizontalContentAlignment="Stretch">
                <Slider Name="sliProgress" Thumb.DragStarted="sliProgress_DragStarted"  Thumb.DragCompleted="sliProgress_DragCompleted" ValueChanged="sliProgress_ValueChanged" />
            </StatusBarItem>
            <StatusBarItem Grid.Column="2">
                <ProgressBar Name="pbVolume" Width="50" Height="12" Maximum="1" Value="{Binding ElementName=mePlayer, Path=Volume}" />
            </StatusBarItem>
        </StatusBar>
    </Grid>
</Window>
using System;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Threading;
using Microsoft.Win32;

namespace WpfTutorialSamples.Audio_and_Video
{
	public partial class AudioVideoPlayerCompleteSample : Window
	{
		private bool mediaPlayerIsPlaying = false;
		private bool userIsDraggingSlider = false;

		public AudioVideoPlayerCompleteSample()
		{
			InitializeComponent();

			DispatcherTimer timer = new DispatcherTimer();
			timer.Interval = TimeSpan.FromSeconds(1);
			timer.Tick += timer_Tick;
			timer.Start();
		}

		private void timer_Tick(object sender, EventArgs e)
		{
			if((mePlayer.Source != null) && (mePlayer.NaturalDuration.HasTimeSpan) && (!userIsDraggingSlider))
			{
				sliProgress.Minimum = 0;
				sliProgress.Maximum = mePlayer.NaturalDuration.TimeSpan.TotalSeconds;
				sliProgress.Value = mePlayer.Position.TotalSeconds;
			}
		}

		private void Open_CanExecute(object sender, CanExecuteRoutedEventArgs e)
		{
			e.CanExecute = true;
		}

		private void Open_Executed(object sender, ExecutedRoutedEventArgs e)
		{
			OpenFileDialog openFileDialog = new OpenFileDialog();
			openFileDialog.Filter = "Media files (*.mp3;*.mpg;*.mpeg)|*.mp3;*.mpg;*.mpeg|All files (*.*)|*.*";
			if(openFileDialog.ShowDialog() == true)
				mePlayer.Source = new Uri(openFileDialog.FileName);
		}

		private void Play_CanExecute(object sender, CanExecuteRoutedEventArgs e)
		{
			e.CanExecute = (mePlayer != null) && (mePlayer.Source != null);
		}

		private void Play_Executed(object sender, ExecutedRoutedEventArgs e)
		{
			mePlayer.Play();
			mediaPlayerIsPlaying = true;
		}

		private void Pause_CanExecute(object sender, CanExecuteRoutedEventArgs e)
		{
			e.CanExecute = mediaPlayerIsPlaying;
		}

		private void Pause_Executed(object sender, ExecutedRoutedEventArgs e)
		{
			mePlayer.Pause();
		}

		private void Stop_CanExecute(object sender, CanExecuteRoutedEventArgs e)
		{
			e.CanExecute = mediaPlayerIsPlaying;
		}

		private void Stop_Executed(object sender, ExecutedRoutedEventArgs e)
		{
			mePlayer.Stop();
			mediaPlayerIsPlaying = false;
		}

		private void sliProgress_DragStarted(object sender, DragStartedEventArgs e)
		{
			userIsDraggingSlider = true;
		}

		private void sliProgress_DragCompleted(object sender, DragCompletedEventArgs e)
		{
			userIsDraggingSlider = false;
			mePlayer.Position = TimeSpan.FromSeconds(sliProgress.Value);
		}

		private void sliProgress_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
		{
			lblProgressStatus.Text = TimeSpan.FromSeconds(sliProgress.Value).ToString(@"hh\:mm\:ss");
		}

		private void Grid_MouseWheel(object sender, MouseWheelEventArgs e)
		{
			mePlayer.Volume += (e.Delta > 0) ? 0.1 : -0.1;
		}

	}
}

Resumo

A listagem de código pode parecer um pouco avassaladora, mas como você pode ver, há muita repetição nela. Se você tirar isso da imagem, logo perceberá que criar um media player bastante competente no WPF não é tão difícil assim! Sinta-se à vontade para expandir este exemplo para seus próprios projetos - que tal implementar um recurso de lista de reprodução?


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!