[resolvido]Media player: Quando toca música a janela some e só volta quando a música acaba

7 respostas
brunofin

Olá! Estou fazendo um programa para tocar arquivos em mp3. Baixei a biblioteca JavaZoom para tocar as músicas e consegui fazer tudo funcionar. Mas eu tenho uma dúvida. O programa fica parado enquanto a função play() não terminar. Sei que esse é o comportamento que se deveria esperar mas eu quero que o programa continue sem esperar a função terminar, daí eu posso colocar uma janela depois com opção de pausar, resumir ou parar a música. Tem como fazer isso? Agradeço desde já!

Esse é o código do programa:

package som;
import javazoom.jl.decoder.*;
import javazoom.jl.player.*;
import javax.swing.JOptionPane;
import java.io.*;


public class Main{
    public static int menu(){
        // cria um menu para escolher uma opção.
        int opt;
        do{
            opt = Integer.parseInt(
                    JOptionPane.showInputDialog(
                    "1 - Tocar música.\n" +
                    "2 - Listar arquivos em um diretório.\n" +
                    "3 - Sair."));
        } while((opt < 1) || (opt > 3));
        return opt;
    }
    
    public static String getPath(){
        // retorna um diretório digitado pelo usuário
        String PATH;
        PATH = JOptionPane.showInputDialog(
                "Digite um diretório:");
        return PATH;
    }
    
    public static String getFullPath(){
        // retorna o diretório e o nome do arquivo.
        String fullPath;
        fullPath = getPath() + getFile();
        return fullPath;
    }
    
    public static String getFile(){
        // retorna um nome de arquivo digitado pelo usuário.
        String filename;
        filename = JOptionPane.showInputDialog(
                "Digite um nome de arquivo");
        return filename;
    }
    
    public static void tocar(String path) throws JavaLayerException{
        // toca uma música
        try{
            InputStream in = (InputStream)
                    (new FileInputStream (path));
            Player p = new Player(in);
            p.play();    // <- eu quero que o programa não espere a finalização dessa função
            // aqui eu chamaria outra JOptionPane com a opção de pausa, resumir ou parar.
            p.close();
            in.close();
        } catch(IOException e){
            e.printStackTrace();
        }
    }
    
    public static void ls() throws IOException{
        // lista arquivos e pastas em determinado diretório.
        String saida = "";
        String path = getPath();
        File files = new File(path);
        String[] list;
        list = files.list();
        for(int i = 0; i < list.length; i++){
            files = new File(path + list[i]);
            if(files.isFile())
                if(!files.isHidden())
                    saida += list[i] + "\n";
            if(files.isDirectory()){
                if(!files.isHidden())
                    saida += "[+] " + list[i] + "\n";
            }
        }
        JOptionPane.showMessageDialog(null, saida);
    }
    
    public static void main(String[] args){
        int opt;
        do{
            opt = menu();
            switch( opt ){
                case 1:
                    try{
                        tocar( getFullPath() );
                    } catch(JavaLayerException e){
                        e.printStackTrace();
                    }
                    break;
                    
                case 2:
                    try{
                        ls();
                    } catch(IOException e){
                        e.printStackTrace();
                    }
                    break;
                    
                default:    
            }
        } while(opt != 3);
    }
}

7 Respostas

Marcelo_FS

Cria uma thread nova pra tocar… e deixa o controle de play/pause na thread Main.

Marky.Vasconcelos

Eu lembro de ter feito a muito tempo um player também… tanto tempo que perdi os sources…
Mas a solução é apenas deixar a parte que toca em outra Thread.

thegoergen

Na sua função tocar você cria outra Thread:

public static void tocar(String path) throws JavaLayerException{  
         // toca uma música  
         try{  
             InputStream in = (InputStream)  
                     (new FileInputStream (path));  
             Player p = new Player(in);  
new Thread(){
public void run(){
            // Como está em outra Thread, vai executar isso aqui e vai seguir o baile (hehehe)
             p.play(); 
}   
}.start();
             // aqui eu chamaria outra JOptionPane com a opção de pausa, resumir ou parar.  
             p.close();  
             in.close();  
         } catch(IOException e){  
             e.printStackTrace();  
         }  
     }
Marcelo_FS

thegoergen:
Na sua função tocar você cria outra Thread:

public static void tocar(String path) throws JavaLayerException{ // toca uma música try{ InputStream in = (InputStream) (new FileInputStream (path)); Player p = new Player(in); new Thread(){ public void run(){ // Como está em outra Thread, vai executar isso aqui e vai seguir o baile (hehehe) p.play(); } }.start(); // aqui eu chamaria outra JOptionPane com a opção de pausa, resumir ou parar. p.close(); in.close(); } catch(IOException e){ e.printStackTrace(); } }

p.close();” e “in.close();” tem que ficar dentro da thread, depois da chamada ao “play()”, ou você encerrará sua música antes de conseguir tocar alguma coisa audível… :roll:

marcosharbs

Thread é a solução, qdo executar o método play() faça ele abrir uma thread assim seu problema será resolvido.

brunofin

Olá! Muito obrigado pela resposta rápida. Eu ainda não cheguei nessa parte na aula de programação da faculdade, por isso ainda não conhecia esse comando. Vou dar uma pesquisada sobre ele, parece bem interessante. Muito obrigado pela ajuda!

thegoergen

MarceloS:
thegoergen:
Na sua função tocar você cria outra Thread:

public static void tocar(String path) throws JavaLayerException{ // toca uma música try{ InputStream in = (InputStream) (new FileInputStream (path)); Player p = new Player(in); new Thread(){ public void run(){ // Como está em outra Thread, vai executar isso aqui e vai seguir o baile (hehehe) p.play(); } }.start(); // aqui eu chamaria outra JOptionPane com a opção de pausa, resumir ou parar. p.close(); in.close(); } catch(IOException e){ e.printStackTrace(); } }

p.close();” e “in.close();” tem que ficar dentro da thread, depois da chamada ao “play()”, ou você encerrará sua música antes de conseguir tocar alguma coisa audível… :roll:

É verdade, não tinha reparado… :oops:

Criado 30 de dezembro de 2008
Ultima resposta 30 de dez. de 2008
Respostas 7
Participantes 5