FFMPEG: using video filter with complex filter
Asked Answered
S

2

13

I'm using the fluent-ffmpeg Node.js library to perform batch manipulations on video files. The video filter which crops a 16:9 input, adds padding and burns subtitles into the padding.

In the next step, I would like to use a complex filter to overlay an image as a watermark.

ff.input(video.mp4)
ff.input(watermark.png)
ff.videoFilter([
  'crop=in_w-2*150:in_h',
  'pad=980:980:x=0:y=0:color=black',
  'subtitles=subtitles.ass'
])
ff.complexFilter([
  'overlay=0:0'
])
ff.output(output.mp4)

However, running this, I get the following error:

Filtergraph 'crop=in_w-2*150:in_h,pad=980:980:x=0:y=0:color=black,subtitles=subtitles.ass' was specified through the -vf/-af/-filter option for output stream 0:0, which is fed from a comple.
-vf/-af/-filter and -filter_complex cannot be used together for the same stream.

From what I understand the video filter and complex filter options can't be used together. How does one get around this?

Spittoon answered 1/4, 2019 at 13:8 Comment(2)
You will have to put the overlay filter in one filter only. You cannot use 2 filtergraphs in ffmpeg in the same command. Try to study the complex filtergraphs and match your stream accordingly to the overlay filter.Dumpling
You can use multiple complex filtergraphs in the same command. You just can't refer to intermediate or output streams, created in one graph, in the other graphs.Oraleeoralia
S
45

Solved this by learning some basics about filter graphs. Here's the full ffmpeg command. I find the filter strings easier to read when they are written out line-by-line.

ffmpeg \
-i video.mp4 \
-i watermark.png \
-filter_complex " \
  [0]crop = \
    w = in_w-2*150 : \
    h = in_h \
    [a] ;
  [a]pad = \
    width = 980 : \
    height = 980 : \
    x = 0 :
    y = 0 :
    color = black
    [b] ;
  [b]subtitles = 
    filename = subtitles.ass
    [c] ;
  [c][1]overlay = \
    x = 0 :
    y = 0
  " \
output.mp4

Explanation:

[0]crop=...[a]; => Begin by applying crop filter to video input 0. Name the result a.

[a]pad=...[b]; => Apply the pad filter to the a stream. Name the result b.

[b]subtitles=...[c] => Apply the subtitles filter to the b stream. Name the result c.

[c][1]overlay... => Apply the overlay filter to stream c using input 1 (the png file).

Hope this helps someone struggling with filter graphs.

Spittoon answered 1/4, 2019 at 20:29 Comment(4)
The filters that have a single input/output can be joined by commas which can simplify the command somewhat because you can omit unnecessary labeling such as [0]crop,pad[bg];[bg][1]overlay,subtitles or [0]crop,pad,subtitles[bg];[bg][1]overlay.Screw
Your Q is about fluent-ffmpeg syntax. This answer relates to ffmpeg CLI syntax.Oraleeoralia
Yes, but the filter graph was the issue.Spittoon
Do you have the fluent-ffmpeg version?Deon
D
8

simple syntax with 3 logos and 1 text scroll

ffmpeg
    .complexFilter([

        {
            filter: 'overlay',
            options: { x: 100, y: 100 },
            inputs: 0, outputs: '1'

        },
        {
            filter: 'overlay',
            options: { x: 200, y: 200 },
            inputs: '1', outputs: '2'

        },
        {
            filter: 'overlay',
            options: { x: 300, y: 300 },
            inputs: '2', outputs: '3'

        },
        {
            filter: 'drawtext',
            options: {
            // outputs: 1,
            fontfile:'/usr/share/fonts/dejavu/DejaVuSans.ttf',
            text: 'some text',
            fontsize: 40,
            fontcolor: 'white',
            x: 'w-w/10*mod(t,10*(w+tw)/w)',
            y: 'h-line_h',
            shadowcolor: 'black',
            shadowx: 3,
            shadowy: 3,
            },
            inputs: '3',
          },
        ])
Dunno answered 4/9, 2019 at 3:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.