title: Batch Highpass Filter in FFmpeg tags: ffmpeg audio filter I wrote this for a 16 core 5950X, as ffmpeg's audio processing is single threaded. I haven't benchmarked if you get more performance using 32 queues (one per hardware thread rather than one per hardware core). The main purpose is to have high-passed versions of a number of tracks or mixes, so that I can play them later through my hifi with the bass rolled off for the reason of being friendly to neighbours. ```py #!/usr/bin/env python num_cores = 16 from glob import glob from subprocess import run, PIPE, DEVNULL from threading import Thread import os, sys, re from icecream import ic; ic.configureOutput(includeContext=True) infiles = glob("*/*.m*") # all files are .m4a and .mp3 so this glob will do outfiles = [ "../hp_mp3/"+x for x in infiles ] zfiles = list(zip(infiles,outfiles)) # we have a list of lists, one per core zfs = [[] for i in range(num_cores)] # We assign the files to queues in a round-robin fashion for i,x in enumerate(zfiles): zfs[i%num_cores].append(x) # do one file def work(xs): ifn,ofn = xs # get bitrate of input file, so we can use the same bitrate on the encoded file m = run(["ffprobe","-hide_banner",ifn],stdin=DEVNULL,stdout=PIPE,stderr=PIPE) e = m.stderr.decode() es = e.splitlines() fs = [ x for x in es if "Audio:" in x ] # we'll get one line per audio stream if len(fs) == 0: ic("# fail",xs) # shouldn't happen return m = re.search(r"(\d+) kb/s",fs[0]) # hopefully this line includes a xxx kb/s bitrate if not m: ic("# fail2",xs) # shouldn't happen return br = m.group(1) br = f"{br}k" # do the transcoding run(["ffmpeg","-i",ifn,"-b:a",br,"-af","highpass=f=200,highpass=f=200",ofn],stdin=DEVNULL) # takes a list of (infile/outfile) pairs and processes them one after another class Worker: def __init__(self,zfs): self.zfs = zfs def __call__(self): for xs in self.zfs: work(xs) threads = [] # create one thread per queue for i,z in zfs.items(): thread = Thread(target=Worker(z)) threads.append(thread) # start all the threads for thread in threads: thread.start() # join all the threads for thread in threads: thread.join() ```