-
-
Save danielfomin96/e79d223d0cb439fadd868edccce9a172 to your computer and use it in GitHub Desktop.
#!/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 $? |
I found something. (had some errors)
"TL;DR: if you have configured an alternative ffmpeg path in Jellyfin, make sure there's an ffprobe binary in the same location with the same file extension"
The errors
MediaBrowser.Providers.TV.EpisodeMetadataService: Error in ffprobe
System.ComponentModel.Win32Exception (2): No such file or directory
Is it enough to link the binary into the folder?
yes.
ln -s `which ffprobe` /ffmpeg_wrapper_path/ffprobe
Thanks, this works great
Edit; forget this, I was using an earlier version of the script and updated to last revision, work like a charm, thanks for providing this
Any chance you can adapt the script to deep quotes if file path/names contain spaces as these are removed by parsing the args array
Example
/path/to/ffmpeg -fflags +genpts -i file:"/media/Movies/The Movie Example (2021)/The Movie Example (2021).mkv" -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 copy -start_at_zero -vsync -1 -codec:a:0 aac -ac 6 -ab 640000 -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 6 -hls_segment_type mpegts -start_number 0 -hls_segment_filename "/config/transcodes/e8e57aa6a93c2ff1e1d3bb6de528a1d5%d.ts" -hls_playlist_type vod -hls_list_size 0 -y "/config/transcodes/e8e57aa6a93c2ff1e1d3bb6de528a1d5.m3u8"
Is converted to
/usr/lib/jellyfin-ffmpeg/ffmpeg -fflags +genpts -i file:/media/Movies/The Movie Example (2021)/The Movie Example (2021).mkv -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 copy -start_at_zero -vsync -1 -codec:a:0 aac -af pan=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 -ab 640000 -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 6 -hls_segment_type mpegts -start_number 0 -hls_segment_filename /config/transcodes/e8e57aa6a93c2ff1e1d3bb6de528a1d5%d.ts -hls_playlist_type vod -hls_list_size 0 -y /config/transcodes/e8e57aa6a93c2ff1e1d3bb6de528a1d5.m3u8
Edit; forget this, I was using an earlier version of the script and updated to last revision, work like a charm, thanks for providing this
Any chance you can adapt the script to deep quotes if file path/names contain spaces as these are removed by parsing the args array
Example
/path/to/ffmpeg -fflags +genpts -i file:"/media/Movies/The Movie Example (2021)/The Movie Example (2021).mkv" -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 copy -start_at_zero -vsync -1 -codec:a:0 aac -ac 6 -ab 640000 -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 6 -hls_segment_type mpegts -start_number 0 -hls_segment_filename "/config/transcodes/e8e57aa6a93c2ff1e1d3bb6de528a1d5%d.ts" -hls_playlist_type vod -hls_list_size 0 -y "/config/transcodes/e8e57aa6a93c2ff1e1d3bb6de528a1d5.m3u8"
Is converted to
/usr/lib/jellyfin-ffmpeg/ffmpeg -fflags +genpts -i file:/media/Movies/The Movie Example (2021)/The Movie Example (2021).mkv -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 copy -start_at_zero -vsync -1 -codec:a:0 aac -af pan=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 -ab 640000 -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 6 -hls_segment_type mpegts -start_number 0 -hls_segment_filename /config/transcodes/e8e57aa6a93c2ff1e1d3bb6de528a1d5%d.ts -hls_playlist_type vod -hls_list_size 0 -y /config/transcodes/e8e57aa6a93c2ff1e1d3bb6de528a1d5.m3u8
Are you using the newest revision?
echo will remove quotes, but the command is working nevertheless. to debug a bash script, add "set -x" to the top.
There you can see the quotes are there.
Yep, works great with the latest version of the script.
Is it possible to add an option to use a 2.1 system instead of stereo, it sounds already waaaaaay better than the previous "-ac 2" but a bit dull without a proper LFE channel
This script is just an example which everybody can fit to their own liking.
The channel formula is specified in the replace
variable. In your case, try to append something like |LFE=LFE
to the variable, maybe it will work.
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!
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 $?
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.
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.
Thanks, will test this now as I have an older Firestick v1, and the latest (Master) jellyfin android tv app doesn't tell the server to downmix.