Intégration du multimédia à Java avec JMF
[30 mn de lecture - paru le 11/4/2003 - Public : Confirmé]
|
   
|
Auteur
3. Mise en oeuvre
3.1. Objectif
Maintenant que nous avons vu la théorie, nous allons passer à
un exemple un peu plus pratique, car pour l’instant tout ça doit
vous sembler encore assez obscur. Bien sûr, dans un souci de lisibilité
je ne vais pas mettre le source complet du programme (interface etc…)
mais juste les bouts de code intéressants dans l’utilisation de
JMF.
Cette petite application permettra de lire un média
quelconque (audio ou vidéo), et de capturer de la vidéo
à partir d’une webcam et du son à partir d’un micro
en les renvoyant vers l’écran et les haut-parleurs. Il s’agit
donc d’une application de lecture et d’acquisition.
Il y a donc 2 éléments à développer
: la partie principale qui permettra de lire les médias stockés
et de présenter les médias capturés, l’autre est
la partie qui permet de sélectionner les périphériques
de capture que l’application utilisera. C’est par cette seconde
partit que nous commencerons.
3.2. Choix des périphériques de capture
La fenêtre de choix des périphériques se présentera
comme ceci :

Dès que l’on choisit un périphérique audio ou vidéo
dans les listes déroulantes, les listes déroulantes des formats
se mettent à jour pour correspondre au périphérique sélectionné.
Passons un peu au code… (voici les imports à faire et l'ouverture
de la classe...)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import javax.media.*;
import javax.media.format.*;
import javax.media.protocol.*;
import java.util.Vector;
public class ChoixPeriphCapture extends JDialog implements ActionListener, ItemListener {
|
La fonction ChoixPeriphCapture() applique ce que
nous avons vu dans la seconde partie de cette note. Nous utiliserons la fonction
getDeviceList() pour récupérer une liste des périphériques
disponibles. On parcourt ensuite la liste en créant pour chaque périphérique
un objet de type CaptureDeviceObject qui nous permettra de récupérer
les formats disponibles pour le périphérique et du même
coup de déterminer s’il s’agit d’un périphérique
de capture audio ou vidéo grâce à l’opérateur
instanceof AudioFormat ou VideoFormat.
Les listes déroulantes sont ensuite mises à jour.
public ChoixPeriphCapture() {
// Appli
CaptureDeviceInfo cdi = null;
periphs = CaptureDeviceManager.getDeviceList (null);
periphsAudio = new Vector();
periphsVideo = new Vector();
if (periphs != null && periphs.size() > 0) {
int nbPeriphs = periphs.size();
Format[] formats;
for ( int i = 0; i < nbPeriphs; i++) {
cdi = (CaptureDeviceInfo) periphs.elementAt (i);
formats = cdi.getFormats();
for (int j = 0; j < formats.length; j++) {
if (formats[j] instanceof AudioFormat) {
periphsAudio.addElement(cdi);
break;
}
else if (formats[j] instanceof VideoFormat) {
periphsVideo.addElement(cdi);
break;
}
}
}
}
// remplissage des combobox
for (int i = 0; i < periphsAudio.size(); i++) {
cdi = (CaptureDeviceInfo) periphsAudio.elementAt(i);
comboPeriphAudio.addItem(cdi.getName());
}
for (int i = 0; i < periphsVideo.size(); i++) {
cdi = (CaptureDeviceInfo) periphsVideo.elementAt(i);
comboPeriphVideo.addItem(cdi.getName());
}
affichageFormatsAudio();
affichageFormatsVideo();
}
|
Il faut ensuite écrire les fonctions permettant de mettre à jour
les listes déroulantes des formats, des fonctions qui retourneront un
objet CaptureDeviceInfo du périphérique audio ou vidéo
sélectionné (cette fonction sera utile pour la suite du programme),
il faudra aussi d’autres fonctions retournant les périphériques
et formats sélectionnés etc. Nous ne les mettrons pas ici car
elles ne feraient qu’obscurcir cette note inutilement.
3.3. Présentation des médias
Voici un exemple d’interface de lecture banal :

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import javax.media.*;
import javax.media.format.*;
import javax.media.protocol.*;
public class MonSoft extends JFrame implements ActionListener, ControllerListener { |
Déclarations des variables utiles...
Player monPlayer;
CaptureDeviceInfo cdiAudio = null;
CaptureDeviceInfo cdiVideo = null;
String nomPeriphAudio = null;
String nomPeriphVideo = null;
Format formatAudio;
Format formatVideo; |
Intéressons nous à la fonction de capture.
Si aucun objet de type CaptureDeviceInfo n’existe, alors on appelle
la fonction periphEnregistrement() qui utilise ce
que nous avons développé dans la partie précédente.
On crée ensuite un tableau de source de données qui contiendra
une source pour l’audio et une autre pour la vidéo, grâce
au Manager et aux objets de type CaptureDeviceInfo.
Grâce à la méthode createMergingDataSource()
on réunit les 2 sources de données en une seule puis on crée
un lecteur en lui passant en paramètre la nouvelle source de données.
void capture() {
if (cdiAudio == null && cdiVideo == null)
periphEnregistrement();
try {
if (!(cdiAudio == null && cdiVideo == null)) {
DataSource[] dataSources = new DataSource[2];
System.out.println("Creation des sources
de donnees.");
dataSources[0] = Manager.createDataSource(cdiAudio.getLocator());
dataSources[1] = Manager.createDataSource(cdiVideo.getLocator());
DataSource ds = Manager.createMergingDataSource(dataSources);
monPlayer = Manager.createPlayer(ds);
monPlayer.addControllerListener(this);
monPlayer.start();
}
else
System.out.println("CDI non trouve.");
}
catch (Exception e) {
System.out.println(e.toString());
}
} |
Pour la lecture d’un fichier multimédia local, c’est encore
plus simple. Il s’agit de récupérer l’adresse du fichier,
l’utiliser pour créer un MediaLocator que l’on utilisera
à son tour pour créer un lecteur.
void lecture() {
try {
FileDialog fd = new FileDialog(this, "Choisir un fichier", FileDialog.LOAD);
fd.show();
String nomFichier = fd.getDirectory() + fd.getFile();
monPlayer = Manager.createPlayer(new MediaLocator("file:///" + nomFichier));
System.out.println("Ajout du controller listener...");
monPlayer.addControllerListener(this);
System.out.println("Lancement du player...");
monPlayer.start();
}
catch (Exception e) {
System.out.println(e.toString());
} |
Encore une fois, je n’ai présenté ici que les parties du
code qui me semblent importantes pour vous aider à vous faire une idée
de ce à quoi ressemble le développement avec JMF.
|