sannies / mp4parser

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

Currupt output file from DefaultMp4Builder. #430

Open afsaredrisy opened 4 years ago

afsaredrisy commented 4 years ago

I am trying to replace the audio of an mp4 video. I have a mp4 source file and a .aac audio file. Mp4 file I am recording from native android MediaRecorder following is my code used for recording mp4 video.

 public void initRecorder(File saveToFile, int displayWidth, int displayHeight,
                             int desiredWidth, int desiredHeight, int orientationHint,
                             MediaRecorder.OnErrorListener errorListener,
                             MediaRecorder.OnInfoListener infoListener)
            throws IOException {

        MediaRecorder mediaRecorder = new MediaRecorder();

        mediaRecorder.setOnInfoListener(infoListener);

        mediaRecorder.setOnErrorListener(errorListener);

        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
        mediaRecorder.setInputSurface(mSurface);
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);

        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        mediaRecorder.setAudioSamplingRate(44100);
        mediaRecorder.setAudioEncodingBitRate(96000);

        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);

        mediaRecorder.setVideoEncodingBitRate(12000000);
        mediaRecorder.setVideoFrameRate(30);

        if(desiredWidth > desiredHeight){
            float desiredAspect = 1080.0f / 2280.0f;

            if(desiredWidth > 2280 || desiredHeight > 1080){
                float aspect = (float) desiredHeight / desiredWidth;
                if(aspect > desiredAspect){
                    desiredHeight = 1080;
                    desiredWidth = (int) Math.floor(desiredHeight / aspect);
                } else {
                    desiredWidth = 2280;
                    desiredHeight = (int) Math.floor(desiredWidth * aspect);
                }
            }
        } else {
            float desiredAspect = 2280.0f / 1080.0f;

            if(desiredWidth > 1080 || desiredHeight > 2280){
                float aspect = (float) desiredHeight / desiredWidth;
                if(aspect > desiredAspect){
                    desiredHeight = 2280;
                    desiredWidth = (int) Math.floor(desiredHeight / aspect);
                } else {
                    desiredWidth = 1080;
                    desiredHeight = (int) Math.floor(desiredWidth * aspect);
                }
            }
        }

        mDesiredHeight = desiredHeight;
        mDesiredWidth = desiredWidth;

        mediaRecorder.setVideoSize(mDesiredWidth, mDesiredHeight);

        mediaRecorder.setOrientationHint(orientationHint);

        mediaRecorder.setOutputFile(saveToFile.getPath());
        mediaRecorder.prepare();

        mMediaRecorder = mediaRecorder;

    }

Above MediaRecorder object is being used to generate mp4 video file. I downloaded .aac file from some internet source & I don't know its bit-rate, encoding etc. following code I am using for merging/mixing .aac with mp4.

Movie m = MovieCreator.build(video);
List nuTracks = new ArrayList<>();
for (Track t : m.getTracks()) {
        if (!"soun".equals(t.getHandler())) {
        nuTracks.add(t);
        Log.d(TAG,"found video track");
        }
    }
Track nuAudio = new AACTrackImpl(new FileDataSourceImpl(audio));
Track crop_track= CropAudio(video,nuAudio);
nuTracks.add(crop_track);
m.setTracks(nuTracks);
Container mp4file = new DefaultMp4Builder().build(m);
FileChannel fc = new FileOutputStream(new File(output)).getChannel();
mp4file.writeContainer(fc);
fc.close();
// sending final output file to player.

output file is not playing in some players and playing without audio in some player. I tried to play output file in ubuntu video player as well but there also it could not work. I am not sure whats wrong I am doing but suspecting that it could be different encoding issue but not sure how to deal with that. Any idea/suggestion will be helpful.