我有两个视频剪辑。两者都是 640x480,最后 10 分钟。一个包含背景音频,另一个包含歌唱演员。我想创建一个尺寸为 1280x480 的 10 分钟视频剪辑(换句话说,我想将视频彼此相邻放置并同时播放它们,混合两个剪辑的音频)。我试图弄清楚如何使用 ffmpeg/avidemux 来做到这一点,但到目前为止我一无所获。当我搜索合并时,它们都指的是连接。
有什么建议吗?
答案1
老实说,使用接受的答案导致我丢了很多帧。
然而,使用hstack
filter_complex 产生了完美的流体输出:
ffmpeg -i left.mp4 -i right.mp4 -filter_complex hstack output.mp4
答案2
ffmpeg \
-i input1.mp4 \
-i input2.mp4 \
-filter_complex '[0:v]pad=iw*2:ih[int];[int][1:v]overlay=W/2:0[vid]' \
-map '[vid]' \
-c:v libx264 \
-crf 23 \
-preset veryfast \
output.mp4
input1.mp4
这实际上是通过用与原始视频大小相同的黑色填充右侧来使大小加倍,然后input2.mp4
使用覆盖过滤器放置在该黑色区域的顶部。
来源:https://superuser.com/questions/153160/join-videos-split-screen
答案3
答案4
等级依赖
implementation "com.writingminds:FFmpegAndroid:0.3.2"
代码
将两个视频并排连接成一个的命令
val cmd : arrayOf("-y", "-i", videoFile!!.path, "-i", videoFileTwo!!.path, "-filter_complex", "hstack", outputFile.path)
将两个视频(一个接一个)附加到一个视频中的命令
val cmd : arrayOf("-y", "-i", videoFile!!.path, "-i", videoFileTwo!!.path, "-strict", "experimental", "-filter_complex",
"[0:v]scale=iw*min(1920/iw\\,1080/ih):ih*min(1920/iw\\,1080/ih), pad=1920:1080:(1920-iw*min(1920/iw\\,1080/ih))/2:(1080-ih*min(1920/iw\\,1080/ih))/2,setsar=1:1[v0];[1:v] scale=iw*min(1920/iw\\,1080/ih):ih*min(1920/iw\\,1080/ih), pad=1920:1080:(1920-iw*min(1920/iw\\,1080/ih))/2:(1080-ih*min(1920/iw\\,1080/ih))/2,setsar=1:1[v1];[v0][0:a][v1][1:a] concat=n=2:v=1:a=1",
"-ab", "48000", "-ac", "2", "-ar", "22050", "-s", "1920x1080", "-vcodec", "libx264", "-crf", "27",
"-q", "4", "-preset", "ultrafast", outputFile.path)
笔记:
“videoFile”是您的第一个视频路径。
“videoFileTwo”是您的第二个视频路径。
“outputFile”是您的组合视频路径,这是我们的最终输出路径
创建视频输出路径
fun createVideoPath(context: Context): File {
val timeStamp: String = SimpleDateFormat(Constant.DATE_FORMAT, Locale.getDefault()).format(Date())
val imageFileName: String = "APP_NAME_"+ timeStamp + "_"
val storageDir: File? = context.getExternalFilesDir(Environment.DIRECTORY_MOVIES)
if (storageDir != null) {
if (!storageDir.exists()) storageDir.mkdirs()
}
return File.createTempFile(imageFileName, Constant.VIDEO_FORMAT, storageDir)
}
执行命令的代码
try {
FFmpeg.getInstance(context).execute(cmd, object : ExecuteBinaryResponseHandler() {
override fun onStart() {
}
override fun onProgress(message: String?) {
callback!!.onProgress(message!!)
}
override fun onSuccess(message: String?) {
callback!!.onSuccess(outputFile)
}
override fun onFailure(message: String?) {
if (outputFile.exists()) {
outputFile.delete()
}
callback!!.onFailure(IOException(message))
}
override fun onFinish() {
callback!!.onFinish()
}
})
} catch (e: Exception) {
} catch (e2: FFmpegCommandAlreadyRunningException) {
}