プログラムでビデオを作成できるJavaライブラリをお勧めしますか?具体的には、次のようになります。
誰かが何かを推薦できますか?画像とサウンドのミキシングについては、一連のフレームを使用するものを使用し、フレームごとに、そのフレームに関連付けられた非圧縮サウンドデータの生のバイトを提供する必要がありました。
追伸Java Media Frameworkが上記を達成するための呼び出しを持っている場合、それ自体が「サードパーティライブラリ」である必要はありませんが、私の大ざっぱな記憶から、私はそれを感じていますt。
以下のコードを使用して、pure Javaで要件リストの項目1、2、および4を正常に実行しました。それは一見の価値があり、おそらく#3を含める方法を理解することができます。
http://www.randelshofer.ch/blog/2010/10/writing-quicktime-movies-in-pure-Java/
マルチメディアファイルをある形式から別の形式に変換できるffmpegというツールを見つけました。 ffmpegにはlibhfilterと呼ばれるフィルターがあり、vhookの代わりに使用して、ビデオとオーディオをデコーダーとエンコーダーの間で変更または検査できます。生のフレームを入力してビデオを生成することは可能だと思います。私は任意のJava ffmpegの実装について調査し、 "Getting Started with FFMPEG-Java" というタイトルのページを見つけましたJava JNAを使用したFFMPEGのラッパー。
純粋なJava JCodecと呼ばれるコーデックライブラリを試すことができます。
非常に基本的なH.264(AVC)エンコーダとMP4マルチプレクサを備えています。以下は、サンプルから取得した完全なサンプルコード TranscodeMain です。
private static void png2avc(String pattern, String out) throws IOException {
FileChannel sink = null;
try {
sink = new FileOutputStream(new File(out)).getChannel();
H264Encoder encoder = new H264Encoder();
RgbToYuv420 transform = new RgbToYuv420(0, 0);
int i;
for (i = 0; i < 10000; i++) {
File nextImg = new File(String.format(pattern, i));
if (!nextImg.exists())
continue;
BufferedImage rgb = ImageIO.read(nextImg);
Picture yuv = Picture.create(rgb.getWidth(), rgb.getHeight(), ColorSpace.YUV420);
transform.transform(AWTUtil.fromBufferedImage(rgb), yuv);
ByteBuffer buf = ByteBuffer.allocate(rgb.getWidth() * rgb.getHeight() * 3);
ByteBuffer ff = encoder.encodeFrame(buf, yuv);
sink.write(ff);
}
if (i == 1) {
System.out.println("Image sequence not found");
return;
}
} finally {
if (sink != null)
sink.close();
}
}
このサンプルはより洗練されており、エンコードされたフレームのMP4ファイルへの多重化を実際に示しています。
private static void prores2avc(String in, String out, ProresDecoder decoder, RateControl rc) throws IOException {
SeekableByteChannel sink = null;
SeekableByteChannel source = null;
try {
sink = writableFileChannel(out);
source = readableFileChannel(in);
MP4Demuxer demux = new MP4Demuxer(source);
MP4Muxer muxer = new MP4Muxer(sink, Brand.MOV);
Transform transform = new Yuv422pToYuv420p(0, 2);
H264Encoder encoder = new H264Encoder(rc);
MP4DemuxerTrack inTrack = demux.getVideoTrack();
CompressedTrack outTrack = muxer.addTrackForCompressed(TrackType.VIDEO, (int) inTrack.getTimescale());
VideoSampleEntry ine = (VideoSampleEntry) inTrack.getSampleEntries()[0];
Picture target1 = Picture.create(ine.getWidth(), ine.getHeight(), ColorSpace.YUV422_10);
Picture target2 = null;
ByteBuffer _out = ByteBuffer.allocate(ine.getWidth() * ine.getHeight() * 6);
ArrayList<ByteBuffer> spsList = new ArrayList<ByteBuffer>();
ArrayList<ByteBuffer> ppsList = new ArrayList<ByteBuffer>();
Packet inFrame;
int totalFrames = (int) inTrack.getFrameCount();
long start = System.currentTimeMillis();
for (int i = 0; (inFrame = inTrack.getFrames(1)) != null && i < 100; i++) {
Picture dec = decoder.decodeFrame(inFrame.getData(), target1.getData());
if (target2 == null) {
target2 = Picture.create(dec.getWidth(), dec.getHeight(), ColorSpace.YUV420);
}
transform.transform(dec, target2);
_out.clear();
ByteBuffer result = encoder.encodeFrame(_out, target2);
if (rc instanceof ConstantRateControl) {
int mbWidth = (dec.getWidth() + 15) >> 4;
int mbHeight = (dec.getHeight() + 15) >> 4;
result.limit(((ConstantRateControl) rc).calcFrameSize(mbWidth * mbHeight));
}
spsList.clear();
ppsList.clear();
H264Utils.encodeMOVPacket(result, spsList, ppsList);
outTrack.addFrame(new MP4Packet((MP4Packet) inFrame, result));
if (i % 100 == 0) {
long elapse = System.currentTimeMillis() - start;
System.out.println((i * 100 / totalFrames) + "%, " + (i * 1000 / elapse) + "fps");
}
}
outTrack.addSampleEntry(H264Utils.createMOVSampleEntry(spsList, ppsList));
muxer.writeHeader();
} finally {
if (sink != null)
sink.close();
if (source != null)
source.close();
}
}
FFMPEGを使用しないのはなぜですか?
Javaのラッパーがあるようです:
http://fmj-sf.net/ffmpeg-Java/getting_started.php
FFMPEGでさまざまなメディアソースを1つのビデオにコンパイルする方法の例を次に示します。
http://howto-pages.org/ffmpeg/#multiple
そして最後に、ドキュメント: