本文介绍了jcodec - 有没有人看过这个库的文档?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用jcodec将bufferedimages编码为h264电影。只有我无法在任何地方找到示例代码。

I'm trying to use jcodec to encode bufferedimages into a h264 movie. Only I haven't been able to find example code anywhere.

过去有没有人使用过此库?我没有看到任何文档,即使库附带的javadoc也没有包含使用信息。如果你已经看过例子,或者可以提供见解,请告诉我。

Has anyone used this library in the past? I haven't seen any documentation, even the javadoc that comes with the library contains no usage information. If you have seen examples, or can provide insight please let me know.

提前致谢

推荐答案

JCodec不支持H.264编码。但是,您可以将JNA与x264库或ffmpeg一起使用。如果你选择这条路线,这个线程可以帮助你开始:。

JCodec does not support encoding of H.264. You can however use JNA with x264 library or ffmpeg. If you choose this route this thread may help you to get going: How does one encode a series of images into H264 using the x264 C API? .

[更新] 从版本0.1.0开始,JCodec支持H.264编码,这是一个简单的类,可用于将您的图像序列转换为MP4容器中的H.264视频:

[UPDATE] As of version 0.1.0 JCodec supports H.264 encoding, here's a simple class that you can use to turn your sequence of images into an H.264 video in MP4 container:

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
        for (int i = 0; i < 3; i++)
            Arrays.fill(toEncode.getData()[i], 0);
        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);
    }

    public static void main(String[] args) throws IOException {
        SequenceEncoder encoder = new SequenceEncoder(new File("video.mp4"));
        for (int i = 1; i < 100; i++) {
            BufferedImage bi = ImageIO.read(new File(String.format("folder/img%08d.png", i)));
            encoder.encodeImage(bi);
        }
        encoder.finish();
    }
}

[更新1] 使用此代码将交错的YUV 4:2:0字节数组转换为JCodec图片:

[UPDATE 1] Use this code to convert from interleaved YUV 4:2:0 byte array to JCodec picture:

byte[] input = ...
Picture output = Picture.create(width, height, ColorSpace.YUV420);
int[] d0 = output.getData()[0], d1 = output.getData()[1], d2 = output.getData()[2];

for(int i = 0, j0 = 0, j1 = 0, j2 = 0; i < input.length; i += 6, j0 += 4, ++j1 , ++j2) {
    d0[j0    ] = input[i    ] & 0xff;
    d0[j0 + 1] = input[i + 1] & 0xff;
    d0[j0 + 2] = input[i + 2] & 0xff;
    d0[j0 + 3] = input[i + 3] & 0xff;

    d1[j1    ] = input[i + 4] & 0xff;
    d2[j2    ] = input[i + 5] & 0xff;
}

这篇关于jcodec - 有没有人看过这个库的文档?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-26 23:39