Skip to content

Instantly share code, notes, and snippets.

@danielfomin96
Last active June 19, 2023 01:36
Show Gist options
  • Save danielfomin96/e79d223d0cb439fadd868edccce9a172 to your computer and use it in GitHub Desktop.
Save danielfomin96/e79d223d0cb439fadd868edccce9a172 to your computer and use it in GitHub Desktop.
ffmpeg wrapper to customely downmix videos opened by jellyfin
#!/bin/bash -
#title :ffmpeg
#description :This script is a wrapper for jellyfin ffmpeg to downmix audio to stereo using a custom formula
#author :Daniel Fomin
#date :20230104
#version :0.2
#reference :https://superuser.com/questions/852400/properly-downmix-5-1-to-stereo-using-ffmpeg
#
#
#==============================================================================
###############################################################################
# Installation Notes:
# 1. Put wrapper in directory accessible from jellyfin
# 2. `chmod +x path/to/wrapper/dir/ffmpeg`
# 3. `ln -s $(which ffprobe) path/to/wrapper/dir/` to the same directory
# 4. Point jellyfin to the wrapper directory
#
###############################################################################
function join { local IFS=$'\n'; echo "${*}"; }
args=$(join "${@}")
match='-ac\n[3-9]'
replace='-af\npan=stereo|FL<0.707*FC+0.707*FL+0.707*BL+0.5*LFE|FR<0.707*FC+0.707*FR+0.707*BR+0.5*LFE'
ffmpeg="/usr/lib/jellyfin-ffmpeg/ffmpeg"
readarray -t new_args < <(sed -z "s/$match/$replace/g" <<<"$args")
#echo "Command Rewrite: $ffmpeg $new_args" 1>&2
$ffmpeg "${new_args[@]}"
exit $?
@ManuLinares
Copy link

I'll leave here an improved version or the wrapper script, with proper handling of quotes

#!/bin/bash -
#title           :ffmpeg wrapper
#description     :This script is a wrapper for jellyfin ffmpeg to replace arguments
#==============================================================================

ffmpeg="/usr/lib/jellyfin-ffmpeg/ffmpeg"

#Add quotes for arguments with "spaces" and "round brackets")
for x in "${@}" ; do
    # try to figure out if quoting was required for the $x (Arguments)
    if [[ "$x" != "${x%[[:space:]]*}" ]] \
    || [[ "$x" != "${x%(*}" ]] ; then
        x="\""$x"\""
    fi
    _args=$_args" "$x
done

# Downmix audio to stereo
_args=${_args/-ac [3-9]/-af \"pan=stereo|FL < 0.5*FC + 0.3*FLC + 0.3*FL + 0.3*BL + 0.3*SL + 0.5*LFE | FR < 0.5*FC + 0.3*FRC + 0.3*FR + 0.3*BR + 0.3*SR + 0.5*LFE,volume=2\"}

eval $ffmpeg $_args

exit $?

@danielfomin96
Copy link
Author

Thanks for this was trying to write something similar - your foo is much stronger than my bar!

Couple of notes for future noobish users like myself

the "ln -s" command creates a symbolic link for ffprobe - my unraid docker container didn't recognise the "which" command, I had to use:

ln -s /usr/lib/jellyfin-ffmpeg/ffmpeg/ffprobe /config/

where I placed the script in the config directory

another nooby issue is that i forgot to set permissions:

chmod u=rwx,g=rwx,o=rwx /config/ffmpeg

Hope this helps someone!

Thank you @mark-cassidy for your remarks, I have added the chmod command to the installation notes.

@ivaylo-mk
Copy link

Real noob question, but I stumbled upon your script and I am wondering if it is possible to use it somehow in Windows, as currently I am experiencing issues with Jellyfin and 5.1 audio, and want to force downmixing to stereo of everything that is being played.

@mark-cassidy
Copy link

mark-cassidy commented Jan 22, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment