If you are recording audio output from an application, one challenge is that recording the default output can mean you record all the sounds that are produced by all applications. In Linux, you can use pipewire command-line utility pw-link to create a dedicated and isolated link between the application producing the audio output and the application that will be recording the audio output. Below is a bash script that does this – the command-line flags -o and -i imply the only links for the output and input applications should be to each other (exclusive mode). Note that this script makes a few assumptions (outside of assumptions about the format of the output from pw-link itself but I consider that to be not as problematic) – it assumes the application names do not contain _ – a more robust version could probably split the port name on ‘:’ and use the second field on split as channel.
#!/bin/bash
output_exclusive=false
input_exclusive=false
output_application_name="Amazon Music"
input_application_name="OBS"
while getopts "oi" opt; do
case $opt in
o)
output_exclusive=true
;;
i)
input_exclusive=true
;;
\?)
echo "Invalid Option: -$OPTARG" >&2
exit 1
;;
esac
done
shift $((OPTIND - 1))
declare -A deleted_links
node_matched=false
while IFS= read -r line1; do
if [[ ("$line1" =~ "<" || "$line1" =~ ">") && "$node_matched" = true ]]; then
link_id=$(echo $line1 | cut -d ' ' -f 1)
if [[ -z "${deleted_links[$link_id]}" ]]; then
deleted_links["$link_id"]=1
echo pw-link -d "$link_id"
pw-link -d "$link_id"
fi
else
node_matched=false
if [[ "$output_exclusive" = true && "$line1" =~ $output_application_name ]]; then
node_matched=true
elif [[ "$input_exclusive" = true && "$line1" =~ $input_application_name ]]; then
node_matched=true
fi
fi
done < <(pw-link -l -I)
declare -a output_ports
declare -a input_ports
while IFS= read -r line1; do
if [[ "$line1" =~ $output_application_name ]]; then
output_ports+=("$line1")
fi
done < <(pw-link -o)
while IFS= read -r line1; do
if [[ "$line1" =~ $input_application_name ]]; then
input_ports+=("$line1")
fi
done < <(pw-link -i)
for ((i = 0; i < ${#output_ports[@]}; i++)); do
for ((j = 0; j < ${#input_ports[@]}; j++)); do
output_channel=$(echo "${output_ports[i]}" | cut -d '_' -f 2)
input_channel=$(echo "${input_ports[j]}" | cut -d '_' -f 2)
if [[ "$output_channel" == "$input_channel" ]]; then
echo pw-link "${output_ports[i]}" "${input_ports[j]}"
pw-link "${output_ports[i]}" "${input_ports[j]}"
fi
done
done