ffmpeg does not recognize long string filter in execv

62 Views Asked by At

I am writing some simple python script to call ffmpeg and concat some clips together. However, it doesn't work for reasons I am unable to explain.

below is a working version of the code after some debugging

inputs = sorted(list(askopenfilenames()))
n = len(inputs)

filter = []
for i in range(n):
    filter.append("[{}:v]".format(i))
    filter.append("[{}:a]".format(i))
filter.append("concat={}:v=1:a=1".format(n))
filter.append("[v]")
filter.append("[a]")
filter = " ".join(filter)

fargs = zip(itertools.repeat('-i'), inputs)
fargs = itertools.chain(
    ["ffmpeg"],
    itertools.chain.from_iterable(fargs),
    ["-filter_complex", '"{}"'.format(filter), "-vsync", "vfr", "-map", "[v]", "-map", "[a]"],
    ["-c:v", "libx264", "-crf", "{}".format(quality)],
    ["-c:a", "aac", "-b:a", "192k"],
    [out]
    )

os.execvp("ffmpeg", list(fargs))

but the entire fargs construction causes ffmpeg to complain about the filter chain when quotes are not utilized. e.g. by utilizing the below process

fargs = itertools.chain(
    ["ffmpeg", "-loglevel", "debug"],
    itertools.chain.from_iterable(fargs),
    #["-filter_complex", '"{}"'.format(filter), "-vsync", "vfr", "-map", "[v]", "-map", "[a]"],
    ["-filter_complex", filter, "-vsync", "vfr", "-map", "[v]", "-map", "[a]"],
    ["-c:v", "libx264", "-crf", "{}".format(quality)],
    ["-c:a", "aac", "-b:a", "192k"],
    [out]
    )

we see that ffmpeg somehow sees this as multiple arguments

Reading option '-filter_complex' ... matched as option 'filter_complex' (create a complex filtergraph) with argument '[0:v]'.
Reading option '[0:a]' ... matched as output url.
Reading option '[1:v]' ... matched as output url.
Reading option '[1:a]' ... matched as output url.
Reading option '[2:v]' ... matched as output url.
Reading option '[2:a]' ... matched as output url.
Reading option 'concat=3:v=1:a=1' ... matched as output url.
Reading option '[v]' ... matched as output url.
Reading option '[a]' ... matched as output url.

even though a simple print(list(fargs)) yields

['ffmpeg', '-loglevel', 'debug', '-i', 'a.mp4', '-i', 'b.mp4', '-i', 'c.mp4', '-filter_complex', '[0:v] [0:a] [1:v] [1:a] [2:v] [2:a] concat=3:v=1:a=1 [v] [a]', '-vsync', 'vfr', '-map', '[v]', '-map', '[a]', '-c:v', 'libx264', '-crf', '20', '-c:a', 'aac', '-b:a', '192k', 'asdf.mp4']

implying that the long filter string is being passed to ffmpeg as a single argument.

0

There are 0 best solutions below