MajorMaad
MajorMaad

Reputation: 11

Android : java.lang.NullPointerException / Merging Videos

I am currently making an Android app that can Merge Videos. Here is the java class to do so :

public class MergeVideos extends AsyncTask<String, Integer, String> {
// The working path where the video files are located
private String workingPath;
// The files name to merge
private ArrayList<String> videosToMerge;

public MergeVideos(String workingPath, ArrayList<String> videosToMerge) {
    this.workingPath=workingPath;
    this.videosToMerge=videosToMerge;
}

@Override
protected void onPreExecute() {
}

@Override
protected String doInBackground(String... params) {
    int count=videosToMerge.size();
    try {
        Movie[] inMovies = new Movie[count];
        for (int i = 0; i < count; i++) {
            File file = new File(workingPath, videosToMerge.get(i));
            if (file.exists()) {
                FileInputStream fis = new FileInputStream(file);
                FileChannel fc = fis.getChannel();
                inMovies[i] = MovieCreator.build((DataSource) fc);
                fis.close();
                fc.close();
            }
        }

        List<Track> videoTracks = new LinkedList<Track>();
        List<Track> audioTracks = new LinkedList<Track>();

        for (Movie m : inMovies) {
            for (Track t : m.getTracks()) {
                if (t.getHandler().equals("soun")) {
                    audioTracks.add(t);
                }
                if (t.getHandler().equals("vide")) {
                    videoTracks.add(t);
                }
                if (t.getHandler().equals("")) {

                }
            }
        }

        Movie result = new Movie();

        if (audioTracks.size() > 0) {
            result.addTrack(new AppendTrack(audioTracks.toArray(new Track[audioTracks.size()])));
        }
        if (videoTracks.size() > 0) {
            result.addTrack(new AppendTrack(videoTracks.toArray(new Track[videoTracks.size()])));
        }

        IsoFile out = (IsoFile) new DefaultMp4Builder().build(result);

        long timestamp = new Date().getTime();
        String timestampS = "" + timestamp;

        File storagePath = new File(Environment.getExternalStorageDirectory() + "/VideosMerged");
        storagePath.mkdirs();

        File myMovie = new File(storagePath, String.format("output-%s.mp4", timestampS));

        FileOutputStream fos = new FileOutputStream(myMovie);
        FileChannel fco = fos.getChannel();
        fco.position(0);
        out.getBox(fco);
        fco.close();
        fos.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    String mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
    mFileName += "/output.mp4";
    return mFileName;
}

@Override
protected void onPostExecute (String value) {
    super.onPostExecute(value);
}

I got this code from Github

And here is how I use it in the main class : In onCreate :

videosList=new ArrayList<String>();
videosList.add("sample_mpeg4.mp4");
videosList.add("big_buck_bunny.mp4");

this.workPath = Environment.getExternalStorageDirectory()+"/com.marakana.android.videocapturedemo";

And then when I click on a Button, it is supposed to merge :

 mergeVideos= new MergeVideos(workPath, videosList).execute();

However, when I launch the app, I have the following errors :

02-04 10:59:34.952 32644-32644/com.marakana.android.videocapturedemo E/MediaPlayer﹕ Should have subtitle controller already set 02-04 10:59:34.962 32644-961/com.marakana.android.videocapturedemo E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #2 Process: com.marakana.android.videocapturedemo, PID: 32644 java.lang.RuntimeException: An error occured while executing doInBackground() at android.os.AsyncTask$3.done(AsyncTask.java:300) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355) at java.util.concurrent.FutureTask.setException(FutureTask.java:222) at java.util.concurrent.FutureTask.run(FutureTask.java:242) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) at java.lang.Thread.run(Thread.java:841) Caused by: java.lang.NullPointerException at com.marakana.android.videocapturedemo.MergeVideos.doInBackground(MergeVideos.java:69) at com.marakana.android.videocapturedemo.MergeVideos.doInBackground(MergeVideos.java:30) at android.os.AsyncTask$2.call(AsyncTask.java:288) at java.util.concurrent.FutureTask.run(FutureTask.java:237)             at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)             at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)             at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)             at java.lang.Thread.run(Thread.java:841)

I tried to look a the lignes 30 and 69 in MergeVideos as it is said, which are :

public class MergeVideos extends AsyncTask<String, Integer, String> {

and

for (Movie m : inMovies) {

but I can't see what is wrong. I'm a beginner in Android, so any help would be very much appreciated !

Thank you

Upvotes: 1

Views: 366

Answers (1)

user3956566
user3956566

Reputation:

Try adding to your mMovies array like this

inMovies.add( MovieCreator.build((DataSource) fc))

instead of this:

inMovies[i] = MovieCreator.build((DataSource) fc);

Also add a try and catch or if to check that mMovies is empty

if (mMovies.length==0)
//don't proceed with the offending code
        for (Movie m : inMovies) {

It is throwing the exception, because it is trying to loop through an empty array, the array is not null, it is empty, so you need to check the length.

Upvotes: 0

Related Questions