This is how I did that.
First merging the input audio files using the below method.
private fun mergeAudios() {
//ffmpeg -i one.mp3 -i two.mp3 -shortest -filter_complex \
//"[0:a]adelay=10000|10000,volume=0.4[a0]; \
// [1:a]volume=5.0[a1]; \
// [a0][a1]amix=inputs=2[out]" \
// -map "[out]" -ac 2 -c:a libfdk_aac output.m4a
val finalAudio =
File(Environment.getExternalStorageDirectory().absolutePath + "/" + System.currentTimeMillis() + ".mp3")
val command = arrayOf(
"-i",
Environment.getExternalStorageDirectory().absolutePath + "/2.mp3",
"-i",
Environment.getExternalStorageDirectory().absolutePath + "/1543575307959.mp3",
"-shortest",
"-filter_complex",
"[0:a]volume=0.4[a0];[1:a]volume=5.0[a1];[a0][a1]amix=inputs=2:duration=shortest",
finalAudio.absolutePath
)
Log.d("ffmpeg", command.contentDeepToString())
ffmpeg.execute(command, object : ExecuteBinaryResponseHandler() {
override fun onFinish() {
super.onFinish()
}
override fun onSuccess(message: String?) {
super.onSuccess(message)
Log.d("ffmpeg", "onSuccess ")
}
override fun onFailure(message: String?) {
super.onFailure(message)
Log.d("ffmpeg", "failure " + message)
}
override fun onProgress(message: String?) {
super.onProgress(message)
Log.d("ffmpeg", "progress " + message)
}
override fun onStart() {
super.onStart()
}
})
}
And then merging the merged audio file with the video file.
private fun mergeAudioVideo() {
val finalVideo =
File(Environment.getExternalStorageDirectory().absolutePath + "/" + System.currentTimeMillis() + ".mp4")
//ffmpeg -i video.mp4 -i audio.wav \
//-c:v copy -c:a aac -strict experimental \
//-map 0:v:0 -map 1:a:0 output.mp4
val command = arrayOf(
"-i",
Environment.getExternalStorageDirectory().absolutePath + "/2.mp4",
"-i",
Environment.getExternalStorageDirectory().absolutePath + "/1543577399776.mp3"
,
"-c:v",
"copy",
"-c:a",
"aac",
"-strict",
"experimental",
"-map",
"0:v:0",
"-map",
"1:a:0",
finalVideo.absolutePath
)
ffmpeg.execute(command, object : ExecuteBinaryResponseHandler() {
override fun onFinish() {
super.onFinish()
}
override fun onSuccess(message: String?) {
super.onSuccess(message)
Log.d("ffmpeg", "onSuccess ")
}
override fun onFailure(message: String?) {
super.onFailure(message)
Log.d("ffmpeg", "failure " + message)
}
override fun onProgress(message: String?) {
super.onProgress(message)
Log.d("ffmpeg", "progress " + message)
}
override fun onStart() {
super.onStart()
}
})
}
Try this if it works for you. You might need some additional flags as your video has no audio files. If the command in the method doesn't work for you, try removing the -map argument for the audio flag
For a single command, this might work. I don't have the complete project to test it now so can't confirm for this one.
fun mergeAudioVideoDirectly(){
val finalVideo =
File(Environment.getExternalStorageDirectory().absolutePath + "/" + System.currentTimeMillis() + ".mp4")
//ffmpeg -i <input1> -i <input2> -filter_complex "[0:a:0][1:a:0]amix[outa]" -map "[0:v:0]" -map ["outa"] <output>
val command = arrayOf(
"-i",
Environment.getExternalStorageDirectory().absolutePath + "/2.mp4",
"-i",
Environment.getExternalStorageDirectory().absolutePath + "/1.mp3",
"-filter_complex",
"[0:a:0][1:a:0]amix[outa]",
"-map",
"0:v:0",
"-map",
"[outa]",
finalVideo.absolutePath
)
Log.d("ffmpeg ","command "+command.contentDeepToString())
ffmpeg.execute(command, object : ExecuteBinaryResponseHandler() {
override fun onFinish() {
super.onFinish()
}
override fun onSuccess(message: String?) {
super.onSuccess(message)
Log.d("ffmpeg", "onSuccess ")
}
override fun onFailure(message: String?) {
super.onFailure(message)
Log.d("ffmpeg", "failure " + message)
}
override fun onProgress(message: String?) {
super.onProgress(message)
}
override fun onStart() {
super.onStart()
}
})
}