我们创建了一个使用Xuggler记录网络摄像头流的应用程序,但视频和音频是分开记录的。
我们需要将这两个文件合并而不是串联起来。
如何在Java中实现这一目标?
我们需要将这两个文件合并而不是串联起来。
如何在Java中实现这一目标?
ffmpeg -i audiofile.mp3 -i moviefile.avi -acoded libfaac -vcodec libx264 output.mp4
您需要具备内置x264
和liblame
支持的ffmpeg
。并且要注意由于mp3 / x264许可证而导致的版权侵权问题,如何处理请自行决定。 - cristobalpublic class WrapperExe {
public boolean doSomething() {
String[] exeCmd = new String[]{"ffmpeg", "-i", "audioInput.mp3", "-i", "videoInput.avi" ,"-acodec", "copy", "-vcodec", "copy", "outputFile.avi"};
ProcessBuilder pb = new ProcessBuilder(exeCmd);
boolean exeCmdStatus = executeCMD(pb);
return exeCmdStatus;
} //End doSomething Function
private boolean executeCMD(ProcessBuilder pb)
{
pb.redirectErrorStream(true);
Process p = null;
try {
p = pb.start();
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("oops");
p.destroy();
return false;
}
// wait until the process is done
try {
p.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("woopsy");
p.destroy();
return false;
}
return true;
}// End function executeCMD
} // End class WrapperExe
根据格式的不同,您可以使用JMF(Java媒体框架),它虽然古老且并不是很好,但对于您的目的可能已经足够。
如果它不支持您的格式,您可以使用FFMPEG包装器,如果我记得正确的话,它提供了一个JMF接口,但使用的是FFMPEG:http://fmj-sf.net/ffmpeg-java/getting_started.php
正如其他答案已经建议的那样,ffmeg似乎是最好的解决方案。
这里是我最终使用的代码:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Arrays;
public static File mergeAudioToVideo(
File ffmpegExecutable, // ffmpeg/bin/ffmpeg.exe
File audioFile,
File videoFile,
File outputDir,
String outFileName) throws IOException, InterruptedException {
for (File f : Arrays.asList(ffmpegExecutable, audioFile, videoFile, outputDir)) {
if (! f.exists()) {
throw new FileNotFoundException(f.getAbsolutePath());
}
}
File mergedFile = Paths.get(outputDir.getAbsolutePath(), outFileName).toFile();
if (mergedFile.exists()) {
mergedFile.delete();
}
ProcessBuilder pb = new ProcessBuilder(
ffmpegExecutable.getAbsolutePath(),
"-i",
audioFile.getAbsolutePath(),
"-i",
videoFile.getAbsolutePath() ,
"-acodec",
"copy",
"-vcodec",
"copy",
mergedFile.getAbsolutePath()
);
pb.redirectErrorStream(true);
Process process = pb.start();
process.waitFor();
if (!mergedFile.exists()) {
return null;
}
return mergedFile;
}