By my count Lensley is going into year 8 (jeez) but despite working with all kinds of image and video processing over the years, I only just finally got around to sitting down and grokking ffmpeg’s filter_complex
this past week.
While it’s conceptually simple, the syntax documentation is rather dense and unintuitive. Web searches will let you find how to do any number of things, and you can hack your way for most stuff (in the past I’ve used h264_mp4toannexb
, various intermediates, and concats to chain things together for example), but recently I found two writeups that were particularly useful in breaking down how -filter_complex
works:
- This Stack Overflow answer does a great job breaking down the exact construction of a relatively simple multi-stream complex filtergraph
- This slightly more complex example w/ a nice graph chart is also good
One thing to note is that image2’s frame inputs remain stubbornly limiting and it’s tempting to simply do image manipulation externally to pass in, but doing it all in ffmpeg was at least 10x better performance than using ImageMagick for preprocessing. ffmpeg is just stupidly fast. I simply end up writing temporary symlinks and calling the ffmpeg bin, but you can also now conceivably use PyAV in Python which has just recently added filtergraph access to its libffmpeg/libav bindings.
Related: fantastic writeup of optimizing animated GIFs w/ ffmpeg
Another recent “I probably should have sat down and figured this out years ago” moment was finally figuring out single-line multi-hops. I’ve been an “intermediate” level SSH user for a while now, figuring out SOCKS proxying and autossh-based tunneling a long while back. All our Lensley machines automatically reverse tunnel to our config servers and I have both ssh configs and various portmapping scripts to make connecting relatively easy.
However, my access (whether it be connections, port forwarding, or file copying) has always required an extra step for chaining until I stumbled on a post about multi-hop proxying. Now that particular description is confusing as hell, but the secret is in the -t
part of the command. Here’s a much clearer description. So now I have a script that lets me connect to a reverse tunneled machine in one command that looks something like:
ssh -t server ssh -t localhost -p $port
Of course, there’s more than one way to skin a cat, and it looks like OpenSSH 7.3, released just a few days ago, has just added a ProxyJump command that makes life easier.
That script I wrote also tests first to see if a machine is available on the local network using curl
(better than ping
I think. netcat -z
would be preferable but even w/ time-out set to 1, it always takes 5 seconds to time out):
curl --silent --fail --show-error --connect-timeout 1 http://$host.local:22/ 2>&1 | grep timed