6

I created a h264 raw video file, and I was able to mux it with Android MediaMuxer on Android 4.3 and up. Now I need to support Android versions 4.1 and 4.2. I found Jcodec. And there is an example for doing this:

https://github.com/jcodec/jcodec/blob/master/samples/main/java/org/jcodec/samples/mux/AVCMP4Mux.java

But I'm getting java.nio.ReadOnlyBufferException exception at line 70:

H264Utils.encodeMOVPacket(data);

I guess this code is not for Android? How do I fix this. Can someone familiar with Jcodec help on this?

X.Y.
  • 13,726
  • 10
  • 50
  • 63

1 Answers1

13

I gave up on Jcodec. It exposes too many codec internal stuff, and there is no documentation on usage at all. Mp4Parser did the job for me, and it's simple. Here is the code I mux raw h264 video into mp4 container:

    String h264Path = "path to my h264 file, generated by Android MediaCodec";

    DataSource videoFile = new FileDataSourceImpl(h264Path);

    H264TrackImpl h264Track = new H264TrackImpl(videoFile, "eng", 5, 1); // 5fps. you can play with timescale and timetick to get non integer fps, 23.967 is 24000/1001

    Movie movie = new Movie();

    movie.addTrack(h264Track);

    Container out = new DefaultMp4Builder().build(movie);
    FileOutputStream fos = new FileOutputStream(new File("path to my generated file.mp4"));
    out.writeContainer(fos.getChannel());

    fos.close();

Code examples were found here. Loop is closed! Now my video encoder implementation works from Android 4.1 and up, without the need of FFMpeg

BTW: Android stock "Gallery" app uses Mp4Parser, listed in its open source licenses.

Paul Gregoire
  • 9,715
  • 11
  • 67
  • 131
X.Y.
  • 13,726
  • 10
  • 50
  • 63
  • Android should really make the muxer into compatibility library, it's mostly file operations, no hardware encoder involved. Current 4.3 is too high as a minimum sdk version. – X.Y. Apr 22 '14 at 16:24
  • How did you generate h264 file to send as a input to mp4parser? I have mp4 format and need to add audio to my video. How can I use mp4Parser? – Ehsan Sep 06 '14 at 12:43
  • @user2204093 Use Android video encoding framework, take a look at import android.media.MediaCodec; import android.media.MediaFormat; Android does have MediaMuxer, but it's from API 18 and up – X.Y. Sep 06 '14 at 16:31
  • Thanks for your quick reply, I use jcodec to create a video from series of images but it doesn't have audio and output is mp4, it has muxer but in android version seems cannot generate h264, what should I do now? still use media codec to get h264? or another way? – Ehsan Sep 06 '14 at 17:22
  • 1
    jcodec is software encoding, I doubt it can be used in production environment. you want to stick with Android native encoder, it's hardware accelerated. Once you have h264, you can use Mp4Parser or the native Android Muxer (API > 18) to mux your h264 and video together. – X.Y. Sep 06 '14 at 18:45
  • I think this is deprecated. The constructor for H264TrackImpl only accepts FileChannel. Can someone provide an example for the implementation? – Stefan Alexandru Jan 28 '15 at 13:59
  • This worked perfectly for use with the mp4parser found in isoparser-1.0.6.jar. Funnily enough this is a better example than the one the author of mp4parser himself gave (admitedly that was a while back for an older version) :-)) This is SOOO much easier than MediaMuxer, if you have an elemetary h264 stream handy. – MacD Apr 22 '15 at 20:02