question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

create a new filter with a specific signature selecting a subset of actual ffmpeg filter args?

See original GitHub issue

Apologies for what might be an incredibly dumb or obvious question: I’m new here. I was thinking about trying to add a ‘fade’ filter – as much to learn the interface and repo as anything else… then my usecase morphed a little bit into something more like “What if I wanted to implement a filter that exposed a subset of the arguments or mangled them in a specific way?”. A couple of illustrative examples might be:

  • implement a fadeByTime filter, where the signature was something like: def fadeByTime(stream, direction=in, offset=0, fade_len=0, **kwargs) – but in my contrived example, the offset and duration would be interpreted in seconds rather than in frames… In the code I would then map the inputs of this function to the actual ffmpeg fade filter with the arguments {t=direction, st=offset, d=fade_len}

In much more general terms, I guess I’m asking how this library knows or decides that some parameters for some filters are position and some appear to be defined by keywords.

https://ffmpeg.org/ffmpeg-filters.html#fade

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
kkroeningcommented, Jan 23, 2019

In short:

  • Every kind of operator (input, output, filter) produces a certain kind of Node instance.
  • A node refers to a set of upstream parent nodes along with any additional metadata. For example, an input node has no parents, and a filter node can have one or more parents (e.g. an input node or other filter nodes).
  • Nodes are immutable: once created, they contain all the metadata and reference all the other upstream nodes.
  • Adding additional nodes to the graph simply consists of making more node(s) that reference other upstream node(s), similar to how a git repository keeps track of history with commits that point to parent commit(s) (which in turn point to other parent commits and so on, maintaining the entire history of the repo).
  • Together, a set of nodes represents an ffmpeg signal graph as a directed acyclic graph (DAG). (Again, think of git and how it forms a DAG from immutable commits)
  • Once the entire signal graph is built (using a combination of ffmpeg.input / .filter / .output / etc), it can be compiled into the corresponding ffmpeg command-line arguments using ffmpeg.compile (which ffmpeg.run uses internally).
  • Compilation consists of a topological sort of the DAG. The graph is traversed in a topologically sorted order and sequentially converted into a linear sequence of command-line snippets, in the same way that a programming language compiler converts an abstract syntax tree (AST) into machine code. One can think of the ffmpeg-python signal graph / DAG as an AST and most of the concepts map accordingly.
  • Care is taken during compilation to allocate unique stream identifiers to be used in the -filter_complex command-line argument (e.g. the things that show up as e.g. [s0], [s1], etc.
  • The end result is that the signal graph DAG/AST is compiled into a set of ffmpeg command-line arguments.

A key thing to note is that everything in this design is functional/immutable: constructing a graph consists of creating nodes that refer to other nodes, and then compiling the graph into ffmpeg command-line arguments is a pure function that takes a graph (downstream leafnode references) and produces a set of strings.

Useful background info might be to look at simple compiler/AST examples on the web to understand some of the compilation concepts.

Does this explanation help?

(At some point this info/explanation should probably be copied into some actual docs somewhere, so feedback on the above explanation is helpful)

1reaction
153957commented, Jan 3, 2019

If you want to implement your own function to apply the fade filter to an input you can do it like this:

def fade_by_time(stream, type, start_time, duration):
    return stream.filter('fade', type=type, start_time=start_time, duration=duration)

But maybe I misunderstand and you really want to add your own filter operators, in which case I would suggest your just look at other implemented filters in the filter module, for example: https://github.com/kkroening/ffmpeg-python/blob/master/ffmpeg/_filters.py#L216

Read more comments on GitHub >

github_iconTop Results From Across the Web

FFmpeg Filters Documentation
Some filters take in input a list of parameters: they are specified after the filter name and an equal sign, and are separated...
Read more >
FFmpeg filters
Some filters take in input a list of parameters: they are specified after the filter name and an equal sign, and are separated...
Read more >
FFmpeg: possible to apply filter to only part of a video file ...
How do I flip only a subsection of a video using ffmpeg ? Here, -filter_complex is your friend, as it can create chains...
Read more >
3 Common Tasks
Check Existing Layers: Before creating a new layer, you should be sure ... that building for a particular machine affects only the signature...
Read more >
How to download portion of video with youtube-dl command?
I don't believe youtube-dl alone will do what you want. However you can combine it with a command line utility like ffmpeg. First...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found