ffmpeg:在具有自定义透明度的视频上叠加 png 图像?

ffmpeg: overlay a png image on a video with custom transparency?

假设我有一个视频 foo.mkv 和一个图像 bar.png(恰好包含一个 alpha 通道)。我可以像这样将此图像混合到视频中:

ffmpeg 
 -i foo.mkv 
 -i bar.png 
 -filter_complex "[0:v][1:v]overlay" 
 -vcodec libx264 
 myresult.mkv

(为了便于阅读,这里使用多行,通常这是一个命令行)。

现在,除了 png 图像有自己的 alpha 通道外,我还会在视频上混合此图像时应用自定义 整体透明度

在上面的示例中,图像将在视频顶部 100% 可见——或者至少是其 Alpha 通道完全不透明的部分。

有没有办法添加自定义的整体不透明度或透明度混合因子,例如 opacity=0.5 或其他任何东西,这将使图像只有 50% 可见?

我想我明白了:

ffmpeg 
 -i foo.mkv 
 -i bar.png 
 -filter_complex "[1:v]format=argb,geq=r='r(X,Y)':a='0.5*alpha(X,Y)'[zork]; 
   [0:v][zork]overlay" 
 -vcodec libx264 
 myresult.mkv

其中 0.5 是不透明度系数。我包括 format=argb,因此它也适用于本身没有 alpha 通道的叠加图像。

geq之外的另一个选项是colorchannelmixer

[1:v]format=argb,colorchannelmixer=aa=0.5[zork]

使用此函数在 FFmpeg 视频中叠加具有透明度的图像 Android

fun addimagemerge(inputVideo: String, imageInput: String, output: String): Array<String> {
    val inputs: ArrayList<String> = ArrayList()
    inputs.apply {
        add("-i")
        add(inputVideo)
        add("-i")
        add(imageInput)
        add("-filter_complex")
        add("[1:v]format=argb,geq=r='r(X,Y)':a='0.5*alpha(X,Y)'[zork]; [0:v][zork]overlay")
        add("-preset")
        add("ultrafast")
        add(output)
    }
    return inputs.toArray(arrayOfNulls<String>(inputs.size))
}

将其用于转换按钮上的调用函数

val outputPath = getFilePath(this, VIDEO)
  
    val query = ffmpegQueryExtension.addimagemerge(
        selectedVideoPath!!,
        selectedImagePath!!,
        outputPath
    )

    CallBackOfQuery().callQuery(this, query, object : FFmpegCallBack {
        override fun process(logMessage: LogMessage) {

            runOnUiThread {
                tvOutputPath.text = logMessage.text
            }
        }

        override fun success() {
            tvOutputPath.text = String.format(getString(R.string.output_path), outputPath)
            processStop()
            runOnUiThread {
                videoPlayclass.stopVideoPlay(bottmLay, videoPlayAct)
                videoPlayclass.videoPlayStart(
                    this@MergeImageVideoActivity,
                    bottmLay,
                    videoPlayAct,
                    outputPath
                )
            }
        }

        override fun cancel() {
            processStop()
        }

        override fun failed() {
            processStop()
        }
    })