I would like to encode video from sequence of images with java only in my current android project. I mean without any use of external tools such as NDK.
Also is there any availability of java libraries for encoding video from sequence of images ?
Asked
Active
Viewed 1.4k times
8

captaindroid
- 2,868
- 6
- 31
- 45
1 Answers
11
You can use a pure java library called JCodec ( http://jcodec.org ). It contains a primitive yet working H.264 ( AVC ) encoder and a fully functioning MP4 ( ISO BMF ) muxer.
Here's a CORRECTED code sample that uses low-level API:
public void imageToMP4(BufferedImage bi) {
// A transform to convert RGB to YUV colorspace
RgbToYuv420 transform = new RgbToYuv420(0, 0);
// A JCodec native picture that would hold source image in YUV colorspace
Picture toEncode = Picture.create(bi.getWidth(), bi.getHeight(), ColorSpace.YUV420);
// Perform conversion
transform.transform(AWTUtil.fromBufferedImage(bi), yuv);
// Create MP4 muxer
MP4Muxer muxer = new MP4Muxer(sink, Brand.MP4);
// Add a video track
CompressedTrack outTrack = muxer.addTrackForCompressed(TrackType.VIDEO, 25);
// Create H.264 encoder
H264Encoder encoder = new H264Encoder(rc);
// Allocate a buffer that would hold an encoded frame
ByteBuffer _out = ByteBuffer.allocate(ine.getWidth() * ine.getHeight() * 6);
// Allocate storage for SPS/PPS, they need to be stored separately in a special place of MP4 file
List<ByteBuffer> spsList = new ArrayList<ByteBuffer>();
List<ByteBuffer> ppsList = new ArrayList<ByteBuffer>();
// Encode image into H.264 frame, the result is stored in '_out' buffer
ByteBuffer result = encoder.encodeFrame(_out, toEncode);
// Based on the frame above form correct MP4 packet
H264Utils.encodeMOVPacket(result, spsList, ppsList);
// Add packet to video track
outTrack.addFrame(new MP4Packet(result, 0, 25, 1, 0, true, null, 0, 0));
// Push saved SPS/PPS to a special storage in MP4
outTrack.addSampleEntry(H264Utils.createMOVSampleEntry(spsList, ppsList));
// Write MP4 header and finalize recording
muxer.writeHeader();
}
You can download JCodec library from a project web site or via Maven, for this add the below snippet to your pom.xml:
<dependency>
<groupId>org.jcodec</groupId>
<artifactId>jcodec</artifactId>
<version>0.1.3</version>
</dependency>
[UPDATE 1] Android users can use something like below to convert Android Bitmap object to JCodec native format:
public static Picture fromBitmap(Bitmap src) {
Picture dst = Picture.create((int)src.getWidth(), (int)src.getHeight(), RGB);
fromBitmap(src, dst);
return dst;
}
public static void fromBitmap(Bitmap src, Picture dst) {
int[] dstData = dst.getPlaneData(0);
int[] packed = new int[src.getWidth() * src.getHeight()];
src.getPixels(packed, 0, src.getWidth(), 0, 0, src.getWidth(), src.getHeight());
for (int i = 0, srcOff = 0, dstOff = 0; i < src.getHeight(); i++) {
for (int j = 0; j < src.getWidth(); j++, srcOff++, dstOff += 3) {
int rgb = packed[srcOff];
dstData[dstOff] = (rgb >> 16) & 0xff;
dstData[dstOff + 1] = (rgb >> 8) & 0xff;
dstData[dstOff + 2] = rgb & 0xff;
}
}
}

Stanislav Vitvitskyy
- 2,297
- 20
- 17
-
I will give a try then – captaindroid May 13 '13 at 06:49
-
Here is a little problem, how do i port import java.awt.image.BufferedImage; in android. Android SDK doesnt support **awt**. Thanks – captaindroid May 13 '13 at 08:52
-
See the **[UPDATE 1]** above. – Stanislav Vitvitskyy May 13 '13 at 19:46
-
You have `for (int i = 0, srcOff = 0, dstOff = 0; i < src.getHeight(); i++)` in your code, but dstOff is unused ;) – kelunik May 14 '13 at 15:01
-
1My edit isn't reviewed yet, but `Picture.create((int)src.getWidth(), (int)src.getHeight(), RGB);` should be `ColorSpace.RGB` I think ;) Also the int-casts aren't necessary. – kelunik May 14 '13 at 17:05
-
For neatness I'd suggest incrementing the `srcOff` and `dstOff` in the body of the `for` loop instead. For example, `int rgb = packed[srcOff++]` and each of the `dstData` lines would become `dstData[dstOff++]` instead. – Erik Jun 20 '14 at 15:41
-
If anyone decides to go the jcoded way then there is a android version now and a BuildUtil class that contains the fromBitmap function. – Raanan Aug 08 '14 at 12:43
-
@Raanan Any android tutorials on how to use jcodec on android? More specifically creating video out of images. Thanks! – Ziad Halabi Jan 12 '16 at 12:14
-
@ZiadHalabi Sorry, I don't think I can help more then Google in this case. :( – Raanan Jan 12 '16 at 14:28