package org.ffmpeg.android.test;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Locale;
import net.sourceforge.sox.CrossfadeCat;
import net.sourceforge.sox.SoxController;
import org.ffmpeg.android.Clip;
import org.ffmpeg.android.FfmpegController;
import org.ffmpeg.android.ShellUtils;
public class CrossfadeTest {
public static void test (String videoRoot, String fileTmpPath, String clipOutPath, double fadeLen) throws Exception
{
File fileTmp = new File(fileTmpPath);
File fileAppRoot = new File("");
File fileVideoRoot = new File(videoRoot);
String fadeType = "l";
int sampleRate = 22050;
int channels = 1;
FfmpegController ffmpegc = new FfmpegController (null, fileTmp);
Clip clipOut = new Clip();
clipOut.path = clipOutPath;
clipOut.audioCodec="aac";
clipOut.audioBitrate=56;
ArrayList<Clip> listVideos = new ArrayList<Clip>();
String[] fileList = fileVideoRoot.list();
for (String fileVideo : fileList)
{
if (fileVideo.endsWith("mp4"))
{
Clip clip = new Clip();
clip.path = new File(fileVideoRoot,fileVideo).getCanonicalPath();
//clip.startTime = "00:00:03";
//clip.duration = "00:00:02";
ffmpegc.getInfo(clip);
//System.out.println("clip " + fileVideo + " duration=" + clip.duration);
listVideos.add(clip);
}
}
//now add 1 second cross fade to each audio file and cat them together
SoxController sxCon = new SoxController(null, fileAppRoot, new ShellUtils.ShellCallback() {
@Override
public void shellOut(String shellLine) {
// System.out.println("sxCon> " + shellLine);
}
@Override
public void processComplete(int exitValue) {
if (exitValue != 0)
{
System.err.println("sxCon> EXIT=" + exitValue);
RuntimeException re = new RuntimeException("non-zero exit: " + exitValue);
re.printStackTrace();
throw re;
}
}
});
ArrayList<Clip> alAudio = new ArrayList<Clip>();
//convert each input file to a WAV so we can use Sox to process
int wavIdx = 0;
for (Clip mediaIn : listVideos)
{
if (new File(mediaIn.path).exists())
{
if (mediaIn.audioCodec == null)
{
//there is no audio track so let's generate silence
}
else
{
Clip audioOut = ffmpegc.convertToWaveAudio(mediaIn, new File(fileTmp, wavIdx+".wav").getCanonicalPath(),sampleRate,channels, new ShellUtils.ShellCallback() {
@Override
public void shellOut(String shellLine) {
// System.out.println("convertToWav> " + shellLine);
}
@Override
public void processComplete(int exitValue) {
if (exitValue != 0)
{
System.err.println("convertToWav> EXIT=" + exitValue);
RuntimeException re = new RuntimeException("non-zero exit: " + exitValue);
re.printStackTrace();
throw re;
}
}
});
alAudio.add(audioOut);
/*
float duration = (float) sxCon.getLength(new File(audioOut.path).getCanonicalPath());
if (mediaIn.duration == null)
{
mediaIn.duration = String.format(Locale.US, "%f", duration);
}*/
ffmpegc.getInfo(mediaIn);
wavIdx++;
}
}
else
{
throw new FileNotFoundException(mediaIn.path);
}
}
if (alAudio.size() > 0)
{
String fileOut = alAudio.get(0).path;
System.out.println("mix length=" + sxCon.getLength(fileOut));
for (int i = 1; i < alAudio.size(); i++)
{
File fileAdd = new File(alAudio.get(i).path);
CrossfadeCat xCat = new CrossfadeCat(sxCon, fileOut, fileAdd.getCanonicalPath(), fadeLen, fileOut);
xCat.start();
fileAdd.deleteOnExit();
System.out.println("mix length=" + sxCon.getLength(fileOut));
}
//1 second fade in and fade out, t = triangle or linear
//String fadeLenStr = sxCon.formatTimePeriod(fadeLen);
String fadeFileOut = sxCon.fadeAudio(fileOut, fadeType, fadeLen, sxCon.getLength(fileOut)-fadeLen, fadeLen);
//now export the final file to our requested output format mOut.mimeType = AppConstants.MimeTypes.MP4_AUDIO;
Clip mdFinalIn = new Clip();
mdFinalIn.path = fadeFileOut;
System.out.println ("final duration: " + sxCon.getLength(fadeFileOut));
Clip exportOut = ffmpegc.convertTo3GPAudio(mdFinalIn, clipOut, new ShellUtils.ShellCallback() {
@Override
public void shellOut(String shellLine) {
//System.out.println("convertTo3gp> " + shellLine);
}
@Override
public void processComplete(int exitValue) {
if (exitValue < 0)
{
RuntimeException re = new RuntimeException("non-zero exit: " + exitValue);
re.printStackTrace();
throw re;
}
}
});
}
}
}