I. Introduction

RAD Studio est un environnement de développement permettant de construire des applications multiplateformes desktop, mobile, multitiers. La dernière version de l'environnement est la version XE3, sortie le XX Août 2012. Cette dernière mouture comporte plusieurs nouveautés, telles que :

  • Metropolis UI permettant de contruire des applications au look Windows 8 pour la VCL et FireMonkey
  • Améliorations apportées au framework FireMonkey
  • Améliorations de la technologie LiveBindings avec notamment l'ajout d'un éditeur visuel
  • Support des bases de données Sqlite pour dbExpress

II. Présentation plateforme FireMonkey

FireMonkey est une plateforme de développement d'applications multiplateformes, permettant de conserver la même base de code et le même look visuel sur toutes les plates formes supportées. A ce jour, elle permet de créer des applications Windows 32 et 64 bits et des applications 32 bits pouvant s'exécuter sur les systèmes Mac OS X 32 ou 64 bits. Le support d'autres environnements est prévu dans les versions futures de la plateforme.

III. Nouveautés de FireMonkey 2

Les changements suivants ont été dans XE3 :

Experts d'application FireMonkey
L'expert d'applications FireMonkey Metropolis UI a été ajouté, permettant de créer des applications de bureau au style Windows 8.
L'expert Applications de bureau FireMonkey a été ajouté et permet de créer au choix des applications FireMonkey HD ou 3D.

Support des actions et des listes d'action
Auparavant supportés uniquement dans la VCL, il est maintenant possible d'utiliser des actions et listes d'action dans son code.

Support du toucher et des mouvements
Il est dorénavant possible de gérer les événement de toucher et de mouvement dans les applications FireMonkey dans Windows et Mac OS X.
Les jeux de mouvement de la VCL sont supportés, mais il n'est pas encore possible de définir des mouvements personnalisés.

Amélioration des styles visuels
Le concepteur de styles bitmap vous aide à créer, éditer et tester les styles FireMonkey aussi bien que VCL.
Les styles Retina du Macbook Pro avec l'affichage Retina.

Zone non-client des fenêtres stylées
Le styling de la bordure des fiches est a présent supporté sur Windows et Mac OS X.

Capture et lecture audio-vidéo
La capture audio et vidéo est maintenant supportée, au travers des classes TCaptureDevice et TCaptureDeviceManager.
La lecture audio et vidéo est possible via les composants TMedia, TMediaPlayer et TMediaPlayerControl.

Améliorations 3D
Un nouveau compilateur de shaders vous permet de créer des shaders natifs pour différentes plates-formes à partir d'une source hlsl. DirectX est utilisé pour créer la version DX9 et DX10 de shaders, et NVideo cg-toolkit pour créer la version ARB (OpenGL asm) et GLSL de shaders.
Il est possible de définir des filtres, des matériaux et le contexte des objets 3D FireMonkey au travers d'un nouveau shader de contexte
Les textures de bitmap ont été remplacés par une nouvelle classe FMX.Types3D.TTexture utilisant la mémoire GPU pour le stockage des données réelles.
Le nouveau système matériel est basé seulement sur les shaders.
Les textures sont correctement importées lors de l'importation des modèles 3D.

Gestion des dispositions des contrôles
De nouvelles disposition en flux et en grille on été ajoutées. La disposition de texte est également supportée.

Possibilité d'ancrer des composants
Il est dorénavant possible d'ancrer un composant sur les bords haut, droite, bas et gauche de son conteneur, comme dans la VCL.

Détecteurs d'emplacements et de mouvements
Un détecteur d'emplacement a été ajouté pour les plates formes Windows et Mac OS X, tandis que le détecteur de mouvements n'est pour le moment disponible que sous Windows.

Support du clavier virtuel
Le clavier virtuel est maintenant supporté dans les applications FireMonkey.

Support de DirectX 10 sur la plate forme Windows

Nous allons nous intéresser plus particulièrement à la classe TMedia, ainsi qu'aux composants qui sont basés sur cette dernière, TMediaPlayer et TMediaPlayerControl

III-A. Classe TMedia

Il s'agit de la classe de base pour l'accès aux fichiers multimédia. C'est une classe abstraite définissant les interfaces à implémenter spécifiquement pour chaque plateforme. Les principales propriétés du fichier multimédia exposées sont :

  • Filename
  • Size
  • Dimension
  • State
  • Duration

Le différents formats de fichier supportés nativement sont ceux de la plate forme cible, à savoir

  • Formats audio :
    • .wma, .mp3, .wav pour Windows
    • .mp3 pour Mac OS
  • Formats vidéo :
    • .avi, .wmv pour Windows
    • .mov, .m4v, .mp4 pour Mac OS

Il est bien sûr possible d'étendre la liste des formats supportés en recensant d'autres codecs à l'aide de la classe TMediaCodecManager.

III-B. Contrôle TMediaPlayer

Le composant non visuel TMediaPlayer permet de lire facilement tous les formats de fichier multimédia supportés. Il expose également les mêmes propriétés du fichier multimédia comme le TMedia, mais dispose également des propriétés FileName et CurrentTime. Ces deux dernières permettent respectivement de spécifier le fichier à lire et la position en cours dans le fichier.

Ce composant permet par exemple, de réaliser un lecteur mp3 avec un minimum de lignes de code. La lecture d'un fichier consistant à renseigner la propriété FileName et à appeler la méthode Play pour commencer la lecture du fichier.

Pour la lecture de fichiers vidéos, il faut associer un autre contrôle au composant afin que l'image puisse être affichée. Il s'agit du contrôle visuel TMediaPlayerControl.

III-C. Contrôle TMediaPlayerControl

Le contrôle TMediaPlayerControl est un composant visuel permettant l'affichage du fichier vidéo en cours de lecture par le composant TMediaPlayer.

Son usage est également des plus simples, puisqu'il suffit de l'associer au contrôle TMediaPlayer pour qu'il affiche la vidéo en cours de lecture par ce dernier.

Ayant ainsi présenté les composants permettant la lecture de fichiers audio et vidéos, nous allons à présent montrer les extraits de code permettant la lecture de fichiers audio ou vidéo.

IV. Lecture d'un fichier audio

La lecture d'un fichier audio est des plus simples, puisqu'il suffit de d'indiquer le fichier à lire et commencer la lecture. L'extrait de code ci-dessous permet de lire un fichier au format mp3.

 
Sélectionnez

procedure TForm2.btnLireClick(Sender: TObject);
begin
  MediaPlayer1.FileName := 'd:\audio\demo.mp3';
  MediaPlayer1.Play();
end;

Pour arrêter la lecture du fichier, c'est tout aussi simple, il suffit d'appeler la méthode Stop du composant.

 
Sélectionnez

procedure TForm2.btnStopClick(Sender: TObject);
begin
  MediaPlayer1.Stop();
end;

V. Lecture d'un fichier vidéo

Le code pour lecture d'un fichier vidéo est totalement identique à celui permettant de lire un fichier audio. La seule chose à faire en plus c'est d'associer un composant TMediaPlayerControl au composant TMediaPlayer. Cela se fait en définissant la propriété MediaPlayer de notre instance de TMediaPlayerControl à une instance d'un TMediaPlayer.

Cela est fait de manière graphique ainsi que le montre la capture écran ci-dessous

liaison du contrôle TMediaPlayerControl au contrôle TMediaPlayer
liaison du contrôle TMediaPlayerControl au contrôle TMediaPlayer

Ensuite la lecture d'un fichier vidéo est un jeu d'enfant. Exemple de code pour démarrer la lecture d'un fichier et pour l'arrêter.

 
Sélectionnez

procedure TForm2.btnLireVideoClick(Sender: TObject);
begin
  MediaPlayer1.FileName := 'd:\video\demo.avi';
  MediaPlayer1.Play();
end;

procedure TForm2.btnStopVideoClick(Sender: TObject);
begin
  MediaPlayer1.Stop();
end;

le résultat

démonstration de lecture vidéo
démonstration

Comme vous avez pu le voir il est très simple de lire des fichiers multimédia à l'aide de ces composants, l'ont pourrait même réaliser très facilement un petit lecteur multimédia, ce que nous allons faire tout de suite.

VI. Application simple de lecture multimédia

VI-A. Objectifs

L'objectif de notre lecteur multimédia sera la possibilité de lire des fichiers audio et vidéo. Les fichiers devront pouvoir être sélectionnés et rajoutés dans une playlist.

Voici ce à quoi ressemblera notre interface au final.

application de lecture multimédia

VI-B. Création du projet

Si l'environnement de développement n'est pas encore ouvert, ouvrez ce dernier, et créez une nouvelle application de bureau FireMonkey.

créer un nouveau projet application de bureau FireMonkey
créer un nouveau projet application de bureau FireMonkey

Dans l'assistant, choisissez l'option Application HD FireMonkey et cliquez sur le bouton OK.

Expert application de bureau FireMonkey
Expert application de bureau FireMonkey

VI-C. Configuration des contrôles

Déposez ensuite des contrôles sur la fiche afin qu'elle ressemble à l'image ci-après. Il s'agit de :

  • 1 TPanel (pnlControls)
  • 3 TButton (btnCharger, btnJouer, btnReinitialiser)
  • 1 TCheckBox (chkLectureAuto)
  • 1 TTrackBar (trbProgress)
  • 1 TMediaPlayer (mp)
  • 1 TMediaPlayerControl (mpc)
  • 1 TTimer (tmrProgress)
  • 1 TOpenDialog (od)
  • 1 TActionList (alControles)
  • 1 TStyleBook (StyleBook1)
contrôles sur le formulaire
contrôles sur le formulaire

Les trois bouton serviront respectivement à :

  1. Ajouter des éléments à la liste de lecture
  2. Démarrer ou arrêter les lecture des fichiers ajoutés
  3. Réinitialiser la liste de lecture

La case à cocher Lecture automatique permettra de commencer la lecture des fichier aussitôt qu'un fichier est sélectionné, ou d'attendre que le bouton Jouer soit pressé.

Le slider permettra d'avoir la position dans le fichier en cours de lecture ou de définir celle-ci. Nous utiliserons les LiveBindings pour définir automatiquement la position de lecture sans écrire le moindre code. Mais pour ce qui est de l'affichage de cette position, nous coderons celle-ci avec un TTimer. Procéder comme suit pour lier la propriété Progress du TTrackBar à la propriété CurrentTime du TMediaPlayer: Faire un clic droit sur le formulaire, et sélectionner l'action Lier visuellement Dans le concepteur LiveBindings qui s'affiche, cliquer sur la propriété Value du Slider et faire glisser vers la propriété CurrentTime du TMediaPlayer.

liaison LiveBindings
liaison LiveBindings

Le TMediaPlayer nous permettra de lire nos fichiers multimédia.

Le TMediaPlayerControl affichera les vidéos lues par le TMediaPlayer.

Le TTimer sera utilisé pour synchroniser la TTrackBar avec la position en cours de lecture du fichier multimédia.

Le TOpenDialog nous servira à sélectionner les fichiers à ajouter à la liste de lecture.

Nos actions "Charger", "Jouer" et "Réinitialiser" seront implémentées à l'aide d'actions du TActionList.

L'apparence finale de notre application sera prise en charger par le composant TStyleBook.

Nous utiliserons également du Visual LiveBinding, ce qui ajoutera automatiquement à notre fiche un composant TBindingList.

VI-D. Choix d'une apparence pour l'application

Modifions l'apparence visuelle de notre application. Pour cela, double cliquer sur le composant TStyleBook, cela a pour effet d'ouvrir l'éditeur de styles FireMonkey. Dans l'éditeur, cliquer sur le bouton "Charger", sélectionner le style "Transparent" comme apparence, puis cliquer sur le bouton "Appliquer et fermer".

Les styles installés avec Delphi se trouvent par défaut sous le chemin "C:\Program Files (x86)\Embarcadero\RAD Studio\10.0\Redist\styles\Fmx" sur un système 64bits, et "C:\Program Files\Embarcadero\RAD Studio\10.0\Redist\styles\Fmx" sur un système 32bits.

VI-E. Ecriture du code

Nous écrirons du code pour gérer nos actions, initialiser notre playlist lors de l'ouverture de la fiche et détruire celle-ci lors de la fermeture de la fiche; nous écrirons également du code pour gérer la progression de la lecture.

La première action est la lecture/pause du fichier multimédia. Si un fichier est en cours de lecture, il doit être mis en pause, sinon il doit reprendre sa lecture. On profite de cette action pour mettre à jour le titre de la fiche.

 
Sélectionnez

procedure TPlayerForm.actJouerExecute(Sender: TObject);
begin
  if mp.State = tmediastate.Playing then
    mp.Stop
  else if mp.State = tmediastate.Stopped then
  begin
    mp.Play;
    Caption := Format('Lecteur multimédia - %s',
      [ExtractFileName(mp.FileName)]);
  end;
end;

Dans le gestionnaire d'événement OnUpdate de l'action, rajouter le code suivant, qui permet de désactiver l'action lorsqu'aucun fichier n'est chargé, et de changer le libellé de l'action selon qu'un fichier est en cours de lecture ou non.

 
Sélectionnez

procedure TPlayerForm.actJouerUpdate(Sender: TObject);
begin
  TAction(Sender).Enabled := mp.Media <> nil;
  if mp.State = tmediastate.Playing then
    TAction(Sender).Caption := 'Pause'
  else if mp.State = tmediastate.Stopped then
    TAction(Sender).Text := 'Jouer';
end;

En ce qui concerne l'action de réinitialisation de la playlist, celle-ci permet tout simplement de vider la liste de lecture, et est évidemment active lorsque la liste n'est pas vide. Ci dessous les extraits de code pour les événement OnExecute et OnUpdate de l'action.

 
Sélectionnez

procedure TPlayerForm.actResetPlayListExecute(Sender: TObject);
begin
  PlayList.Clear;
  IndexCourrant := -1;
end;

procedure TPlayerForm.actResetPlayListUpdate(Sender: TObject);
begin
  TAction(Sender).Enabled := PlayList.Count > 0;
end;

L'action charger permet d'ajouter des fichiers multimédia à notre liste de lecture. Lors de l'ajout de ces fichiers, si la case à cocher "lecture automatique" est cochée, la lecture du premier fichier de la liste commence.

 
Sélectionnez

procedure TPlayerForm.actChargerExecute(Sender: TObject);
var
  s: String;
begin
  // sélection des fichiers
  if od.Execute then
  begin
    if (PlayList.Count = 0) or (IndexCourrant < 0) then
      IndexCourrant := 0;
    for s in od.Files do
      PlayList.Add(s);
    mp.FileName := PlayList[IndexCourrant];
    trbProgress.Max := mp.Duration;
    // lecture automatique au premier chargement ?
    if (chkLectureAuto.IsChecked) and (IndexCourrant = 0) then
    begin
      mp.Play;
      Caption := Format('Lecteur multimédia - %s',
        [ExtractFileName(mp.FileName)]);
    end;
  end;
end;

Lors de la création de notre formulaire, nous initialisons notre liste de lecture, l'index courant et le titre du formulaire. L'objet utilisé pour gérer notre liste est détruit lors de la destruction du formulaire.

 
Sélectionnez

procedure TPlayerForm.FormCreate(Sender: TObject);
begin
  // initialisation de la playlist
  PlayList := TStringList.Create;
  IndexCourrant := -1;
  // titre
  Caption := 'Lecteur multimédia FMX';
end;

procedure TPlayerForm.FormDestroy(Sender: TObject);
begin
  // libération de la playlist
  PlayList.Free;
end;

Le dernier bout de code concerne l'implémentation du gestionnaire d'événements du timer. Ce gestionnaire est appelé à chaque seconde afin de vérifier si la lecture du fichier en cours s'est achevée et par conséquent passer au fichier suivant si tel est le cas. Nous utilisons cette technique car le composant TMediaPlayer ne dispose pas d'événement pouvant nous permettre de savoir quand la lecture en cours est terminée.

 
Sélectionnez

procedure TPlayerForm.tmrProgressTimer(Sender: TObject);
begin
  // passer au fichier suivant ou suspendre la lecture ?
  if (mp.State = tmediastate.Playing) then
  begin
    if (mp.CurrentTime = mp.Duration) then
    begin
      Inc(IndexCourrant);
      if IndexCourrant < PlayList.Count then
      begin
        mp.FileName := PlayList[IndexCourrant];
        trbProgress.Max := mp.Duration;
        mp.Play;
        Caption := Format('Lecteur multimédia - %s',
          [ExtractFileName(mp.FileName)]);
      end
      else
      begin
        mp.Stop;
        trbProgress.Value := 0;
      end;
    end;
  end
  else
  begin
    mp.Stop;
    Caption := 'Lecteur multimédia FMX';
  end;
  // désactivation du livebinding afin de positionner la durée de lecture du fichier
  LinkControlToProperty1.Active := false;
  trbProgress.Value := mp.CurrentTime;
  // réactivation du livebinding
  LinkControlToProperty1.Active := true;
end;

Dans le même événement, nous positionnons également le slider en fonction de la position de lecture du fichier.

VI-F. Test de l'application

Exécuter l'application.

Vérifiez qu'une fois la fenête apparue, seul le bouton Charger est activé, car la liste de lecture est vide.

Charger un ou plusieurs fichiers dans la liste de lecture, si la case "lecture automatique" est cochée, vérifier que la lecture commence automatiquement, sinon cliquer sur le bouton "Jouer".

Vérifier que la position du slider s'adapte à la position de lecture du fichier, vérifier également qu'un positionnement manuel du slider modifie la position de lecture du fichier.

Enfin, mettre en pause et résumer la lecture du fichier.

Si tout fonctionne jusque là, tout est ok, nous avons réussi très facilement à créer un mini lecteur multimédia compatible PC et Mac!

VII. Remarques

Durant la création de l'application, je me suis rendu compte que seuls quelques formats de fichiers peuvent être lus par l'application. Lors du chargement de certains fichiers, un message des plus inexplicites apparaît, avec le nom du fichier et puis plus rien! Quelques recherche sur l'internet m'ont indiqué quels sont les formats reconnus par plateforme, mais il semblerait que la présence de certains codecs soit également nécéssaire pour jouer ces fichiers.

erreur de lecture du fichier
erreur de lecture du fichier

Il semblerait également qu'il soit possible d'étendre la liste des formats reconnus, je rédigerai un autre tutoriel à ce sujet si possible.

VIII. Conclusion

Cet article, nous a permis d'avoir une vision générale des nouveautés du framework FireMonkey 2 avec RAD XE3, notamment ceux concernant la lecture de fichiers multimédia. Nous avons également pu remarquer leur facilité d'utilisation lors de la création de notre mini lecteur multimédia.

La capture audio et vidéo fera le sujet d'un prochain article, où nous verrons de la même manière comment créer une application de capture audio vidéo multiplateforme avec FireMonkey.

IX. Liens utiles

X. Remerciements

Je tiens tout particulièrement à remercier ... pour leur aide tout au long de la rédaction de ce tutoriel.