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

3 respostas
E

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

/**
 * @(#)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();
    	}
    }
    
}

Valeu...

3 Respostas

E

Tentei usar o ProcessBuildr também

/**
 * @(#)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();
    	}
    }
    
}
E

Ninguém?

E

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...

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;
        } 
}
Criado 29 de maio de 2008
Ultima resposta 4 de jun. de 2008
Respostas 3
Participantes 1