Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crop audio track #33

Closed
damienoliver opened this issue Dec 18, 2014 · 6 comments
Closed

Crop audio track #33

damienoliver opened this issue Dec 18, 2014 · 6 comments

Comments

@damienoliver
Copy link

Hi mate,

Great library!

I'm trying to crop an audio track to match a video duration and then mux together. At the moment I've just hard coded in 5 seconds for the audio duration, but it is coming out much shorter. I know it's to do with the sample length mismatch between the tracks but I just can't seem to work it out.

I've tried to follow your lead (in ShortenExample.java) but my audio track is always much shorter than expected. i.e. the endSample is not calculated properly.

This is my code, anything obviously wrong here?

String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES).getAbsolutePath();
String videoPath = path + "/" + "sas-video.mp4";


Movie orig_movie = MovieCreator.build(videoPath);

String filename = "finalaudiolong.aac";
File audioFile = new File(path, filename);

AACTrackImpl aacTrack = new AACTrackImpl(new FileDataSourceImpl(audioFile));

Track track = (Track) orig_movie.getTracks().get(0);


double startTime1 = 0;
double endTime1 = 5; //stop at 5 seconds

boolean timeCorrected = false;

if (track.getSyncSamples() != null && track.getSyncSamples().length > 0) {
    if (timeCorrected) {

        throw new RuntimeException("The startTime has already been corrected by another track with SyncSample. Not Supported.");
    }
    startTime1 = correctTimeToSyncSample(track, startTime1, false);
    endTime1 = correctTimeToSyncSample(track, endTime1, true);
    timeCorrected = true;
}

long currentSample = 0;
double currentTime = 0;
double lastTime = -1;
long startSample1 = -1;
long endSample1 = -1;


for (int i = 0; i < track.getSampleDurations().length; i++) {
    long delta = track.getSampleDurations()[i];


    if (currentTime > lastTime && currentTime <= startTime1) {

        startSample1 = currentSample;
    }
    if (currentTime > lastTime && currentTime <= endTime1) {

        endSample1 = currentSample;
    }

    lastTime = currentTime;
    currentTime += (double) delta / (double) track.getTrackMetaData().getTimescale();
    currentSample++;
}

CroppedTrack cropperAacTrack = new CroppedTrack(aacTrack, startSample1, endSample1);


Movie movie = new Movie();

movie.addTrack(track);
movie.addTrack(cropperAacTrack);

Container mp4file = new DefaultMp4Builder().build(movie);

FileChannel fc = new FileOutputStream(new File(path,"sas-video-with-audio.mp4")).getChannel();
mp4file.writeContainer(fc);
fc.close();
@damienoliver
Copy link
Author

Whoops, ignore that. I just realised I was measuring samples on the video track not audio track.

Here is the working code if anyone else is trying to do this.

Thanks!

String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES).getAbsolutePath();
String videoPath = path + "/" + "sas-video.mp4";

Movie orig_movie = MovieCreator.build(videoPath);

String filename = "finalaudiolong.aac";
File audioFile = new File(path, filename);

AACTrackImpl aacTrack = new AACTrackImpl(new FileDataSourceImpl(audioFile));

//get duration of video
IsoFile isoFile = new IsoFile(videoPath);
double lengthInSeconds = (double)
        isoFile.getMovieBox().getMovieHeaderBox().getDuration() /
        isoFile.getMovieBox().getMovieHeaderBox().getTimescale();


Track track = (Track) orig_movie.getTracks().get(0);

Track audioTrack = (Track) aacTrack;


double startTime1 = 0;
double endTime1 = lengthInSeconds;

boolean timeCorrected = false;

if (audioTrack.getSyncSamples() != null && audioTrack.getSyncSamples().length > 0) {
    if (timeCorrected) {

        throw new RuntimeException("The startTime has already been corrected by another track with SyncSample. Not Supported.");
    }
    startTime1 = correctTimeToSyncSample(audioTrack, startTime1, false);
    endTime1 = correctTimeToSyncSample(audioTrack, endTime1, true);
    timeCorrected = true;
}

long currentSample = 0;
double currentTime = 0;
double lastTime = -1;
long startSample1 = -1;
long endSample1 = -1;


for (int i = 0; i < audioTrack.getSampleDurations().length; i++) {
    long delta = audioTrack.getSampleDurations()[i];


    if (currentTime > lastTime && currentTime <= startTime1) {
        // current sample is still before the new starttime
        startSample1 = currentSample;
    }
    if (currentTime > lastTime && currentTime <= endTime1) {
        // current sample is after the new start time and still before the new endtime
        endSample1 = currentSample;
    }

    lastTime = currentTime;
    currentTime += (double) delta / (double) audioTrack.getTrackMetaData().getTimescale();
    currentSample++;
}

CroppedTrack cropperAacTrack = new CroppedTrack(aacTrack, startSample1, endSample1);

Movie movie = new Movie();

movie.addTrack(track);
movie.addTrack(cropperAacTrack);

Container mp4file = new DefaultMp4Builder().build(movie);

FileChannel fc = new FileOutputStream(new File(path,"sas-video-with-audio.mp4")).getChannel();
mp4file.writeContainer(fc);
fc.close();

@sannies
Copy link
Owner

sannies commented Jan 28, 2015

clean up

@sannies sannies closed this as completed Jan 28, 2015
@ltpquang
Copy link

ltpquang commented Jun 20, 2016

@damienoliver sorry for digging this up, but I cant understand what does correctTimeToSyncSample method do? Could you give me some sort explanations, and how did you implement it?

I took some examinations and relized that with audio (AAC in my cases), the audioTrack.getSyncSamples() always returns null, therefore the time correction process was never be executed. Or am I doing it wrong?

@pajama
Copy link

pajama commented Jun 23, 2017

@ltpquang @chad187
Found the correctTimeToSyncSample method with description here -
https://stackoverflow.com/questions/26841622/trimming-video-with-the-help-of-mp4parser

@ltpquang
Copy link

@pajama nice find, thank you so much, gonna give it a try

@pajama
Copy link

pajama commented Jun 25, 2017

@ltpquang good luck! The method that worked for me was actually in his sample project, at the bottom of this class.
https://gitlab.com/lassana/mp4parser-test/blob/master/src/com/github/lassana/mp4parser_test/Mp4Cutter2.java

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants