2012-02-19 17 views
6

* .movファイルを* .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:パイプが閉じています」というエラーが発生します。誰かが私を助けてくれますか? は(WindowsおよびRedHatのLinuxの場合)、このトランスコーディングを行うことができます任意のJava APIがある代わりにあれば、それはそのように動作するつもりはない

おかげ

答えて

3

非常に参考になります。

JAVEは単にあなたがして、基本的fmpegを呼び出し、設定を渡すためにJAVEを伝えるターゲットエンコーディング、ラウドネス、などと のように、パラメータを指定されffmpegの実行ファイル、 へのラッパーとして動作することを忘れないでください、あなたが使用して に入りましたffmpeg実行可能ファイルへのパラメータとしてのJavaメソッド。

このステップでは、指定した設定は、今、あなたはそこにあるとのFileInputStream のような、少なくともいくつかの、入力ストリームは、何らかの形で直列化可能であることを主張する可能性がffmpegの実行可能

に既知の 1.シリアライズ 2.あることが必要です に対応する低レベルのFile Descriptorですが、ByteArrayInputStreamを考慮してください。 Javaが各プラットフォームでJavaを実装していますが、どういうわけか、 対応するFile Descriptorが存在します。

しかしながら、重要な点は、ffmpeg実行ファイルは入力ストリームのJavaオブジェクトが何であるか分からず、 はわからないことです。 (少なくともPOSIXシステムでは) の整数値(ファイル記述子E)をとり、そこからデータを読み取ろうとします。しかし、 がファイル記述子を使用しているときに、多くのことが間違っている可能性があります。たとえば、実際にソケットから読み取られたデータを表している場合は、ファイルがある場合は であるかどうかを調べることができます。

嬉しいことに、Posixシステムでは、すべてのプロセスに対して少なくとも3つのファイルディスクリプタ、 があります.STDIN、STDOUT、STDERRです。これは、あるプロセスから別のプロセスへのパイプ入出力を で行うことができるという概念に対応しています。 Windows上でこれがどういうふうに動作するのか分かりませんが、OSXやLinuxではffmpeg実行可能ファイルにデータをパイプすることができます。この は実際には、ffmpegにSTDINファイル記述子からの読み込みを指示することを意味します。

悲しいことに、JAVEはffmpegのこの特定の機能を実装していません。すなわち、 メソッドがありません。データがffmpegs STDINにパイプされます。

FWIW。あなたは、いくつかのネイティブ(C/C++)のコードを書いて、Javaオブジェクトをダウン渡すことができる「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 を参照してください。

関連する問題