web-dev-qa-db-fra.com

Bibliothèque Java recommandée pour créer une vidéo par programme

Quelqu'un peut-il recommander une bibliothèque Java qui me permettrait de créer une vidéo par programme? Plus précisément, cela ferait ce qui suit:

  • prendre une série de BufferedImages comme cadres
  • permettre l'ajout d'un fond WAV/MP3
  • autoriser l'ajout de fichiers WAV/MP3 "accidentels" à des points spécifiés par programme de manière arbitraire
  • sortir la vidéo dans un format commun (MPEG, etc.)

Quelqu'un peut-il recommander quelque chose? Pour le mélange image/son, je vivais même avec quelque chose qui prenait une série d’images, et pour chaque image, je devais fournir les octets bruts de données sonores non compressées associées à cette image.

P.S. Il n’est même pas nécessaire que ce soit une "bibliothèque tierce" en tant que telle si Java Media Framework répond aux demandes susmentionnées, mais j’ai le sentiment que ce n’est pas le cas.

29
Neil Coffey

J'ai utilisé le code mentionné ci-dessous pour exécuter avec succès les éléments 1, 2 et 4 de votre liste d'exigences en Java pur. Ça vaut le coup d'oeil et vous pourriez probablement trouver comment inclure le n ° 3.

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

5
janoside

J'ai trouvé un outil appelé ffmpeg qui permet de convertir des fichiers multimédia d'un format à un autre. Il existe un filtre appelé libavfilter dans ffmpeg, qui remplace vhook et permet de modifier ou d’examiner la vidéo/l’audio entre le décodeur et le codeur. Je pense qu'il devrait être possible de saisir des images brutes et de générer de la vidéo. J'ai effectué une recherche sur toute implémentation Java de ffmpeg et trouvé la page intitulée "Prise en main de FFMPEG-Java" qui est un wrapper Java autour de FFMPEG utilisant la JNA. 

4
Mukesh Kamath

Vous pouvez essayer une bibliothèque de codec Java pure appelée JCodec.
Il possède un encodeur H.264 (AVC) très basique et un multiplexeur MP4. Voici un exemple de code complet tiré de leurs exemples - 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();
    }
}

Cet exemple est plus sophistiqué et montre en réalité le multiplexage d'images encodées dans un fichier 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();
    }
}
2

Pourquoi ne pas utiliser FFMPEG?

Il semble y avoir un wrapper Java pour cela:

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

Voici un exemple de compilation de diverses sources multimédia en une vidéo avec FFMPEG:

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

Et enfin les docs:

http://ffmpeg.org/ffmpeg.html

0
Jonathan