2012-02-19 5 views
6

* .mov 파일을 ffmpeg를 호출하는 JAVE를 사용하여 * .mp4 파일로 변환하려고합니다. 입력 파일과 출력 파일은 모두 InputStream 및 OutputStream 형식입니다. 즉, ffmpeg에 대해 InputStream 및 OutputStream을 -i 및 -y parematers로 전달해야 함을 의미합니다. 어떻게하면됩니까?FileInputStream 및 FileOutputStream을 ffmpeg에 전달하여 (JAVE-Java 오디오 비디오 인코딩 사용)

//Read a movfile.mov converted into a FileInputStream 
    InputStream fileInputStream = getFileInputStream(); 
    OutputStream fileOutputStream = new FileOutputStrea(outputMP4File) //Output   
    Process p = Runtime.exec("ffmpeg -i - -y -"); 
    InputStream pInStrm = p.getInputStream(); 
    OutputStream pOutStrm = p.getOutputStream(); 
    int vin = 0, vout = 0; 

    Thread read = new Thread() { 
     byte[] buff = new byte[4096]; 
      void run() { 
      while ((vin=fileInputStream.read(buf))!=-1) { 
       pOutStrm.write(buf, 0, vin); 
      } 
     } 
     }; read.start(); 

    Thread write = new Thread() { 
     byte[] buff = new byte[4096]; 
     void run() { 
      while ((vout=pInStrm.read(buf))!=-1) { 
       fileOutputStream.write(buf, 0, vout); 
      } 
     } 
     }; write.start(); 

하지만 계속 "IOException : pipe is closed"오류가 발생합니다. 누군가 나를 도울 수 있을까요? 는 (Windows 및 레드햇 리눅스)이 트랜스 코딩을 할 수있는 자바 API가 또는 경우, 그것은 그런 식으로 작동하지 않을

감사

답변

3

매우 도움이 될 것입니다.

JAVE은 단지 당신이 다음 기본적으로 fmpeg를 호출하고 설정을 전달하는 JAVE에게 대상 인코딩, 음의 크기, 등을 과 같은 매개 변수를 제공 인 FFmpeg을 실행, 에 대한 래퍼 역할을 기억하십시오, 당신은 사용 를 입력 Java 메소드를 ffmpeg 실행 파일의 매개 변수로 사용합니다.

이 단계를 설정, 당신은 지정해야합니다 1. 직렬화 2.이 있으므로 FileInputStream에 같은 적어도 일부에는 InputStream는, 어떻게 든 직렬화 것을 주장 할 수는 FFmpeg 실행 이제

로 알려진 이 InputStream에 에 해당하지만 ByteArrayInputStream을 고려한 낮은 수준의 파일 설명자 Java는 각 플랫폼에서 구현되지만 어쨌든 의심 스럽지만 해당 파일 설명자가 있음을 알 수 있습니다.

그러나 중요한 점은 ffmpeg 실행 파일이 InputStream 유형의 Java 객체가 무엇인지 모르는 것이고 이 무엇인지 모르기 때문입니다. (적어도 posix 시스템에서) 수행 할 수있는 최선의 방법은 정수 번호 (File DescriptorE) 을 가져 와서 데이터를 읽는 것입니다. 그러나 파일 설명자로 작업 할 때 많은 일이 잘못 될 수 있습니다. 예를 들어 실제로는 소켓에서 읽은 데이터를 나타낼 경우 파일이거나, 그렇지 않은 파일 인 경우 검색 가능할 수 있습니다.

Posix 시스템에서 모든 프로세스에 대해 STDIN, STDOUT 및 STDERR 인 파일 설명자가 적어도 3 개 있습니다 ( ). 이것은 하나의 프로세스에서 다른 프로세스로의 파이프 입/출력을 할 수있는 개념에 해당합니다. Windows에서이 작업이 작동하는지 또는 작동하는지 모르겠지만 OSX 또는 Linux에서는 데이터를 ffmpeg 실행 파일로 파이프 할 수 있습니다. 이 실제로 ffmpeg STDIN 파일 설명자에서 읽을 수 있음을 의미합니다.

슬프게도 JAVE는 ffmpeg의 특정 기능을 구현하지 않습니다. 즉, 메서드가 없으므로 데이터를 ffmpegs STDIN으로 파이프합니다.

FWIW.당신은 어떤 네이티브 (C/C++) 코드를 작성하고 자바 객체를 전달할 수 'DecodeFeed', 보유 둘 모두의 InputStream 및 OutputStream에

네이티브 코드 JNI (http://en.wikipedia.org/wiki/Java_Native_Interface)를 사용하여, 당신은 포함 할 수있다 작성해야 ffmpeg 소스를 사용하고 을 사용하여 DecodeFeed.in에서 읽은 입력을 디코딩/트랜스 코드 한 다음 DecodeFeed.out에 다시 씁니다.

Android 프로젝트에서이 작업을 수행하고 있습니다. 참조 할 수 있습니다. https://github.com/fscz/FFmpeg-Android

또는 JAVE를 포크하여이 기능을 직접 구현할 수 있습니다. Java는 Runtime.exec를 호출하여 실행 파일을 실행할 수있는 방법을 제공합니다. 이 호출은 이 Process.getOutputStream을 제공하는 Process 클래스의 인스턴스를 리턴합니다. 이 Outputstream에 쓰면 은 방금 생성 한 프로세스의 STDIN에 실제로 씁니다.

프로세스에 알리고 쓰는 방법에 대한 문서는 http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html 을 참조하십시오.

ffmpeg에 대해 을 사용할 수있는 명령 줄 옵션 (STDIN에서 읽기 포함)에 대해서는 http://ffmpeg.org/ffmpeg.html를 참조하십시오.