我对 Java 还很陌生,需要编写一个程序来监听视频转换指令,并在新指令到达时转换视频。 (说明存储在 Amazon SQS 中,但这与我的问题无关)
我面临一个选择,要么使用 Java 运行时执行 FFmpeg 转换(如从命令行),要么使用用 Java 编写的 FFmpeg 包装器。
http://fmj-sf.net/ffmpeg-java/getting_started.php
我更喜欢使用 Java 运行时直接执行 FFmpeg,并避免使用 java-ffmpeg 包装器,因为我必须学习该库。
所以我的问题是:使用 java-ffmpeg 包装器比直接使用运行时执行 FFmpeg 有什么好处吗?
我不需要FFmpeg来播放视频,只需转换视频即可。
如果我没记错的话,您链接到的“ffmpeg-wrapper”项目已经过时并且没有维护。 FFmpeg 是一个非常活跃的项目,一直在进行大量更改和发布。
您应该查看 Xuggler 项目,它为您想要做的事情提供了一个 Java API,并且它们与 FFmpeg 紧密集成。
http://www.xuggle.com/xuggler/
如果您选择走
Runtime.exec()
路径,这个 Red5 线程应该很有用:
我也在寻找用 Java 封装 FFMPEG 的东西。在搜索时,我发现了这个:https://github.com/bramp/ffmpeg-cli-wrapper。
到今天为止,好像一个月前就已经修改过了。所以,希望它能坚持一段时间。
他们文档中的示例:
FFmpeg ffmpeg = new FFmpeg("/path/to/ffmpeg");
FFprobe ffprobe = new FFprobe("/path/to/ffprobe");
FFmpegBuilder builder = new FFmpegBuilder()
.setInput(in)
.overrideOutputFiles(true)
.addOutput("output.mp4")
.setFormat("mp4")
.setTargetSize(250000)
.disableSubtitle()
.setAudioChannels(1)
.setAudioCodec("libfdk_aac")
.setAudioRate(48000)
.setAudioBitrate(32768)
.setVideoCodec("libx264")
.setVideoFramerate(Fraction.getFraction(24, 1))
.setVideoResolution(640, 480)
.setStrict(FFmpegBuilder.Strict.EXPERIMENTAL)
.done();
FFmpegExecutor executor = new FFmpegExecutor(ffmpeg, ffprobe);
executor.createTwoPassJob(builder).run();
。它可与 ffprobe 和 ffmpeg 配合使用,并支持程序化视频制作和消费。 我认为它还有更方便的流体 API。 这是一个 ffprobe 使用示例:
FFprobeResult result = FFprobe.atPath(BIN)
.setInputPath(VIDEO_MP4)
.setShowStreams(true)
.setShowError(true)
.execute();
if (result.getError() != null) {
//TODO handle ffprobe error message
return;
}
for (Stream stream : probe.getStreams().getStream()) {
//TODO analyze stream data
}
ProgressListener listener = new ProgressListener() {
@Override
public void onProgress(FFmpegProgress progress) {
//TODO handle progress data
}
};
这是针对 ffmpeg 的:
FFmpegResult result = FFmpeg.atPath(BIN)
.addInput(Input.fromPath(VIDEO_MP4))
.addOutput(Output.toPath(outputPath)
.addCodec(null, "copy")
)
.setProgressListener(listener)
.execute();
库中的 FFmpeg 和 FFprobe。 添加所需操作系统的依赖项(请参阅
此处了解支持的操作系统):
// The main artifact
implementation("org.bytedeco:ffmpeg:6.1.1-1.5.10")
// The Jar artifact containing executables for the desired OS
implementation("org.bytedeco:ffmpeg:6.1.1-1.5.10:windows-x86_64-gpl")
// OR using Gradle version catalogs
// implementation(libs.ffmpeg)
// implementation(variantOf(libs.ffmpeg) { classifier("windows-x86_64-gpl") })
Java:
import org.bytedeco.ffmpeg.ffmpeg;
import org.bytedeco.javacpp.Loader;
// ...
public class Test {
private final String ffmpegPath = Loader.load(ffmpeg.class);
public void executeFFmpeg() throws IOException {
var ffmpegProcess = new ProcessBuilder()
.command(
ffmpegPath,
// OR any options you would pass to FFmpeg CLI
"-i", "/absolute/path/to/video.mp4"
)
.start();
try (var reader = new BufferedReader(new InputStreamReader(ffmpegProcess.getErrorStream()))) {
reader
.lines()
.forEach(System.out::println);
}
}
}
科特林:
import org.bytedeco.ffmpeg.ffmpeg
import org.bytedeco.javacpp.Loader
// ...
class Test() {
private val ffmpegPath = Loader.load(ffmpeg::class.java)
fun executeFFmpeg() {
ProcessBuilder()
.command(ffmpegPath, "-i", "absolute/path/to/video.mp4")
.runCatching { start() }
.onFailure { println("Starting the FFmpeg process for probing failed") }
.getOrNull()
?.errorStream
?.reader()
?.useLines { lines -> lines.forEach(::println) }
}
}