命令在终端上有效,但不适用于Kotlin

时间:2019-09-11 18:00:58

标签: java kotlin cmd ffmpeg

我正在尝试使用FFMPEG命令来连接不同的视频。命令是

ffmpeg -i video.mp4 -i video-2.mp4 -filter_complex "[0:v:0] [0:a:0] [1:v:0] [1:a:0] concat=n=2:v=1:a=1 [v] [a]" -map "[v]" -map "[a]" output.mp4

当我在Windows PowerShell上运行时,此命令运行良好。但是,当我尝试使用Kotlin代码运行时,此方法将无效。

val firstVideo = "D:\\Videos\\ffmpeg\\video.mp4"
val secondVideo = "D:\\Videos\\ffmpeg\\video-2.mp4"
val resultPath = "D:\\Videos\\ffmpeg\\result-2.mp4"

val cmd = "ffmpeg -i $firstVideo -i $secondVideo -filter_complex \"[0:v:0] [0:a:0] [1:v:0] [1:a:0] concat=n=2:v=1:a=1 [v] [a]\" -map \"[v]\" -map \"[a]\" $resultPath"
.split(" ").toTypedArray()

Runtime.getRuntime().exec(cmd)

自从我使用FFMPEG cli以来,我没有收到任何错误消息。

此外,当我尝试运行其他FFMPEG操作时,这款Kotlin可以完美地工作。

1 个答案:

答案 0 :(得分:-1)

结果是实际问题出在 Runtime.getRuntime()。exec()函数之内。我试图调用 waitFor()方法,但是它卡住了。我一直在等。我做了一些研究并阅读了文档。

  

由于某些本机平台仅为标准输入和输出流提供了有限的缓冲区大小,因此未能及时写入子流程的输入流或读取子流程的输出流可能导致子流程阻塞甚至死锁。

这段代码很好用:

fun main(){

   val path1 = "video-1.mp4"
   val path2 = "video-2.mp4"
   val resultPath = "output.mp4"

   val cmd = arrayOf("ffmpeg",
    "-i", path1, "-i", path2,
    "-filter_complex", "[0:v:0][0:a:0][1:v:0][1:a:0]concat=n=2:v=1:a=1[v][a]",
    "-map", "[v]", "-map", "[a]", resultPath)

    executeCommand(cmd)
}

fun executeCommand(cmd: Array<String>){
    try {
       val runtime = Runtime.getRuntime()
       val process = runtime.exec(cmd)
       val errorStream = process.errorStream
       val input = InputStreamReader(errorStream)
       val reader = BufferedReader(input)
       reader.forEachLine {
          println(it);
       }
       process.waitFor()
   } catch (e: Exception) {
       e.printStackTrace();
   }
}

https://www.javaworld.com/article/2071275/when-runtime-exec---won-t.html

https://docs.oracle.com/javase/8/docs/api/java/lang/Process.html