Tocando arquivo de som em java

7 respostas
L

Pessoal, estou precisando de um programa que toque um arquivo de som.
Fiz isso:

public class TesteAudio extends JFrame {

	private JButton tocar ,parar; 
	private Container c = getContentPane();
	private JPanel painel ;
	private Audio audio = new Audio();
	Player player = null;

	public TesteAudio() {
		this.setTitle("Player");
		this.setLocation(260,100);
		this.setSize(600,450);
		c.setLayout(null);
		c.setBackground(Color.black);

		tocar = new JButton("play");
		tocar.addActionListener(new AcaoBotao());
		tocar.setBounds(185,370,85,25);

		parar = new JButton("stop");
		parar.addActionListener(new AcaoBotao());
		parar.setBounds(285,370,85,25);


		painel = new JPanel();
		painel.setBorder(BorderFactory.createLineBorder(Color.blue,2));
		painel.setBounds(16,20,550,330);
		
		c.add(tocar);
		c.add(parar);
		
		this.setVisible(true);

	}

	public void adicionarComponente(JPanel p){
		c.add(p);
	}


	private class AcaoBotao implements ActionListener  {

		

		public void actionPerformed(ActionEvent e)  {
			if(e.getSource() == tocar){
				try {
						loadFile loadF = new loadFile();
						URL path = loadF.load(2);											
						audio.setAudio(path);
						player = Manager.createRealizedPlayer(audio.getAudio());
						Component controle = player.getControlPanelComponent() ;
						painel.add(controle,BorderLayout.SOUTH);
						adicionarComponente(painel);
						repaint();						
						player.start();
					

				} 
				catch (NoPlayerException e1) {
					JOptionPane.showMessageDialog(null, "NoPlayerException", "Exception", JOptionPane.ERROR_MESSAGE);
					e1.printStackTrace();
				} 
				
				catch (IOException e2) {
					JOptionPane.showMessageDialog(null, "IOException", "Exception", JOptionPane.ERROR_MESSAGE);					
					e2.printStackTrace();
				} 
				
				catch (CannotRealizeException e3) {
					JOptionPane.showMessageDialog(null, "CannotRealizeException", "Exception", JOptionPane.ERROR_MESSAGE);					
					e3.printStackTrace();
				}
			}

			if(e.getSource() == parar){				
				try{
					player.stop();
				}
				catch(Exception exc){
					JOptionPane.showMessageDialog(null, "Nenhum arquivo está sendo tocado", "Error", JOptionPane.ERROR_MESSAGE);
				}
			}

		}
	}

	public static void main(String arg[]){
		TesteAudio t = new TesteAudio();
		t.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

A classe loadFile é a seguinte:

public class loadFile{ public URL load(int selectionMode){ JOptionPane.showMessageDialog(null, "Passou por aqui"); JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(selectionMode); int result = chooser.showOpenDialog(null); if (result == JFileChooser.CANCEL_OPTION){ return null; } else{ JFileChooser file = new JFileChooser(); URL path = null; try { path = file.getSelectedFile().toURL(); } catch (MalformedURLException e) { e.printStackTrace(); } return path; } } }

E a classe Audio:

public class Audio extends JPanel { 
	private URL audio = null ;   
	public URL getAudio() {  
		return audio;  
	}  

	public void setAudio(URL audio) {
		this.audio = audio;  
	}  
}

Mas nao funciona.
clico em play, ele abre o filechooser mas não toca o arquivo que eu escolho.
Alguém poderia me ajudar?

7 Respostas

V

Se seu intuito é só tocar uma arquivo, de maneira simples, dê uma pesquisada na classe AudioClip.

Se você precisa de mais poder, como manipular som, tocar sons muito rapidamente quase sem atraso, etc, então, manipule diretamente as classes do java.

Eu fiz um pequeno framework para isso, quando implementei o Vikanoid. Baixe os fontes aqui e dê uma olhada. Está no projeto JGF, no pacote sound. E no projeto Vikanoid você pode ver como usa.

K

Esse tópico esta parado por alguns anos, mas achei um metodo que faz tocar audio .wav no java. É difícil achar exemplo na internet que funcione de primeira, certo? Comigo foi na lata...funcionou na primeira, um milagre!!! Aqui vai o link...é só copiar o método e colocar o endereço físico do seu audio.

http://www.anyexample.com/programming/java/java_play_wav_sound_file.xml

obs: funcionou bem pra pois precisava chamar um som toda vez que um método java específico fosse acionado...

import java.io.File; 
import java.io.IOException; 
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; 
 
public class AePlayWave extends Thread { 
 
    private String filename;
 
    private Position curPosition;
 
    private final int EXTERNAL_BUFFER_SIZE = 524288; // 128Kb 
 
    enum Position { 
        LEFT, RIGHT, NORMAL
    };
 
    public AePlayWave(String wavfile) { 
        filename = wavfile;
        curPosition = Position.NORMAL;
    } 
 
    public AePlayWave(String wavfile, Position p) { 
        filename = wavfile;
        curPosition = p;
    } 
 
    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;
        byte[] abData = new byte[EXTERNAL_BUFFER_SIZE];
 
        try { 
            while (nBytesRead != -1) { 
                nBytesRead = audioInputStream.read(abData, 0, abData.length);
                if (nBytesRead >= 0) 
                    auline.write(abData, 0, nBytesRead);
            } 
        } catch (IOException e) { 
            e.printStackTrace();
            return;
        } finally { 
            auline.drain();
            auline.close();
        } 
 
    } 
}
A

kalindii:
Esse tópico esta parado por alguns anos, mas achei um metodo que faz tocar audio .wav no java. É difícil achar exemplo na internet que funcione de primeira, certo? Comigo foi na lata…funcionou na primeira, um milagre!!! Aqui vai o link…é só copiar o método e colocar o endereço físico do seu audio.

http://www.anyexample.com/programming/java/java_play_wav_sound_file.xml

obs: funcionou bem pra pois precisava chamar um som toda vez que um método java específico fosse acionado…

kalindii funcionou perfeitamente e o melhor… o código estava completinho… valeu pela dica!!

K

Ótimo que ajudou você :wink:

L

Muito bom o link da biblioteca de reprodução de audio do kalindii, VALEU mesmo!!!

G

Eis uma classe mais enxuta que funciona, uso ela nos games que eu faço:

public class Player{  
  
    private Clip clip;  
    private AudioInputStream audioIn;  
  
     public void playWav(File wav) {  
        try {             
            audioIn = AudioSystem.getAudioInputStream(new BufferedInputStream(new FileInputStream(wav)));              
            clip = AudioSystem.getClip();              
            clip.open(audioIn);  
            clip.start();  
            clip.loop(Clip.LOOP_CONTINUOUSLY);//comente essa linha caso não deseje um loop  
        } catch (Exception ex) {  
            ex.printStackTrace();  
        }  
    }  
  
    public void stopWav() {  
        try {  
            clip.stop();  
            audioIn.close();  
        } catch (Exception ex) {  
            ex.printStackTrace();  
        }  
    }  
}

Se for tocar mp3 então eu uso o JLayer (http://www.javazoom.net/javalayer/javalayer.html).
Uma vez adicionado o jar dele, pode-se fazer assim:

public void playMp3(final InputStream input) {  
        try {  
            new Thread() {  //ou implemente sua Thread numa classe separada se desejar
                public void run() {  
                    try {                          
                        BufferedInputStream bis = new BufferedInputStream(input);  
                        Player player = new Player(bis);  
                        player.play();  
                        player.close();  
                        bis.close();  
                    } catch (Exception e) {  
                        e.printStackTrace();  
                    }  
                }  
            }.start();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }

No caso do JLayer tem que abrir uma Thread senão trava a execução do programa até a musica acabar.

Em anexo está um player que eu fiz para tocar sons .wav em loop.
Também em anexo está um som que eu fiz usando o Linux MultiMedia Studio (lmms) para um game que estou desenvolvendo.

Use esse som para testar o loop, o resultado fica legal.
O código que usei neste player para tocar os .wav é o mesmo que descrevi acima.

Grande abraço

G

Desculpe ressuscitar este tópico, mas estou apanhando para conseguir tocar um som pelo player. Eu estou usando o exemplo do Gustavo Marques para *.wav.

Funcionou quando eu passo uma String com o caminho do arquivo para o construir o argumento File Wav do método play, mas isso me força a sempre passart o caminho inteiro para o método. Eu quero usar o getresource para poder carregar os arquivos direto do JAR mas estou apanhando. Já testei vários códigos que encontrei na internet. Alguns o eclipse mostra o erro, outros não mostra erro nehum mas também não executa o wav.

O que vcs sugerem para eu passar para o método playWav(File wav) do exemplo do Gustavo Marques o parâmetro direto do getresource?
Notei que o get resource retorna uma URL que não consigo passar para File.

Criado 19 de junho de 2007
Ultima resposta 7 de abr. de 2015
Respostas 7
Participantes 7