Chamada nativa à biblioteca nativa - o software Java não termina a execução

Olá…

Estou desenvolvendo uma aplicação que recebe um vídeo em um formato qualquer e o converte para o formato MPEG-1 (para que eu possa transmití-lo via RTP com a JMF). Para realizar esta conversão estou usando uma biblioteca nativa chamada FFMPEG (é provável que vários de vocês já tenham ouvido falar). Todavia, após a chamada nativa, minha aplicação fica parada e nunca chega ao final da execução. Abro o gerenciador de tarefas do Windows XP quando estou executando e posso ver meu processo Java e um processo ffmpeg rodando…O que eu fiz de errado? Outra dúvida, a forma que usei para capturar a saída do processo nativo está correta?

Abaixo segue o código da aplicação. Eu ia anexar a biblioteca também, mas ela ultrapassa o limite máximo de tamanho

[code]/**

  • @(#)Converte.java
  • @author
  • @version 1.00 2008/5/29
    */
    import java.io.File;
    import java.io.BufferedReader;
    import java.io.InputStreamReader;

public class Converte
{
private static final String caminhoFFMPEG = “C:\ffmpeg\ffmpeg.exe”;
//private static final String caminhoFFMPEG = “ffmpeg”;
private static final String diretorioDeVideosConvertidos = System.getProperty(“user.dir”)+"\videos convertidos\";

public Converte() 
{
	File diretorio = new File(diretorioDeVideosConvertidos);
	if(!diretorio.exists())
	{
		diretorio.mkdir();
	}
	
	//System.out.println(diretorio.getPath());
	
	
}

public String paraMPEG1(String caminhoVideo)throws Exception
{
	String retorno = "";
	String linha = "";
	String nomeVideoNovaExtensao = caminhoVideo.substring(caminhoVideo.lastIndexOf("\\"),caminhoVideo.length())+".mpeg";
	Process convertendo = Runtime.getRuntime().exec( caminhoFFMPEG+" -i "+caminhoVideo+" -target mpeg "+diretorioDeVideosConvertidos+"\\"+nomeVideoNovaExtensao);
	
	BufferedReader input = new BufferedReader(new InputStreamReader(convertendo.getInputStream()));
	
  	while ((linha = input.readLine()) != null) 
    {  
         retorno += linha;  
    }
    convertendo.waitFor();
    return retorno;   
}


public static void main(String[] s)
{
	Converte converte = new Converte();
	String resultado = "";
	try
	{
		resultado = converte.paraMPEG1("C:\\teste.mpg");
		System.out.println(resultado);
	}
	catch(Exception ex)
	{
		ex.printStackTrace();
	}
}

}[/code]

Valeu…

Tentei usar o ProcessBuildr também

[code]/**

  • @(#)Converte.java
  • @author
  • @version 1.00 2008/5/29
    */
    import java.io.File;
    import java.io.BufferedReader;
    import java.io.InputStreamReader;

public class Converte1
{
private static final String caminhoFFMPEG = “C:\ffmpeg\ffmpeg.exe”;
//private static final String caminhoFFMPEG = “ffmpeg”;
private static final String diretorioDeVideosConvertidos = System.getProperty(“user.dir”)+"\videos convertidos\";

public Converte1() 
{
	File diretorio = new File(diretorioDeVideosConvertidos);
	if(!diretorio.exists())
	{
		diretorio.mkdir();
	}
	
	//System.out.println(diretorio.getPath());
	
	
}

public String paraMPEG1(String caminhoVideo)throws Exception
{
	String retorno = "";
	String linha = "";
	String nomeVideoNovaExtensao = caminhoVideo.substring(caminhoVideo.lastIndexOf("\\"),caminhoVideo.length())+".mpeg";
	ProcessBuilder convertendo = new ProcessBuilder( caminhoFFMPEG+" -i "+caminhoVideo+" -target mpeg "+diretorioDeVideosConvertidos+"\\"+nomeVideoNovaExtensao);
	Process processo = convertendo.start(); 
	
	BufferedReader input = new BufferedReader(new InputStreamReader(processo.getInputStream()));
	
  	while ((linha = input.readLine()) != null) 
    {  
         retorno += linha;  
    }
    //convertendo.waitFor();
    input.close();
    return retorno;   
}


public static void main(String[] s)
{
	Converte1 converte = new Converte1();
	String resultado = "";
	try
	{
		resultado = converte.paraMPEG1("C:\\teste.mpg");
		System.out.println(resultado);
	}
	catch(Exception ex)
	{
		ex.printStackTrace();
	}
}

}[/code]

Ninguém?

Consegui resolver satisfatoriamente…O código segue abaixo. É bom ter em em mente que o código está sujão, porque é protótipo de teste. É interessante assimilar a lógica e aplicar no contexto particular da cada um…

[code]import java.io.*;

public class Converte3 {

public Converte3() 
{
}

public static void main(String[] s)
{
	try
	{
		String arquivoASerVonvertido = "c:\\teste.mpg";
    	String arquivoDestino = "c:\\conv.mpg";
    	
    	Converte3 converte = new Converte3();
    	boolean sucesso = converte.converte(arquivoASerVonvertido,arquivoDestino);
    	if(sucesso)
    	{
    		System.out.println("Convertido com sucesso");
    	}
    	else
    	{
    		System.out.println("Não foi possível converter o arquivo");
    	}
	}
	catch(Exception ex)
	{
		ex.printStackTrace();
	}
}

public boolean converte(String arquivoAlvo,String arquivoDestino)throws Exception
{
	 String FFMPEG = "C:\\ffmpeg\\ffmpeg.exe";
	 int valorDeSaida = -1;
	 
	 //String arquivoASerVonvertido = "C:\\Arquivos de teste\\videos\\Pixar - Ice Age Extra.mpg";
	 String comando = FFMPEG+" -i "+arquivoAlvo+" -f mpeg "+arquivoDestino+"\n";
	 
	 Process processoDeConversao = Runtime.getRuntime().exec(comando);
	 valorDeSaida = doWaitFor(processoDeConversao); 
	 	
	 //System.out.println("Resultado: "+valorDeSaida+"");
	 if(valorDeSaida==0)
	 {
	 	return true;
	 }
	 else
	 {
	 	return false;
	 }
}

private int doWaitFor(Process p) 
{

	int valorDeSaida = -1; // returned to caller when p is terminado

	try 
	{
    InputStream in = p.getInputStream();
    InputStream err = p.getErrorStream();
    boolean terminado = false; // Set to true when p is terminado

    while (!terminado) 
    {

          try 
          {
	            while (in.available() > 0) 
	            {
	              // Print the output of our system call
	              Character c = new Character((char) in.read());
	              System.out.print(c);
	            }
	
	            while (err.available() > 0) 
	            {
	              // Print the output of our system call
	              Character c = new Character((char) err.read());
	              System.out.print(c);
	            }
	
	            valorDeSaida = p.exitValue();
	            terminado = true;
          } 
          catch (IllegalThreadStateException e) 
          {
           // processoDeConversao ainda não terminou;
           // Thread espera
          	Thread.currentThread().sleep(500);
          }
    }

    } 
    catch (Exception e) 
    {
      // Erro inesperado
      System.err.println("doWaitFor(): unexpected exception - "
                                    + e.getMessage());
    }
      //Retorna a saída do processo nativo: se der 0 tudo certo
      return valorDeSaida;
    } 

}[/code]