sannies / mp4parser

A Java API to read, write and create MP4 files
Apache License 2.0
2.76k stars 566 forks source link

Error merging two videos #275

Open aloklearning opened 7 years ago

aloklearning commented 7 years ago

I've been working on merging two video. I'm taking the videos from the phone storage and passing them in the form of string. Then this videos are getting merged. I've seen that if I'm merging the videos that is taken from the camera then it is working fine, merging is going good. But as soon as the different video file is taken and taken trying to get merged, it throws an exception says java.io.IOException: Cannot merge AudioSampleEntry{bytesPerSample=0, bytesPerFrame=0, bytesPerPacket=0, samplesPerPacket=0, packetSize=0, compressionId=0, soundVersion=0, sampleRate=24000, sampleSize=16, channelCount=2, boxes=[com.googlecode.mp4parser.boxes.mp4.ESDescriptorBox@fffffab7]} and AudioSampleEntry{bytesPerSample=0, bytesPerFrame=0, bytesPerPacket=0, samplesPerPacket=0, packetSize=0, compressionId=0, soundVersion=0, sampleRate=22050, sampleSize=16, channelCount=2, boxes=[com.googlecode.mp4parser.boxes.mp4.ESDescriptorBox@fffff9fb]} 08-22 15:59:03.347 27476-27558/in.pinelane.myhovi W/System.err: at com.googlecode.mp4parser.authoring.tracks.AppendTrack.mergeStsds(AppendTrack.java:116) 08-22 15:59:03.347 27476-27558/in.pinelane.myhovi W/System.err: at com.googlecode.mp4parser.authoring.tracks.AppendTrack.<init>(AppendTrack.java:59)

and does not saves any file inside the storage. Also if the heights are different of the video then it gives me this exception and this does not saves any file either

E/isoparser: AppendTrack:height differs

This is my activity you can see the code :

//asynch task to merge the videos in background
    class MergeVideos extends AsyncTask<ArrayList<File>, Integer, String>{

        @Override
        protected String doInBackground(ArrayList<File>... params) {
                ArrayList<Movie> inMovies = new ArrayList<>();
                for(File file : params[0]){
                    Movie movie = MovieCreator.build(file.getAbsolutePath());
                    inMovies.add(movie);
                }

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

                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 fileChannel = new RandomAccessFile(String.format(Environment
                        .getExternalStorageDirectory() + "/MyHoviVideo.mp4"),
                        "rw").getChannel();
                out.writeContainer(fileChannel);
                fileChannel.close();

            }catch (FileNotFoundException e){
                e.printStackTrace();
            }catch (IOException e){
                e.printStackTrace();
            }

            //retruning the file after successfull completion of the merging
            String mFileName = Environment.getExternalStorageDirectory()
                    .getAbsolutePath();
            mFileName += "/MyHoviVideo.mp4";
            //   = mFileName;
            return mFileName;
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            progressDialog.dismiss();
            Log.e("FILE_PATH===",s);
            playVideo(s);

        }
    }

    void playVideo(String play){
        mVideoPlayer.setVideoPath(play);
        mMediaController = new MediaController(this);
        mMediaController.setMediaPlayer(mVideoPlayer);
        mVideoPlayer.setMediaController(mMediaController);
        mVideoPlayer.setBackgroundColor(Color.TRANSPARENT);
        mVideoPlayer.requestFocus();
        mVideoPlayer.start();
    }
gibinNewAge commented 6 years ago

Hi , If you want to append two separate videos to one video then these videos need to have the same basic parameters (same codec, same resolution, same framerate, same colors - generally same decoder configuration). In your case the 'same codec' requirement is already fulfilled as I can see

the existence of an AvcConfigurationBox (AVC = Advanced Video Codec = different name for H264) tells me that. Now a problem might be be one of the others e.g. resolution, framerate, colors or some other decoder configuration. Could you make these two videos available to me so that I can have a look what the problem is? The mp4parser does not do any encoding. It takes encode audio and video and packages it as MP4. In your case the source is an MP4 as well as it seems. MP4 is a container - it may contain H263, H264, H265, AAC, AC3, EC3 - and so on - video/audio data. Playing the videos at the same time (picture in picture) either requires encoding a new video - not doable with mp4parser - or two surfaces each displaying a separate video. Think of simple pictures for the moment. Displaying two JPEG overlaid either requires you to create a completely new JPEG (in this case with photoshop or similar) or it requires you to first render picture 1 and then on top picture 2. Same is true for video. Best Regards, Gibin

vandanabpatel commented 5 years ago

Hi, i am getting same issue i have pick 2 videos from gallery (have different duration) i want merge them into one video

note: second video dont have sound it is just 5 second mute video

Nakuls426 commented 3 years ago

Hi, i am getting same issue i have pick 2 videos from gallery (have different duration) i want merge them into one video

note: second video dont have sound it is just 5 second mute video

As far as i know. It doesnt work with muted videos. The video must have some sound.