u2takey / ffmpeg-go

golang binding for ffmpeg
Apache License 2.0
1.66k stars 167 forks source link

How do you bring `palettegen` output variable to `paletteuse` filter? #76

Closed YamiOdymel closed 1 year ago

YamiOdymel commented 1 year ago

I'm trying to generate a palette for GIF to keep it's transparency by using palettegen and paletteuse.

ffmpeg-go automatically generated [s0] and [s1] for me.

[s0]palettegen=reserve_transparent=on:transparency_color=ffffff[s1];[s1]paletteuse[s2]

But the command won't run, because paletteuse should takes 2 input arguments: [input][palette]

(error: Cannot find a matching stream for unlabeled input pad 1 on filter Parsed_paletteuse_2)

The corrected compiled filter should look like this:

[s0]palettegen=reserve_transparent=on:transparency_color=ffffff[p];[s1][p]paletteuse[s2]
                                                                ^       ^

But I can't get it work with ffmpeg-go because the input.Filter escapes my variable placeholder.

[s0]palettegen=reserve_transparent=on:transparency_color=ffffff\[p\][s1];[s1]\[p\]paletteuse[s2]
                                                                 ^             ^

My code

input.Filter("palettegen", ffmpeg.Args{"reserve_transparent=on", "transparency_color=ffffff[p]"})
input.Filter("[p]paletteuse", ffmpeg.Args{})

It seems that ffmpeg-python supports multi-input for a single filter:

https://github.com/kkroening/ffmpeg-python/issues/193

YamiOdymel commented 1 year ago

Problem solved

split := input.Split()
split1, split2 := split.Get("0"), split.Get("1")

ffmpeg.Filter(
    []*ffmpeg.Stream{
        split1,
        split2.Filter("palettegen", ffmpeg.Args{}, ffmpeg.KwArgs{
            "reserve_transparent": "on",
            "transparency_color":  "ffffff",
        }),
    }, "paletteuse", ffmpeg.Args{}).Output(path).OverWriteOutput().ErrorToStdOut().Run()

and it generates something like this

[s2]split=2[s3][s4];[s4]palettegen=reserve_transparent=on:transparency_color=ffffff[s5];[s3][s5]paletteuse[s6]