Publié le 01/02/2012
Auteur fobec
Réseaux sociaux
0 partages
0 tweets
0 plus
4 commentaires

Wav Player avec bouton stop et barre de progression

En novembre, Axel a publié un article sur la lecture de fichiers wav en JAVA. En réponse à la question de Steev, un petit player wav a été développé en se basant sur les fonctions de la class AePlayWave.

VisualPlayerLa class VisualPlayer regroupe les fonctionnalités suivantes:
1. interface graphique pour piloter le Thread de lecture,
2. ajout des fonctions pause et stop,
3. affichage de la progression de lecture.

Au travers de cet exemple, la communication entre un Thread et une interface graphique est abordée. Au lieu du Timer, un Thread 'écouteur' aurait été une variante pour le rafraichissement de la JProgressBar

Thread de lecture d'un avi

Les nouvelles fonctions permettent de mieux piloter le Thread de lecture du fichier wav:
- pause(): mettre en pause ou reprendre la lecture,
- cancel(): abandonner la lecture,
- getProgress(): connaitre la progression de lecture.
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
 
/**
 * Player de sons wav
 * ajout de fonctions à la class AePlayWave
 * http://www.fobec.com/java/1043/jouer-son-musique-format-wav.html
 * -> pause et reprendre la lecture
 * -> arreter la lecture
 * -> calculer la progression de lecture.
 * @author fobec 2011 *
 */
public class WavePlayerThread extends Thread {
 
    private String filename;
    private Position curPosition;
    private final int EXTERNAL_BUFFER_SIZE = 65536; // 16Kb
    private boolean isSuspend = false;
    private boolean isCanceled = false;
    private VisualPlayer frame = null;
    private int readpercent = 0;
 
    enum Position {
 
        LEFT, RIGHT, NORMAL
    };
 
    /**
     * Constructeur: fixer le fichier wav
     * @param wavfile
     */
    public WavePlayerThread(String wavfile) {
        filename = wavfile;
        curPosition = Position.NORMAL;
    }
 
    /**
     * Mettre en pause ou reprendre la lecture
     */
    public synchronized void pause() {
        if (this.isSuspend == true) {
            this.isSuspend = false;
        } else {
            this.isSuspend = true;
        }
        notify();
    }
 
    /**
     * Abandonner la lecture
     */
    public synchronized void cancel() {
        this.isCanceled = true;
        notify();
    }
 
    /**
     * Fixer la Frame VisualPlayer
     * @param visualplayer
     */
    public void setFrame(VisualPlayer visualplayer) {
        this.frame = visualplayer;
    }
 
    /**
     * Connaitre la progression de lecture
     * @return
     */
    public int getProgress() {
        return this.readpercent;
    }
 
    public void run() {
        File soundFile = new File(filename);
        if (!soundFile.exists()) {
            System.err.println("Wave file not found: " filename);
            return;
        }
 
        AudioInputStream audioInputStream = null;
        try {
            audioInputStream = AudioSystem.getAudioInputStream(soundFile);
        } catch (UnsupportedAudioFileException e1) {
            e1.printStackTrace();
            return;
        } catch (IOException e1) {
            e1.printStackTrace();
            return;
        }
 
        AudioFormat format = audioInputStream.getFormat();
        SourceDataLine auline = null;
        DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
 
        try {
            auline = (SourceDataLine) AudioSystem.getLine(info);
            auline.open(format);
        } catch (LineUnavailableException e) {
            e.printStackTrace();
            return;
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }
 
        if (auline.isControlSupported(FloatControl.Type.PAN)) {
            FloatControl pan = (FloatControl) auline.getControl(FloatControl.Type.PAN);
            if (curPosition == Position.RIGHT) {
                pan.setValue(1.0f);
            } else if (curPosition == Position.LEFT) {
                pan.setValue(-1.0f);
            }
        }
 
        auline.start();
        int nBytesRead = 0;
        //longueur du fichier wav
        Long audiolength = soundFile.length();
        int audioreaded = 0;
        byte[] abData = new byte[EXTERNAL_BUFFER_SIZE];
 
        try {
            while (nBytesRead != -1 && this.isCanceled == false) {
                nBytesRead = audioInputStream.read(abData, 0, abData.length);
                if (nBytesRead >= 0) {
                    //calcul de la progression
                    readpercent = Math.round(audioreaded * 100 / audiolength);
                    auline.write(abData, 0, nBytesRead);
                    audioreaded = nBytesRead;
                }
                /**
                 * Annuler la lecture
                 */
                if (this.isCanceled == true) {
                    System.out.print("Thread has been stopped");
                    break;
                }
               /**
                 * Mettre en pause
                 */
                if (this.isSuspend == true) {
                    while (this.isSuspend == true) {
                        try {
                            Thread.sleep(250);
                            if (this.isCanceled == true) {
                                System.out.print("Thread has been stopped");
                                break;
                            }
                        } catch (InterruptedException ex) {
                            Logger.getLogger(WavePlayerThread.class.getName()).log(Level.SEVERE,
 
			 null, ex);
                        }
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            return;
        } finally {
            auline.drain();
            auline.close();
        }
        /**
         * Fin du thread de lecture
         */
        readpercent = 100;
        this.frame.onTerminated();
    }
}

Interface graphique VisualPlayer

Interface minimaliste pour suivre et piloter la lecture d'un wav, à savoir 3 boutons et 1 barre de progression.
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
 
/**
 * Interface grpahique de lecture d'un son wav
 * @author fobec 2011
 */
public class VisualPlayer extends JFrame {
 
    private WavePlayerThread thread = null;
    private JProgressBar jprogressbar = null;
    private JButton jButton_pause = null;
    private String wavefile = "";
    private Timer timer = null;
 
    /**
     * Constructor
     * @param filename
     */
    public VisualPlayer(String filename) {
        this.wavefile = filename;
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400, 75);
        setLocation(200, 200);
        setTitle("Lecture de " filename);
        /**
         * Composant graphique
         */
        JPanel buttonpanel = new JPanel();
        buttonpanel.setLayout(new GridLayout(2, 2, 2, 2));
        JButton jButton_play = new javax.swing.JButton();
        jButton_play.setText("Play");
        jButton_play.addMouseListener(new java.awt.event.MouseAdapter() {
 
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                play();
            }
        });
        jButton_pause = new javax.swing.JButton();
        jButton_pause.setText("Pause");
        jButton_pause.addMouseListener(new java.awt.event.MouseAdapter() {
 
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                pause();
            }
        });
        JButton jButton_stop = new javax.swing.JButton();
        jButton_stop.setText("Stop");
        jButton_stop.addMouseListener(new java.awt.event.MouseAdapter() {
 
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                stop();
            }
        });
        buttonpanel.add(jButton_play);
        buttonpanel.add(jButton_pause);
        buttonpanel.add(jButton_stop);
        getContentPane().add(buttonpanel);
 
        jprogressbar = new JProgressBar();
        jprogressbar.setStringPainted(true);
        buttonpanel.add(jprogressbar);
        /**
         * Timer de suivi de la progression
         */
        this.timer = new Timer(250,
                new ActionListener() {
 
                    public void actionPerformed(ActionEvent event) {
                        updateUI();
                    }
                });
 
        setVisible(true);
    }
 
    /**
     * Lancer la lecture
     */
    public void play() {
        if (this.thread == null) {
            this.thread = new WavePlayerThread(this.wavefile);
            this.thread.setFrame(this);
            this.thread.start();
            this.timer.start();
        }
    }
 
    /**
     * Mettre en pause ou reprendre la lecture
     */
    public void pause() {
        if (this.thread != null) {
            if (jButton_pause.getText().equalsIgnoreCase("Pause")) {
                jButton_pause.setText("Reprendre");
            } else {
                jButton_pause.setText("Pause");
            }
            this.thread.pause();
        }
    }
 
    /**
     * Abandonner la lecture
     */
    public void stop() {
        if (this.thread != null) {
            this.thread.cancel();
            //will call onTerminated
        }
    }
 
    /**
     * Timer event: mettre à jour la progressbar
     */
    public void updateUI() {
        if (this.thread != null) {
            jprogressbar.setValue(this.thread.getProgress());
        }
    }
 
    /**
     * Thread event: fin du thread de lecture
     */
    public void onTerminated() {
        System.out.print("end");
        updateUI();
        this.timer.stop();
        this.thread = null;
        // pour relancer la lecture
        // play();
    }
 
    /**
     * Exemple de lancement de la class
     * @param args
     */
    public static void main(String[] args) {
        VisualPlayer player = new VisualPlayer("C:tambour.wav");
        player.setVisible(true);
    }
}

Ajouter un commentaire

Les champs marqués d'un * sont obligatoires, les adresses emails se sont pas publiées.
avatar Helo

Publié par Helo

le 01/02/2012 à 16:46:40

SVP Comment faire fonctionner le bouton pause ?

avatar fobec

Publié par fobec

le 01/02/2012 à 20:50:11

La boucle de lecture est corrigée et prend en compte l'état pause. Sympa d'avoir signaler l'erreur

avatar Bonjour

Publié par Bonjour

le 08/02/2012 à 09:37:35

Joli travail!
Par contre, savez vous que votre barre de progression s'arrête à un certain pourcentage?

avatar Marcos

Publié par Marcos

le 14/03/2016 à 06:16:46

Bon travail , mais il a quelque chose d'etrange ! Je devais faire l'interface publique de classe avec des variables de position separees Position NORMAL = null; Position RIGHT = null; et position GAUCHE = null; de travailler et meme alors, la barre de progression ne fera que jusqu'a 12% , puis verrouillez est 100% !

A lire aussi

Réseaux sociaux
Présentation de l'article
Catégorie
java - class
Mise a jour
01/02/2012
Visualisation
vu 6965 fois
Public
Internaute
Auteur de la publication
Fobec
Admin
Auteur de 267 articles
|BIO_PSEUDO|
Commentaires récents

Publié par Kal747 dans php5

Merci pour l'info !

Publié par rsuinux dans php5

Merci pour cet article.
Cela m'a debloque pour sqlite3 sur openwrt :)
Cordialement.

Publié par Souti dans php5

Merci pour ce code. Trs utile.

Pour mon cas, il a fallu que j'ajoute une } avant ?> le pour fermer le for each.

Publié par Deepan dans php5

Bonjour,
Merci pour ce tuto qui m'a bien aide.
Je donne ici les modifications apportees pour que cela fonctionne chez moi.

/****************************************
* Ouvrir u...

Publié par eldiablo dans java

Malheureusement, ce code n'est pas correct.
Cette classe accepte des dates comme : "31/00/2011"