Convert image sequence to video file android java

前端 未结 1 365
别那么骄傲
别那么骄傲 2021-02-02 01:10

I know this is an old question and I have researched a lot through this but seems like there are no proper solutions. There are some ways to do so which I have already seen such

相关标签:
1条回答
  • 2021-02-02 01:25

    You can use a pure java open source library called JCodec ( http://jcodec.org ), the class below demonstrates converting as sequence of images into MP4 clip ( H.264 ) using JCodec low level API:

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

    Then you can use it like this:

    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("img%08d.png", i)));
            encoder.encodeImage(bi);
        }
        encoder.finish();
    }
    
    0 讨论(0)
提交回复
热议问题