I'm creating a wrapper for ffmpeg, and it has the following methods:
fun executeCommand(args: Array<String>): AppRunner.AppResult {
return appRunner.run(ffmpegPath, args)
}
class AppRunner {
fun run(
app: String,
args: Array<String>,
timeoutAmount: Long = 60000,
timeoutUnit: TimeUnit = TimeUnit.SECONDS
): AppResult {
val command = mutableListOf(app)
command.addAll(args)
val processResult = ProcessBuilder(command)
.redirectOutput(ProcessBuilder.Redirect.PIPE)
.redirectError(ProcessBuilder.Redirect.PIPE)
.start()
.apply {
waitFor(timeoutAmount, timeoutUnit)
}
val exitCode = processResult.exitValue()
val stdOut = processResult.inputStream.bufferedReader().readText()
val stdErr = processResult.errorStream.bufferedReader().readText()
return AppResult(exitCode, stdOut, stdErr)
}
}
And:
fun concatenateAudioFiles(files: Collection<File>, outFile: File) {
val args = mutableListOf<String>()
files.forEach { file ->
args.add("-i")
args.add(file.absolutePath)
}
// Create filter
val filterStringBuilder = StringBuilder()
filterStringBuilder.append("'")
files.forEachIndexed { index, _ ->
filterStringBuilder.append("[$index:0]")
}
filterStringBuilder.append("concat=n=")
filterStringBuilder.append(files.size)
filterStringBuilder.append(":v=0:a=1[out]")
filterStringBuilder.append("'")
args.add("-filter_complex")
args.add(filterStringBuilder.toString())
args.add("-map")
args.add("'[out]'")
args.add(outFile.absolutePath)
logger.info { "Filter: ${args.joinToString(" ")}" }
val result = executeCommand(args.toTypedArray())
if (!result.isSuccessful()) {
throw FfmpegException(result.toString())
}
}
Args generated by this method are OK:
-i silence-0.5.mp3 -i vo_1543189276830.mp3 -i silence-0.5.mp3 -filter_complex '[0:0][1:0][2:0]concat=n=3:v=0:a=1[out]' -map '[out]' vo_final_1543189276833.mp3
And if I run ffmpeg with this args from command line it works fine.
But when running within Kotlin app, it gives the following error:
[AVFilterGraph @ 0x7fd134071500] No such filter: '[0:0][1:0][2:0]concat=n=3:v=0:a=1[out]'
Error initializing complex filters.
Invalid argument
I've already tried to:
'
with \
'
with "
Result is the same.
FFMPEG 4.1, Kotlin 1.3, Java 1.8, macOS 10.13.6
Well, the solution is to remove '
at all:
fun concatenateAudioFiles(files: Collection<File>, outFile: File) {
val args = mutableListOf<String>()
files.forEach { file ->
args.add("-i")
args.add(file.absolutePath)
}
// Create filter
val filterStringBuilder = StringBuilder()
files.forEachIndexed { index, _ ->
filterStringBuilder.append("[$index:0]")
}
filterStringBuilder.append("concat=n=")
filterStringBuilder.append(files.size)
filterStringBuilder.append(":v=0:a=1[out]")
args.add("-filter_complex")
args.add(filterStringBuilder.toString())
args.add("-map")
args.add("[out]")
args.add(outFile.absolutePath)
logger.info { "Filter: ${args.joinToString(" ")}" }
val result = executeCommand(args.toTypedArray())
if (!result.isSuccessful()) {
throw FfmpegException(result.toString())
}
}
I'm sure that happens because ProcessBuilder escapes arguments with "
, so they looked like "-filter_complex" "'[0:0][1:0][2:0]concat=n=3:v=0:a=1[out]'"
, and that's wrong.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With