Кодировать видео в h264, используя bufferedimages?

Я пытаюсь перевести большой набор буферизованных изображений (предварительно сохраненные изображения, созданные на лету моим приложением) в видео с использованием Java и, надеюсь, библиотеки, которая может помочь в этом процессе.

Я исследовал ряд различных опций, таких как jcodec (не было документации о том, как его использовать). Xuggler (не удалось запустить его из-за проблем совместимости с jdk5 и связанными с ним библиотеками). и ряд других библиотек, которые имели очень плохую документацию.

Я пытаюсь найти библиотеку, которую я могу использовать, которая использует java для (1) создания видео h264, записывая bufferedimages кадр за кадром, и (2) имеет документацию, чтобы я мог на самом деле понять, как использовать плотину.

Любые идеи о том, что я должен изучить?

Если где-то существует чистый исходный код Java, который может этого добиться, я бы ОЧЕНЬ заинтересовался в этом. Потому что мне очень хотелось бы увидеть, как человек достиг функциональности и как я могу ее использовать!

Заранее спасибо...

2 ответа

Вот как вы можете сделать это с JCodec:

public class SequenceEncoder {
    private SeekableByteChannel ch;
    private Picture toEncode;
    private RgbToYuv420 transform;
    private H264Encoder encoder;
    private ArrayList<ByteBuffer> spsList;
    private ArrayList<ByteBuffer> ppsList;
    private CompressedTrack outTrack;
    private ByteBuffer _out;
    private int frameNo;
    private MP4Muxer muxer;

    public SequenceEncoder(File out) throws IOException {
        this.ch = NIOUtils.writableFileChannel(out);

        // Transform to convert between RGB and YUV
        transform = new RgbToYuv420(0, 0);

        // Muxer that will store the encoded frames
        muxer = new MP4Muxer(ch, Brand.MP4);

        // Add video track to muxer
        outTrack = muxer.addTrackForCompressed(TrackType.VIDEO, 25);

        // Allocate a buffer big enough to hold output frames
        _out = ByteBuffer.allocate(1920 * 1080 * 6);

        // Create an instance of encoder
        encoder = new H264Encoder();

        // Encoder extra data ( SPS, PPS ) to be stored in a special place of
        // MP4
        spsList = new ArrayList<ByteBuffer>();
        ppsList = new ArrayList<ByteBuffer>();

    }

    public void encodeImage(BufferedImage bi) throws IOException {
        if (toEncode == null) {
            toEncode = Picture.create(bi.getWidth(), bi.getHeight(), ColorSpace.YUV420);
        }

        // Perform conversion
        transform.transform(AWTUtil.fromBufferedImage(bi), toEncode);

        // Encode image into H.264 frame, the result is stored in '_out' buffer
        _out.clear();
        ByteBuffer result = encoder.encodeFrame(_out, toEncode);

        // Based on the frame above form correct MP4 packet
        spsList.clear();
        ppsList.clear();
        H264Utils.encodeMOVPacket(result, spsList, ppsList);

        // Add packet to video track
        outTrack.addFrame(new MP4Packet(result, frameNo, 25, 1, frameNo, true, null, frameNo, 0));

        frameNo++;
    }

    public void finish() throws IOException {
        // Push saved SPS/PPS to a special storage in MP4
        outTrack.addSampleEntry(H264Utils.createMOVSampleEntry(spsList, ppsList));

        // Write MP4 header and finalize recording
        muxer.writeHeader();
        NIOUtils.closeQuietly(ch);
    }
}

jcodec сейчас (jcodec-0.1.9.jar) включает в себя SequenceEncoder что напрямую разрешает написание BufferedImage с видео потоком.

Я потратил некоторое время на исправление импорта по умолчанию этого нового класса в Eclipse. После удаления первого импорта, пытаясь (как я уже говорил выше, я не смог найти некоторые классы) создать свой собственный, используя код Станислава, и повторно импортируя, я заметил ошибку:

import org.jcodec.api.awt.SequenceEncoder;
//import org.jcodec.api.SequenceEncoder;

Второй полностью устарел, и никаких документов, направляющих меня к нему, не существует.

Соответствующий метод тогда:

private void saveClip(Trajectory traj) {
    //See www.tutorialspoint.com/androi/android_audio_capture.htm
    //for audio cap ideas.
    SequenceEncoder enc;
    try {
        enc = new SequenceEncoder(new File("C:/Users/WHOAMI/today.mp4"));
        for (int i = 0; i < BUFF_COUNT; ++i) {
            BufferedImage image = buffdFramToBuffdImage(frameBuff.get(i));
            enc.encodeImage(image);
        }
        enc.finish();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
Другие вопросы по тегам