import java.awt.image.BufferedImage; import java.io.File; import com.xuggle.mediatool.*; import com.xuggle.mediatool.IMediaWriter; import com.xuggle.mediatool.MediaListenerAdapter; import com.xuggle.mediatool.MediaToolAdapter; import com.xuggle.mediatool.ToolFactory; import com.xuggle.mediatool.event.IAudioSamplesEvent; import com.xuggle.mediatool.event.IReadPacketEvent; import com.xuggle.mediatool.event.IVideoPictureEvent; import com.xuggle.mediatool.event.IWriteHeaderEvent; import com.xuggle.mediatool.event.IWritePacketEvent; import com.xuggle.mediatool.event.IWriteTrailerEvent; import com.xuggle.xuggler.Global; public class Cutter extends MediaListenerAdapter { //public static double START_POINT = 10.0 * Global.DEFAULT_PTS_PER_SECOND; //public static double END_POINT = 25.0 * Global.DEFAULT_PTS_PER_SECOND; private String TMP_DIR; public static void main(String[] args) { //--> due vettori double s[] = new double[3]; s[0] = 5; s[1] = 20; s[2] = 46; double e[] = new double[3]; e[0] = 10; e[1] = 35; e[2] = 55; new Cutter(s,e,"E:\\TV Series\\Orphan.Black.S01E01.HDTV.x264-2HD.mp4","out"); } //Devo utilizzare diversi writer, uno per ogni parte del filmato da tagliare private IMediaWriter writers[]; public Cutter(double[] starts, double[] ends, String videoPathin, String videoPathout) { writers = new IMediaWriter[starts.length]; IMediaReader reader = ToolFactory.makeReader(videoPathin); reader.setBufferedImageTypeToGenerate(BufferedImage.TYPE_3BYTE_BGR); TMP_DIR = videoPathout + "_tmp"; File tmpdir = new File(TMP_DIR); tmpdir.mkdir(); //creo una cartella temporanea per salvere i frammenti //passo da secondi a nanosecondi for(int i = 0; i < starts.length; i++) { starts[i]*=Global.DEFAULT_PTS_PER_SECOND; ends[i]*=Global.DEFAULT_PTS_PER_SECOND; writers[i] = ToolFactory.makeWriter(TMP_DIR+"/p"+i+".flv", reader); //comprende il nome del file } //creazione di un tool che mi taglia il video nei punti scelti videoCheck checkPos = new videoCheck(); //videocheck estende MediaToolAdapter reader.addListener(checkPos); //IMediaWriter writer = ToolFactory.makeWriter(videoPathout+".flv", reader); //comprende il nome del file boolean updatedS = false; boolean updatedE = false; int rp = 0; //Relative Position, cambia in base allo scorrere delle parti del filmato //E' importante che le parti siano disgiunte //reader. while(reader.readPacket() == null) { if(!updatedS && (checkPos.timeInMilisec >= starts[rp])) { System.out.print("\n" + rp); updatedS = true; //da un certo punto inizio a convertire updatedE = false; checkPos.addListener(writers[rp]); } if(!updatedE && (checkPos.timeInMilisec >= ends[rp] )) { System.out.print("-" + rp); updatedE = true; //arrivato ad un certo punto smetto di convertire checkPos.removeListener(writers[rp]); writers[rp].close(); rp++; //passo alla prossima parte del filmato if(rp == starts.length) { //se sono arrivato alla fine System.out.print("\nCLOSE\n"); //writer.close(); //smetto di convertire } else updatedS = false; } } String OUT_FILE = videoPathout+".flv"; //Ottenuti i file separati li riunisco in un unico file concatenateVideoFromWriters(OUT_FILE); } public void concatenateVideoFromWriters(String OUT_FILE) { //Se il frammento รจ unico allora devo solo spostare e rinominare if(writers.length == 1) { new File(writers[0].getUrl()).renameTo(new File(OUT_FILE)); } else { //concateno i primi due e proseguo dal terzo new MyConcatenateAudioAndVideo().concatenate(writers[0].getUrl(),writers[1].getUrl(),TMP_DIR+"/d1.flv"); int i; for(i = 2; i < writers.length; i++) new MyConcatenateAudioAndVideo().concatenate(TMP_DIR+"/d"+(i-1)+".flv",writers[i].getUrl(),TMP_DIR+"/d"+i+".flv"); //sposto il file new File(TMP_DIR+"/d"+(i-1)+".flv").renameTo(new File(OUT_FILE)); } //elimino tutto deleteAllFromTmpFolder(); } public void deleteAllFromTmpFolder() { System.out.print("deleting tmpfile and folder"+ TMP_DIR +" \n"); File td = new File(TMP_DIR); String[] fileslist = td.list(); for(String fpath : fileslist) { System.out.print(fpath+" \n"); new File(TMP_DIR+"/"+fpath).delete(); //elimino i file nella cartella } td.delete(); //elimino la cartella } class videoCheck extends MediaToolAdapter { //Devono essere millisecondi public Long timeInMilisec = (long) 0; public boolean convert = true; @Override public void onVideoPicture(IVideoPictureEvent event) { timeInMilisec = event.getTimeStamp(); //mi ritorna il preciso istante in MICROsecondi //adesso chiamo la superclasse che continua con la manipolazione if(convert) super.onVideoPicture(event); } @Override public void onAudioSamples(IAudioSamplesEvent event) { if(convert) super.onAudioSamples(event); } @Override public void onWritePacket(IWritePacketEvent event) { if(convert) super.onWritePacket(event); } @Override public void onWriteTrailer(IWriteTrailerEvent event) { if(convert) super.onWriteTrailer(event); } @Override public void onReadPacket(IReadPacketEvent event) { if(convert) super.onReadPacket(event); } @Override public void onWriteHeader(IWriteHeaderEvent event) { if(convert) super.onWriteHeader(event); } } }