The thing that helped me get over that ffmpeg bump, where you go from copying stack overflow answers to actually sort of understanding what you are doing is the fairly recent include external file syntax. On the surface it is such a minor thing, but mentally it let me turn what was a confusing mess into a programing language. There are a couple ways to evoke it but the one I used was to load the whole file as an arg. Note the slash, it is important "-/filter_complex filter_file"
https://ffmpeg.org/ffmpeg-filters.html#toc-Filtergraph-synta...
"A special syntax implemented in the ffmpeg CLI tool allows loading option values from files. This is done be prepending a slash ’/’ to the option name, then the supplied value is interpreted as a path from which the actual value is loaded."
For how critical that was to getting over my ffmpeg hump, I wish it was not buried halfway through the documentation, but also, I don't know where else it would go.
And just because I am very proud of my accomplishment here is the ffmpeg side of my project, motion detection using mainly ffmpeg, there is some python glue logic to watch stdout for the events but all the tricky bits are internal to ffmpeg.
The filter(comments are added for audience understanding):
[0:v]
split #split the camera feed into two parts, passthrough and motion
[vis],
scale= #scale the motion feed way down, less cpu and it works better
w=iw/4:
h=-1,
format= #needed because blend did not work as expected with yuv
gbrp,
tmix= #temporial blur to reduce artifacts
frames=2,
[1:v] #the mask frame
blend= #mask the motion feed
all_mode=darken,
tblend= #motion detect actual, the difference from the last frame
all_mode=difference,
boxblur= #blur the hell out of it to increase the number of motion pixels
lr=20,
maskfun= #mask it to black and white
low=3:
high=3,
negate, #make the motion pixels black
blackframe= #puts events on stdout when too many black pixels are found
amount=1
[motion]; #motion output
[vis]
tpad= #delay pass through so you get the start of the event when notified
start=30
[original]; #passthrough output
and the ffmpeg evocation: ff_args = [
'ffmpeg',
'-nostats',
'-an',
'-i',
camera_loc, #a security camera
'-i',
'zone_all.png', # mask as to which parts are relavent for motion detection
'-/filter_complex',
'motion_display.filter', #the filter doing all the work
'-map', #sort out the outputs from the filter
'[original]',
'-f',
'mpegts', #I feel a little weied using mpegts but it was the best "streaming" of all the formats I tried
'udp://127.0.0.1:8888', #collect the full video from here
'-map',
'[motion]',
'-f',
'mpegts',
'udp:127.0.0.1:8889', #collect the motion output from here, mainly for debugging
]