2014-09-15 4 views
5

Sto sviluppando un'applicazione che unisce le clip mp4 usando la libreria mp4parser (isoparser-1.0-RC-27.jar e aspectjrt-1.8.0.jar). Quando due clip vengono unite, diventano una singola clip ma a mano a mano che vengono aggiunte altre clip, l'output mp4 ha l'audio dietro al video.L'unione di clip mp4 con mp4parser rende l'audio dietro al video

Ecco il codice:

Movie[] clips = new Movie[2]; 

    //location of the movie clip storage 
    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
      Environment.DIRECTORY_PICTURES), "TestMerge"); 

    //Build the two clips into movies 
    Movie firstClip = MovieCreator.build(first); 
    Movie secondClip = MovieCreator.build(second); 

    //Add both movie clips 
    clips[0] = firstClip; 
    clips[1] = secondClip; 

    //List for audio and video tracks 
    List<Track> videoTracks = new LinkedList<Track>(); 
    List<Track> audioTracks = new LinkedList<Track>(); 

    //Iterate all the movie clips and find the audio and videos 
    for (Movie movie: clips) { 
     for (Track track : movie.getTracks()) { 
      if (track.getHandler().equals("soun")) 
       audioTracks.add(track);     
      if (track.getHandler().equals("vide")) 
       videoTracks.add(track); 
     } 
    } 

    //Result movie from putting the audio and video together from the two clips 
    Movie result = new Movie(); 

    //Append all audio and video 
    if (videoTracks.size() > 0) 
     result.addTrack(new AppendTrack(videoTracks.toArray(new Track[videoTracks.size()]))); 

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

    //Output the resulting movie to a new mp4 file 
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
    String outputLocation = mediaStorageDir.getPath()+timeStamp; 
    Container out = new DefaultMp4Builder().build(result); 
    FileChannel fc = new RandomAccessFile(String.format(outputLocation), "rw").getChannel(); 
    out.writeContainer(fc); 
    fc.close(); 

    //Now set the active URL to play as the combined videos! 
    setURL(outputLocation); 
} 

La mia ipotesi è che, come si aggiungono più clip, la sincronizzazione di video in audio viene incasinato, dal momento che se due più clip sono fuse poi l'audio/video è ok. C'è comunque modo di prevenire questa scarsa sincronizzazione di video e audio in più clip più piccoli, o qualcuno ha trovato una soluzione per farlo usando mp4parser ?? FFMpeg è un'altra soluzione che sto prendendo in considerazione, ma non ho trovato nessun altro utilizzarlo per fare questo

MODIFICA: Ho scoperto che l'audio è in genere più lungo del video, quindi, questo è ciò che causa il video finale risultante per essere compensato così tanto quando vengono aggiunte sempre più clip per creare una clip. Ho intenzione di risolvere tagliando campioni audio

risposta

0

Sono stato in grado di risolvere questo problema utilizzando la tecnica con la modifica di cui sopra. Il trucco consiste nel tenere traccia di quante clip vengono unite e rimuovere campioni dalla fine della traccia audio della clip più recente aggiunta. Con l'uscita risultante mp4 cresce con più clip, è necessario spogliarsi sempre di più. Ciò è dovuto in parte alla differenza nei tempi delle tracce audio e video, poiché la traccia audio potrebbe essere 1020ms e il video è 1000ms, con 5 clip aggiunte, quindi avresti un offset di circa 100ms per le lunghezze audio e video, quindi devi risarcirlo.

+0

Si prega di aggiungere il codice per il ritaglio le tracce audio per le altre persone che trovano la soluzione. Grazie! – Episodex

+0

L'ho scritto qualche tempo fa, mi permetta di scovare la mia soluzione –

+0

Grazie per l'interesse :). Ho scoperto come ritagliare tecnicamente l'audio, ma ho ancora problemi con la scelta del giusto numero di campioni da rimuovere. Mi chiedo se hai trovato qualche soluzione a questo. – Episodex

1

solo mettendo un codice di risposta di Lucas sopra:

1.

LinkedList<Track> videoTracks = new LinkedList<>(); 
      LinkedList<Track> audioTracks = new LinkedList<>(); 
      double[] audioDuration = {0}, videoDuration = {0}; 
      for (Movie m : clips) { 
       for (Track t : m.getTracks()) { 
        if (t.getHandler().equals("soun")) { 
         for (long a : t.getSampleDurations()) audioDuration[0] += ((double) a)/t.getTrackMetaData().getTimescale(); 
         audioTracks.add(t); 
        } else if (t.getHandler().equals("vide")) { 
         for (long v : t.getSampleDurations()) videoDuration[0] += ((double) v)/t.getTrackMetaData().getTimescale(); 
         videoTracks.add(t); 
        } 
       } 

       adjustDurations(videoTracks, audioTracks, videoDuration, audioDuration); 
      } 

2.

private void adjustDurations(LinkedList<Track> videoTracks, LinkedList<Track> audioTracks, double[] videoDuration, double[] audioDuration) { 
    double diff = audioDuration[0] - videoDuration[0]; 

    //nothing to do 
    if (diff == 0) { 
     return; 
    } 

    //audio is longer 
    LinkedList<Track> tracks = audioTracks; 

    //video is longer 
    if (diff < 0) { 
     tracks = videoTracks; 
     diff *= -1; 
    } 

    Track track = tracks.getLast(); 
    long[] sampleDurations = track.getSampleDurations(); 
    long counter = 0; 
    for (int i = sampleDurations.length - 1; i > -1; i--) { 
     if (((double) (sampleDurations[i])/track.getTrackMetaData().getTimescale()) > diff) { 
      break; 
     } 
     diff -= ((double) (sampleDurations[i])/track.getTrackMetaData().getTimescale()); 
     audioDuration[0] -= ((double) (sampleDurations[i])/track.getTrackMetaData().getTimescale()); 
     counter++; 
    } 

    if (counter == 0) { 
     return; 
    } 

    track = new CroppedTrack(track, 0, track.getSamples().size() - counter); 

    //update the original reference 
    tracks.removeLast(); 
    tracks.addLast(track); 
} 
+0

Un solo suggerimento, durante il calcolo della durata del campione, dovrebbe essere diviso per la scala temporale della traccia per ottenere la durata effettiva. –

Problemi correlati