it-swarm.com.de

Empfohlene Java-Bibliothek zum programmgesteuerten Erstellen eines Videos

Kann jemand eine Java-Bibliothek empfehlen, mit der ich programmgesteuert ein Video erstellen kann? Insbesondere würde es Folgendes tun:

  • nehmen Sie eine Reihe von BufferedImages als Frames
  • ein Hintergrund-WAV/MP3 kann hinzugefügt werden
  • zufälliges Hinzufügen von zufälligen WAV/MP3-Dateien an willkürlich programmgesteuerten Punkten
  • ausgabe des Videos in einem gemeinsamen Format (MPEG usw.)

Kann jemand etwas empfehlen? Für das Bild-/Tonmischen würde ich sogar mit etwas leben, das eine Reihe von Frames benötigte, und für jedes Frame musste ich die rohen Bytes der unkomprimierten Tondaten bereitstellen, die diesem Frame zugeordnet sind.

P.S. Es muss nicht einmal eine "Bibliothek von Drittanbietern" sein, wenn das Java Media Framework die Aufrufe hat, um die oben genannten Ziele zu erreichen, aber aus meiner unübersichtlichen Erinnerung habe ich das Gefühl, dass dies nicht der Fall ist.

29
Neil Coffey

Ich habe den unten genannten Code verwendet, um die Elemente 1, 2 und 4 in Ihrer Anforderungsliste in reinem Java erfolgreich auszuführen. Es lohnt einen Blick und Sie könnten wahrscheinlich herausfinden, wie Sie # 3 einfügen.

http://www.randelshofer.ch/blog/2010/10/writing-quicktime-movies-in-pure-Java/

5
janoside

Ich habe ein Werkzeug namens ffmpeg gefunden, das Multimedia-Dateien von einem Format in ein anderes konvertieren kann. In ffmpeg gibt es einen Filter namens libavfilter, der als Ersatz für vhook dient, mit dem das Video/Audio zwischen Decoder und Encoder geändert oder untersucht werden kann. Ich denke, es sollte möglich sein, rohe Frames einzugeben und Video zu generieren. Ich habe nach einer beliebigen Java-Implementierung von ffmpeg gesucht und die Seite mit dem Titel "Erste Schritte mit FFMPEG-Java" gefunden, die einen Java-Wrapper enthält FFMPEG mit JNA. 

4
Mukesh Kamath

Sie können eine reine Java-Codec-Bibliothek namens JCodec ausprobieren.
Es hat einen sehr einfachen H.264 (AVC) Encoder und einen MP4 Muxer. Hier ist ein vollständiger Beispielcode aus den jeweiligen Samples - 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();
    }
}

Dieses Beispiel ist komplexer und zeigt tatsächlich das Muxen von codierten Frames in eine MP4-Datei: 

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();
    }
}

Warum nicht FFMPEG verwenden?

Es scheint einen Java-Wrapper dafür zu geben:

http://fmj-sf.net/ffmpeg-Java/getting_started.php

Hier ein Beispiel, wie Sie verschiedene Medienquellen mit FFMPEG zu einem Video zusammenstellen können:

http://howto-pages.org/ffmpeg/#multiple

Und zum Schluss die Dokumente:

http://ffmpeg.org/ffmpeg.html

0
Jonathan