使用 Java FFmpeg 包装器,还是简单地使用 Java 运行时来执行 FFmpeg?

问题描述 投票:0回答:9

我对 Java 还很陌生,需要编写一个程序来监听视频转换指令,并在新指令到达时转换视频。 (说明存储在 Amazon SQS 中,但这与我的问题无关)

我面临一个选择,要么使用 Java 运行时执行 FFmpeg 转换(如从命令行),要么使用用 Java 编写的 FFmpeg 包装器。

http://fmj-sf.net/ffmpeg-java/getting_started.php

我更喜欢使用 Java 运行时直接执行 FFmpeg,并避免使用 java-ffmpeg 包装器,因为我必须学习该库。

所以我的问题是:使用 java-ffmpeg 包装器比直接使用运行时执行 FFmpeg 有什么好处吗?

我不需要FFmpeg来播放视频,只需转换视频即可。

java ffmpeg runtime.exec
9个回答
39
投票

如果我没记错的话,您链接到的“ffmpeg-wrapper”项目已经过时并且没有维护。 FFmpeg 是一个非常活跃的项目,一直在进行大量更改和发布。

您应该查看 Xuggler 项目,它为您想要做的事情提供了一个 Java API,并且它们与 FFmpeg 紧密集成。

http://www.xuggle.com/xuggler/

如果您选择走

Runtime.exec()
路径,这个 Red5 线程应该很有用:

http://www.nabble.com/java-call-ffmpeg-ts15886850.html


27
投票

我也在寻找用 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();

24
投票

有很多 Java 库提供 FFMPEG 包装器。 然而,不幸的是,这些库中的大多数都已经过时,并且使用旧的 FFMPEG 版本,这些版本缺乏一些重要的编解码器(例如 Xuggler、humble video、JavaAV、JavaAVC 和 jave)。 所以使用这些项目时要小心!

但是,有一种 FFMPEG 包装器仍在“积极开发中”并支持 FFMPEG 4:

    JavaCPP FFMPEG
  • - 具有完全捆绑的 Maven 工件
  • 您也可以使用 FFMPEG 命令行界面的包装器,例如
ffmpeg-cli-wrapper

。 然后您就可以手动更新 ffmpeg,而无需等待包装器库的新版本。


15
投票
Jaffree

。它可与 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();



8
投票


4
投票
http://www.sauronsoftware.it/projects/jave


3
投票


0
投票


0
投票
GitHub 上的此项目

以下是如何使用

org.bytedeco.ffmpeg

库中的 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) } } }

	
© www.soinside.com 2019 - 2024. All rights reserved.