5

How to write (wrap) MPEG4 data into a MP4 file in android?

I am doing some kind video processing on android platform, but I don't know how to write the processed data (encoded in some kind standard, like MPEG4) back into video file like mp4. I think it is best to use API to do this, but I can't find the needed API.

Is there anyone have any ideas?

guanlin
  • 51
  • 1
  • 3

4 Answers4

2

mp4parser can work only with fully created frame streams, u cant write frame by frame with it. Correct me if im wrong

H264TrackImpl h264Track = new H264TrackImpl(new BufferedInputStream(some input stream here));
Movie m = new Movie();
IsoFile out = new DefaultMp4Builder().build(m);
File file = new File("/sdcard/encoded.mp4");
FileOutputStream fos = new FileOutputStream(file);
out.getBox(fos.getChannel());
fos.close();

Now we need to know how to write frame by frame there.

Léon Pelletier
  • 2,701
  • 2
  • 40
  • 67
1

OpenCV might be a little too much for the job, but I can't think of anything easier. OpenCV is a computer vision library that offers an API for C, C++ and Python.

Since you are using Android, you'll have to download a Java wrapper for OpenCV named JavaCV, and it's a 3rd party API. I wrote a small post with instructions to install OpenCV/JavaCV on Windows and use it with Netbeans, but at the end you'll have to search for a tutorial that shows how to install OpenCV/JavaCV for the Android platform.

This is a C++ example that shows how to open an input video and copy the frames to an output file. But since you are using Android an example using JavaCV is better, so the following code copies frames from an input video and writes it to an output file named out.mp4:

package opencv_videowriter;

import static com.googlecode.javacv.cpp.opencv_core.*;
import static com.googlecode.javacv.cpp.opencv_imgproc.*;
import static com.googlecode.javacv.cpp.opencv_highgui.*;

public class OpenCV_videowriter 
{
    public static void main(String[] args) 
    {
        CvCapture capture = cvCreateFileCapture("cleanfish47.mp4");
        if (capture == null)
        {
            System.out.println("!!! Failed cvCreateFileCapture");
            return;
        }

        int fourcc_code = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FOURCC);
        double fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
        int w = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
        int h = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

        CvVideoWriter writer = cvCreateVideoWriter("out.mp4",       // filename
                                                    fourcc_code,    // video codec
                                                    fps,            // fps
                                                    cvSize(w, h),   // video dimensions
                                                    1);             // is colored
        if (writer == null) 
        {
            System.out.println("!!! Failed cvCreateVideoWriter");

            return;
        }


        IplImage captured_frame = null;        
        while (true)
        {
            // Retrieve frame from the input file
            captured_frame = cvQueryFrame(capture);
            if (captured_frame == null)
            {
                System.out.println("!!! Failed cvQueryFrame");
                break;
            }


            // TODO: write code to process the captured frame (if needed)


            // Store frame in output file
            if (cvWriteFrame(writer, captured_frame) == 0) 
            {
                System.out.println("!!! Failed cvWriteFrame");
                break;
            }

        }

        cvReleaseCapture(capture);
        cvReleaseVideoWriter(writer);        
    }
}

Note: frames in OpenCV store pixels in the BGR order.

Community
  • 1
  • 1
karlphillip
  • 92,053
  • 36
  • 243
  • 426
  • Thank you for offering help. – guanlin Nov 19 '12 at 13:18
  • 1
    According to this SO question (http://stackoverflow.com/questions/21546906/how-to-open-cvvideowriter-in-android) "OpenCV4adnroid doesn’t support video reading and writing". Its missing from the android implementation of OpenCV. – Mick Mar 19 '14 at 13:37
0

Your question doesn't make 100% sense. MPEG-4 is a family of specification (all ISO/IEC 14496-*) and MP4 is a the file format that is specified in ISO/IEC 14496-14.

If you want to create an MP4 file from a raw AAC and/or H264 stream I would suggest using the mp4parser library. There is an example that shows how to mux AAC and H264 into an MP4 file.

Sebastian Annies
  • 2,438
  • 1
  • 20
  • 38
0
// Full working solution:
// 1. Add to app/build.gradle -> implementation 'com.googlecode.mp4parser:isoparser:1.1.22'
// 2. Add to your code:
try {
    File mpegFile = new File(); // ... your mpeg file ;
    File mp4file = new File(); // ... you mp4 file;
    DataSource channel = new FileDataSourceImpl(mpegFile);
    IsoFile isoFile = new IsoFile(channel);
    List<TrackBox> trackBoxes = isoFile.getMovieBox().getBoxes(TrackBox.class);
    Movie movie = new Movie();
    for (TrackBox trackBox : trackBoxes) {
        movie.addTrack(new Mp4TrackImpl(channel.toString()
                + "[" + trackBox.getTrackHeaderBox().getTrackId() + "]", trackBox));
    }
    movie.setMatrix(isoFile.getMovieBox().getMovieHeaderBox().getMatrix());
    Container out = new DefaultMp4Builder().build(movie);

    FileChannel fc = new FileOutputStream(mp4file).getChannel();

    out.writeContainer(fc);
    fc.close();
    isoFile.close();
    channel.close();

    Log.d("TEST", "file mpeg " + mpegFile.getPath() + " was changed to " + mp4file.getPath());

    // mpegFile.delete(); // if you wish!

} catch (Exception e) {
    e.printStackTrace();
}

// It's all! Happy coding =)
Andrew G
  • 663
  • 8
  • 15