4

首先让我说我对 Java 完全陌生。我来自 PHP 背景,但碰巧我的一项 PHP 任务需要转换为 Java。

任务是使用 ffmpeg 将视频分割成帧,然后使用这些帧。我已经在 PHP 中完成了这个过程。现在我可以将它转换成 Java。

我浏览了一些教程并掌握了基础知识(使用 IDE、运行 java 程序等)。我为此目的使用 Eclipse。

到目前为止,我已经设法通过使用 java 程序来启动 ffmpeg

public static void main(String[] args) throws IOException {

    String livestream = "D:/video.mpg";
    String folderpth = "D:/frames";
    String cmd="D:/ffmpeg/bin/ffmpeg.exe -i "+ livestream +" -r 10 "+folderpth+"/image%d.jpg";

    //System.out.println(cmd);
    Runtime r = Runtime.getRuntime();
    Process p = r.exec(cmd); // this starts creating frames
   // and stores them on local disk
   // any way to store that frame name in array?
   // something like String[] frames = {"image%d.jpg"}
   // so that frames array contains image1.jpg, image2.jpg..and so on?

}

这工作正常,我正在文件夹中获取框架。现在我想做的是在一段时间后终止进程,比如 5 分钟,因为视频超过 2 小时,我不想去任务栏手动终止进程。我还想知道是否有办法将 ffmpeg 创建的帧名称存储到数组中以备将来使用。

我尝试使用p.destroy(),但这并没有停止这个过程。setTimeout()我将如何使用与jQuery 中使用的类似的东西?

一些元数据

操作系统:Windows 7

IDE:日食

4

3 回答 3

3

p.destroy()kill PID在linux上发送。这意味着进程接收到信号但不一定终止。您必须执行kill -9 PID以确保进程确实终止。不幸的是,标准的 java API 没有提供这样的功能,所以你必须自己做。

但这并不复杂。只有 2 个命令:kill用于 Unix 和killtask用于 Windows。两者都接受进程 ID。您可以通过反射发现它:私有 int 字段pid呈现在Process您从中获取的实例的平台特定子类中runtime.exec()

编辑

在 linux 上返回extendsruntime.exec()的实例。我现在没有可用的窗口,无法为您检查它,但据我记得在 Windows 上它返回实例或类似的东西。两者都有可以使用反射提取的私有 int 字段:UnixProcessProcessWindowsProcesspid

Process proc = Rutime.getRuntime().exec("my command");
Field f = proc.getClass().getDeclaredField("pid");
f.setAccessible(true);
int pid = (Integer)f.get(proc);
于 2013-02-19T07:36:49.633 回答
0

我认为 Apache 看门狗会帮助你。它在给定的时间内等待执行。如果时间超过给定时间,它将终止该过程。它在commons exec中可用

示例代码:

ExecuteWatchdog watchdog = new ExecuteWatchdog(1000*60*5);
Process process= Runtime.getRuntime().exec("cmd");
watchdog.start(process);
于 2013-02-19T07:48:08.203 回答
0

一种简单的方法是使用java.util.Timerjava.util.TimerTask将计时器设置为 5 分钟(或您感兴趣的任何持续时间),并且计时器任务将在计时器关闭时获取进程句柄来杀死它并触发定时器任务。

于 2013-02-19T07:34:42.660 回答