TOC

This article has been localized into French by the community.

Audio & Vidéo:

Comment: Créer un lecteur Audio/Vidéo complet

En conclusion aux derniers chapitres sur la lecture audio et vidéo, j'ai décidé de créer un échantillon un peu plus complet, où on prend avantage du fait que les classes MediaPlayer/MediaElement peuvent manipuler non seulement l'audio mais aussi la vidéo.

Je vais prendre les concepts utilisés dans les articles sur la lecture audio et vidéo et les combiner avec quelques contrôles que nous avons déjà discutés précédemment dans cet article, et tourner le tout en un lecteur multimédia WPF. Le résultat va ressembler à quelque chose comme ceci:

Mais cela est seulement lorsqu'il y a lecture de fichiers audio/MP3. Une fois qu'une vidéo est chargée, l'interface s'agrandit pour montrer le contenu vidéo dans la fenêtre:

Laissez-moi vous dire un mot sur comment cette chose a été construite. À la fin, vous pouvez bien sûr voir le code source entier, disponible pour vous amusez avec.

L'interface

L'interface a été divisée en trois zones verticales: Le haut, où la barre d'outils est située, le milieu, où la vidéo (si un fichier vidéo est chargé) est montré, et le bas, où nous trouvons la barre de statut, une Glissière pour voir et contrôler la progression et une Barre de Progression pour montrer le volume. Tous les contrôles utilisés ici ont été expliqués précédemment dans le didacticiel, alors nous ne nous concentrerons pas trop sur ce sujet.

Remarquez l'utilisation de commandes WPF, plutôt que des événements de clics pour les boutons. Ceci nous permets de réutiliser facilement la fonctionnalité au cas où nous voulons ajouter, par exemple, un menu principal ou un menu de contexte avec quelques unes des même fonctionnalités. Ça nous rend la tâche plus facile aussi pour basculer la fonctionnalité en l'activant ou en la désactivant, dépendant de l'état courant du lecteur.

Aussi veuillez noter que nous avons réglé la propriété Agrandir de l'élément Média à Aucun, et la Fenêtre Grandeur au Mode Contenu à Largeur Et Hauteur. C'est ceci qui conserve la fenêtre à la grandeur minimum requise pour montrer l'interface ainsi que la vidéo, s'il y a lecture vidéo.

Pour montrer le Volume, nous avons utilisé une Barre de Progression dans le coin droit inférieur. Pour le moment, ceci ne permet pas l'utilisateur de contrôler le volume, mais renvoie seulement la propriété Volume sur le contrôle de l'élément du Média, à travers une liaison de données classique. Nous avons conçu un petit truc propre pour laisser l'utilisateur contrôler le volume quand même bien que - plus sur ce sujet ci-bas.

Le code

Dans le code-en arrière, nous réutilisons quelques techniques déjà utilisés dans nos exemples précédents. Par exemple, nous initions une minuterie de répartiteur et nous la laissons faire un tic-tac toutes les secondes, pour le progrès de re-lecture courant dans l'interface. Dans l'événement tic-tac de la minuterie, nous faisons une mise à jour du contrôle Glissière, en réglant Minimum, Maximumet la Valeur courante selon le fichier qui est en lecture, et en branchant sur l'événement Valeur changée sur la glissière, nous utilisons cela pour faire une mise à jour sur l'étiquette qui affiche le progrès de relecture courante en heures, minutes et secondes.

Le contrôle Glissière permet aussi de sauter à une autre partie du fichier, simplement de traînant le "pouce" à un autre endroit. Nous manipulons ceci en appliquant des événements pour Traîner débuté and Traîner complété - le premier pour appliquer une variable ( utilisateur Traîne La Glissière) qui dit à la minuterie de ne pas faire de mise à jour sur la Glissière durant le traînage, et le second pour sauter la partie désignée quand l'utilisateur relâche le bouton de la souris.

Il y a des gestionnaires Peut Exécuter et Exécuté pour les quatre commandes que nous utilisons et particulièrement celles pour Pause et Arrêt sont intéressantes. Étant donné que nous ne pouvons pas obtenir un état courant du contrôle élément Média, nous devons tenir à jour l'état courant nous-mêmes. Ceci se fait avec la variable locale appelée Lecteur multimédia Joue, que nous vérifions régulièrement pour voir si les boutons Pause et Arrêt devraient être activés.

Le dernier petit détail que vous devriez prendre en note est l'événement de la Grille_Molette de la souris. La grille principale couvre la fenêtre entière, alors en souscrivant à cet événement, nous sommes notifiés lorsque l'utilisateur fait défiler la molette. Lorsque ceci se produit, comme un petit truc, on baisse ou on monte le volume, tout dépendant de la direction (nous obtenons cela en regardant la propriété Delta, qui est négative quand on défile vers la bas et positive quand on défile vers le haut). Ceci se voit immédiatement dans l'interface utilisateur, où un contrôle de Barre de progrès est lié à la propriété Volume de l'Élément média.

Le code source au complet

Avec toute la théorie derrière l'exemple décrit, voici le code source complet:

<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;
		}

	}
}

Résumé

La liste du code peut paraître écrasant, mais comme vous pouvez le constater, il y a beaucoup de répétitions dedans. Si vous enlevez cela de l'équation, vous réaliserez bientôt que créer un lecteur multimédia en WPF n'est pas si compliqué! Sentez-vous libre de développer sur cet exemple pour vos propres projets - que diriez-vous d'accomplir une fonctionnalité liste de lecture?


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!