我正在尝试使用 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 非常有效。
最佳答案
事实证明,实际问题出在 Runtime.getRuntime().exec() 函数中。我试图调用 waitFor() 方法,但它卡住了。我一直在等待。我做了一些研究并阅读了文档。
Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, or even deadlock.
这段代码工作得很好:
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
关于java - 命令适用于终端,但不适用于 Kotlin,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57894508/