使用 java-ffmpeg 包装器,还是简单地使用 java 运行时来执行 ffmpeg?
Posted
技术标签:
【中文标题】使用 java-ffmpeg 包装器,还是简单地使用 java 运行时来执行 ffmpeg?【英文标题】:use java-ffmpeg wrapper, or simply use java runtime to execute ffmpeg? 【发布时间】:2010-11-19 20:41:48 【问题描述】:我对 Java 很陌生,需要编写一个程序来监听视频转换指令并在新指令到达时转换视频(指令存储在 Amazon SQS 中,但这与我的问题无关)
我面临一个选择,要么使用 Java RunTime 执行 'ffmpeg' 转换(如从命令行),要么我可以使用用 Java http://fmj-sf.net/ffmpeg-java/getting_started.php 编写的 ffmpeg 包装器
我更喜欢使用 Java Runtime 直接执行 ffmpeg,并避免使用 java-ffmpeg 包装器,因为我必须学习该库。所以我的问题是直接使用运行时使用 java-ffmpeg 包装器而不是 exec ffmpeg 有什么好处吗?我不需要ffmpeg来播放视频,只需转换视频即可
谢谢
【问题讨论】:
【参考方案1】:使用包装器的好处主要是它提供了更多和细粒度的功能,这些功能无法通过命令行访问(与您无关),并且使错误处理和状态控制更容易 - 您必须解析命令line 工具的标准输出和错误流。
【讨论】:
【参考方案2】:如果我没记错的话,您链接到的“ffmpeg 包装器”项目已过时且未维护。 ffmpeg 是一个非常活跃的项目,一直有很多变化和发布。
你应该看看 Xuggler 项目,它为你想要做的事情提供了一个 Java API,并且它们与 ffmpeg 紧密集成。
http://www.xuggle.com/xuggler/
如果你选择走 Runtime.exec() 路径,这个 Red5 线程应该很有用:
http://www.nabble.com/java-call-ffmpeg-ts15886850.html
【讨论】:
只是简要查看了 xuggler 文档,这正是我所需要的。感谢您的帮助! 太棒了。请注意,它是 GPL,您可能需要在生产中获得商业许可。 实际上 Xuggler 现在是 LGPL(虽然如果与 libx264 一起使用它将是 GPL) Xuggler 现在处于中断状态。 xuggle.com/xuggler/statusgithub.com/artclarke/xuggle-xuggler 看起来这已经过时了【参考方案3】:此外,从 Xuggler 3.3 开始,Xuggler 是 LGPL,这意味着您不需要商业许可。
【讨论】:
是否支持将图片和mp3转成视频文件?谢谢【参考方案4】:你可以试试jave http://www.sauronsoftware.it/projects/jave
【讨论】:
JAVE 之所以好的只是因为它为所有主流平台捆绑了ffmpeg
二进制文件。然而,他们的 Java API 是一团糟。【参考方案5】:
我也在寻找用 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 去 github 上的网站你会看到一个例子 该库不支持终止子进程(如果您希望从屏幕上捕获视频),也不会将进程公开给客户端。鉴于ffmpeg
有很好的文档记录,您最好通过java.lang.Process
API 手动运行ffmpeg
。【参考方案6】:
有很多提供 FFMPEG 包装器的 Java 库。然而,不幸的是,这些库中的大多数已经过时并且使用缺少一些重要编解码器的旧 FFMPEG 版本(例如 Xuggler、Humble video、JavaAV、JavaAVC 和 jave)。所以在使用这些项目时要小心!
但是,还有一个 FFMPEG 包装器仍在积极开发并支持 FFMPEG 4:
JavaCPP FFMPEG - 包含完全捆绑的 maven artefacts或者,您可以为 FFMPEG 的命令行界面使用包装器,例如 ffmpeg-cli-wrapper。然后,您可以手动更新 ffmpeg,而无需等待包装库的新版本。
【讨论】:
【参考方案7】:我尝试了几种方法,对我来说最简单的是ffmpeg-cli-wrapper,因为它使用默认的ffmpeg或特定的,而且你可以配置很多配置,如比例,比特率......获取持续时间...... JAVE来自sauronsoftware 出错很多,XUGGLE 等我觉得太复杂了
【讨论】:
【参考方案8】:我编写了自己的 Java ffmpeg 命令行包装器: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();
【讨论】:
您好,当ffprobe xsd 切换每个ffmpeg 版本时,如何管理java 接口库?附言我的方法与您的方法相似,但这个问题让我坚持使用一个特定的 ffmpeg 版本。 我只在最新的ffmpeg版本上测试过,有一个选项“位精确输出”。以上是关于使用 java-ffmpeg 包装器,还是简单地使用 java 运行时来执行 ffmpeg?的主要内容,如果未能解决你的问题,请参考以下文章
简单的匿名管道 - 您使用啥包装器模型? (WinAPI, C++)