【发布时间】:2019-09-18 13:45:18
【问题描述】:
我想从我的代码中启动一个 ffmpeg 进程,然后处理结果输出。 ffmpeg 进程将打印出进度信息,我想将该信息发送回另一个应用程序。
我正在尝试使用 ProcessBuilder API 来实现这一点。基于这个答案ProcessBuilder: Forwarding stdout and stderr of started processes without blocking the main thread我尝试了以下代码
@Service
class ProcessExecutorService(@Autowired private val configProps: AppConfigurationProperties) {
private val logger: Logger = Logger.getLogger(ProcessExecutorService::class.qualifiedName)
fun execute(command: List<String>): Int {
logger.info("Executing command $command")
val processBuilder = ProcessBuilder()
processBuilder.command(command)
processBuilder.directory(File(configProps.encoding.workDirectory))
val process = processBuilder.start()
Thread(StreamGobbler(process.inputStream, logger::info)).start()
return process.waitFor()
}
inner class StreamGobbler(private val inputStream: InputStream, private val consumer: (String) -> Unit): Runnable {
override fun run() {
BufferedReader(InputStreamReader(inputStream) as Reader)
.lines()
.forEach(consumer)
}
}
}
但这不会记录任何输出。当我把它改成做
@Service
class ProcessExecutorService(@Autowired private val configProps: AppConfigurationProperties) {
private val logger: Logger = Logger.getLogger(ProcessExecutorService::class.qualifiedName)
fun execute(command: List<String>): Int {
logger.info("Executing command $command")
val processBuilder = ProcessBuilder()
processBuilder.command(command)
processBuilder.directory(File(configProps.encoding.workDirectory))
processBuilder.inheritIO()
val process = processBuilder.start()
return process.waitFor()
}
}
然后我看到了 ffmpeg 输出,但我无法对这个输出做任何有用的事情。
关于为什么第一种方法可能不起作用的任何建议?
【问题讨论】:
-
是 Kotlin,不是吗?
-
在第一种情况下,BufferedReader 是否正确关闭? (如果没有,它可能有未刷新的数据,这可以解释为什么你没有看到它。)我会尝试使用 Kotlin 扩展 forEachLine() 或 useLines() 而不是 Java 流 useLines(),因为它们应该会自动关闭信息流。
-
我尝试了这个建议,但我仍然没有看到输出。
标签: spring kotlin processbuilder