I used an online stream source; A HLS stream that one of my local TV stations broadcasts online.
My method will only work with streams that have SCTE35 packets embedded. This is normally used for local ad insertion on cable networks, so it may not always be available on OTA streams.
There is not much code because it is mostly ffmpeg that does the work.
I used nodejs to manage an ffmpeg child process, read its output streams (one stream over a unix domain socket for the video, and the stdout stream for the SCTE35 packets) and pipe them to a HTTP client.
My code parses the SCTE packets and then sends commands into the running ffmpeg child process to change the audio levels.
I am happy to share it when I get home in a few hours.