How to Append two videos in Android Programmatically

10,056

Solution 1

Code For Merging Multiple Video

Gradle Dependency

implementation 'com.googlecode.mp4parser:isoparser:1.1.9'

Code

private String appendTwoVideos(String firstVideoPath, String secondVideoPath)
{
    try {
        Movie[] inMovies = new Movie[2];

        inMovies[0] = MovieCreator.build(firstVideoPath);
        inMovies[1] = MovieCreator.build(secondVideoPath);

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

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

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

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

        @SuppressWarnings("resource")
        FileChannel fc = new RandomAccessFile(Environment.getExternalStorageDirectory() + "/wishbyvideo.mp4", "rw").getChannel();
        out.writeContainer(fc);
        fc.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

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

You might wanna call this function from a background thread.

Solution 2

The above answer is perfectly right but It will only work if your media encoder is H264.....

mediaRecorder.setVideoEncoder(VideoEncoder.H264);

happy Coding :) :D

Solution 3

The above answer will only work when your codec, framerate, and bitrate are the same.

Gradle Dependency(This library will work in nearly every case)

implementation 'com.github.yangjie10930:EpMedia:v0.9.5'

CODE

private void mergeVideos() {
        ArrayList<EpVideo> epVideos =  new  ArrayList<>();
        epVideos.add(new EpVideo (file2)); // Video 1
        epVideos.add(new EpVideo (file1)); // Video 2
        EpEditor. OutputOption outputOption =new EpEditor.OutputOption(fileOutput);
        outputOption.setWidth(720);
        outputOption.setHeight(1280);
        outputOption.frameRate = 25 ;
        outputOption.bitRate = 10 ; //Default
        EpEditor.merge(epVideos, outputOption, new  OnEditorListener() {
            @Override
            public  void  onSuccess () {
                Log.d("Status","Success");
            }

            @Override
            public  void  onFailure () {

            }

            @Override
            public  void  onProgress ( float  progress ) {
                // Get processing progress here
                Log.d("Progress",""+progress);
            }
        });

    }
Share:
10,056
Ahmad Arslan
Author by

Ahmad Arslan

Updated on June 14, 2022

Comments

  • Ahmad Arslan
    Ahmad Arslan about 2 years

    I am using this code. I need to merge two videos. It saved all videos in temp folder but not in merged condition. Append and DoAppend are my functions which I want for merging the videos.

    public String append(ArrayList<String> trimVideos) {
    
            for (int i = 0; i < trimVideos.size() - 1; i++) {
    
          String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
         if (i == 0) {                      
                String OutPutFileName = Constants.STORAGE_VIDEO_TEMP_PATH +                           
                File.separator + "APPEND" + "_" + timeStamp + ".mp4";
                doAppend(trimVideos.get(0), trimVideos.get(i + 1),OutPutFileName);
                Log.e(Constants.TAG, "In First: " + i + " " +   OutPutFileName);
    
                      } else {
    
            String OutPutFileName = Constants.STORAGE_VIDEO_TEMP_PATH
        + File.separator + "APPEND" + i + "_" + timeStamp + ".mp4";
                        doAppend(lastAppendOut, trimVideos.get(i + 1), OutPutFileName);
                        Log.e(Constants.TAG, "In Second: " + i + " " + OutPutFileName);
                    }
                }
                Log.e(Constants.TAG, "In End: "  + " " + lastAppendOut);
                return lastAppendOut;
            }
    

    This Method Crashed my application on add track.

    private String doAppend(String _firstVideo, String _secondVideo,String _newName) {
            try {
    
                Log.e("test", "Stage1");
                FileInputStream fis1 = new FileInputStream(_firstVideo);
                FileInputStream fis2 = new FileInputStream(_secondVideo);
    
                Movie[] inMovies = new Movie[] {
                        MovieCreator.build(fis1.getChannel()),MovieCreator.build(fis2.getChannel()) };
    
                List<Track> videoTracks = new LinkedList<Track>();
                List<Track> audioTracks = new LinkedList<Track>();
        //It returns one item of video and 2 item of video.
    
                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);
                        }
                    }
                }
                Log.e("test", "Stage2");
                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 = new DefaultMp4Builder().build(result);
                Log.e("test", "Stage3");
                String filename = _newName;
                lastAppendOut = filename;
                Log.e(Constants.TAG, "In Append: "  + " " + lastAppendOut);
    
                FileOutputStream fos = new FileOutputStream(filename);
                FileChannel fco = fos.getChannel();
    
                fco.position(0);
                out.getBox(fco);
                fco.close();
                fos.close();
                fis1.close();
                fis2.close();
    
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
                Log.e("check", e.getMessage());
            }
            return _newName;
        }