FAQ  •  Register  •  Login

FFmpeg wrapper mini HowTo [audio & sub track selection]

<<

ne0zone75

User avatar

Streaming enthusiast

Posts: 29

Joined: Thu Feb 28, 2013 10:04 pm

Location: France

Post Thu Feb 28, 2013 11:30 pm

FFmpeg wrapper mini HowTo [audio & sub track selection]

Hi All,

I'm writing this post because i made a FFmpeg wrapper for myself in order to enable audio & sub track selection and i'd like to share it in case someone is interested.I made it because i was frustrated by the fact that i could not watch my movies the way i'd liked to => original audio track and subtitles. So firstly i'd like to thank the dev team of serviio because this software is simply great out of the box and it can be fastly greater because it's heavy customizable :D; secondly i'd like to thank the community of serviio which is very active so it's easy to find a solution to a problem quickly.

Here is my FFmpeg wrapper based on those of 2 members found in this thread -> http://forum.serviio.org/viewtopic.php?f=11&t=6688

  Code:
#!/bin/sh

#variables for selecting audio & sub tracks
#for each one 0 means the first of its type
#TYPE=0 selects the first track of type "TYPE"
#"TYPE" can match an audio or a sub track
AUDIO=0
SUBS=1

# for details on this loop see the thread i mentioned above -> credit goes @patters
PARAMS=""
INPUT=0
for PARAM in "$@"; do
   if [ ${INPUT} = 1 ]; then
      PARAMS="${PARAMS} \"${PARAM}\""   
      INPUT=0
   else
      PARAMS="${PARAMS} ${PARAM}"
   fi
   if [ "${PARAM}" == "-i" ]; then
      INPUT=1
   fi
done

#Here the wrapper substitutes a part of the FFmpeg serviio output and replaces it -> that's it's purpose
#Credit of the subtitution technique goes again @patters
#This part will have 2 effects : -to select 1 particular audio and 1 particular sub track of the input file
#                                -to hardcode on-the-fly a matching sub stream to the video (subs will be burned into the video)
PARAMS="`echo ${PARAMS} | sed -e "s| -map 0:0 -map 0:1| -filter_complex '[0:v:0][0:s:${SUBS}]overlay[v]' -map [v] -map '0:a:${AUDIO}'|"`"

#Here it sends back the modified arguments to FFmmpeg
#Credits of this part go to soundcheck and patters too
BIN="$(which ffmpeg)"
FOLDER="`dirname $0`"
echo "${BIN} ${PARAMS}" > ${FOLDER}/../log/ffmpeg-wrapper-tracks-selector.log
eval ${BIN} ${PARAMS}

exit $?


It does the job perfectly anytime on Full HD, HD Ready and SD movies :D but it requires a powerfull computer ! (the input file must be transcoded otherwise the wrapper will be simply skipped by serviio)

For those who want to further investigate subtitles hardcoding using FFmpeg, you can read this article : http://ffmpeg.org/trac/ffmpeg/wiki/How%20to%20burn%20subtitles%20into%20the%20video



IMPORTANT NOTES :

- For this wrapper to work you NEED to build the git version of FFmpeg in order to have a build that implements the filter_complex argument
- Subtitles MUST be *.PGS, *.IDX/*.SUB and muxed into the input file ("picture based" subtitles)
- To install it, please follow the procedure described by patters in this thread : http://forum.serviio.org/viewtopic.php?f=11&t=6688

Voilà, that's it !
<<

Illico

User avatar

DLNA master

Posts: 4646

Joined: Fri Jul 23, 2010 8:08 am

Location: France

Post Fri Mar 01, 2013 7:38 am

Re: FFmpeg wrapper mini HowTo [audio & sub track selection]

Good job and thanks to share your work...

The next 1.2 serviio version will support subtitles from a preferred/selected langage... (the 1.2RC is ready)

But audio track selection is not planed for the moment, a ticket was opened about that : https://bitbucket.org/xnejp03/serviio/i ... ection-for
Illico
Sony 2010 KDL-46EX501 | BDP-S373 | SMP-N100 | Windows 8-i7 | Network DD HD-CE1.5TLU2 | Livebox2-UHD86 | ServiiDroid | ServiiGo | BubbleUPnP
Serviio beta tester - Moderator
<<

ne0zone75

User avatar

Streaming enthusiast

Posts: 29

Joined: Thu Feb 28, 2013 10:04 pm

Location: France

Post Fri Mar 01, 2013 8:14 am

Re: FFmpeg wrapper mini HowTo [audio & sub track selection]

You're welcome ;)

Actually, this wrapper really relies on the source material => i've to confess that if you have movies without black bars you'll get into trouble and in case i propose a modified one which extends compatibility for both HD and SD sources :

  Code:
#!/bin/sh

#variables for selecting audio & sub tracks
#for each one 0 means the first of its type
#TYPE=0 selects the first track of type "TYPE"
#"TYPE" can match an audio or a sub track
AUDIO=0
SUBS=0

# for details on this loop see the thread i mentioned above -> credit goes @patters
PARAMS=""
INPUT=0
for PARAM in "$@"; do
   if [ ${INPUT} = 1 ]; then
      PARAMS="${PARAMS} \"${PARAM}\""   
      INPUT=0
   else
      PARAMS="${PARAMS} ${PARAM}"
   fi
   if [ "${PARAM}" == "-i" ]; then
      INPUT=1
   fi
   if [
done

#Here the wrapper substitutes a part of the FFmpeg serviio output and replaces it -> that's it's purpose
#Credit of the subtitution technique goes again @patters
#This part will have 2 effects : -to select 1 particular audio and 1 particular sub track of the input file
#                                -to hardcode on-the-fly a matching sub stream to the video (subs will be burned into the video)
PARAMS="`echo ${PARAMS} | sed -e "s| -map 0:1| -map '0:a:${AUDIO}'|"`"
PARAMS="`echo ${PARAMS} | sed -e "s| -map 0:0| -filter_complex '[0:s:${SUBS}]null[subs];[0:v:0]pad=max(iw\,ih*16/9):max(ih\,iw/16*9):(ow-iw)/2:(oh-ih)/2:black,setdar=4:3[video];[video][subs]overlay'|"`"

#Here it sends back the modified arguments to FFmmpeg
#Credits of this part go to soundcheck and patters too
BIN="$(which ffmpeg)"
FOLDER="`dirname $0`"
echo "${BIN} ${PARAMS}" > ${FOLDER}/../log/ffmpeg-wrapper.log
eval ${BIN} ${PARAMS}

exit $?


I'm waiting the next release of serviio with patience ...

Have a nice day :D
<<

ne0zone75

User avatar

Streaming enthusiast

Posts: 29

Joined: Thu Feb 28, 2013 10:04 pm

Location: France

Post Sat Mar 02, 2013 1:08 pm

Re: FFmpeg wrapper mini HowTo [audio & sub track selection]

It seems that the modified wrapper i've posted yesterday and edited today solves a lot of troubles but it remains one important one -> the size of the subs canvas which is set by FFmpeg (git version) can cause the failure of the wrapper. The only workaround i found is to modify the "sub2video_prepare" function in FFmpeg sources and then recompile it : result => it works like a charm :D
<<

ne0zone75

User avatar

Streaming enthusiast

Posts: 29

Joined: Thu Feb 28, 2013 10:04 pm

Location: France

Post Sat Mar 02, 2013 5:53 pm

Re: FFmpeg wrapper mini HowTo [audio & sub track selection]

Just to let you know, i've worked a little bit more on my wrapper and now it's 100% functional (... for my movie collection i must say).

It features :
-> autodetection of SD & HD inputs
-> audio & subs track selection
-> hardcoding any "picture based" sub included in the movie to the streamed output

It's limitations are :
-> the need to tweak FFmpeg git source code in order to have a proper subs canvas size
-> the need to let serviio make the difference beetween SD & HD sources : to achieve this i added 2 different profiles for my TV in profiles.xml, the first one use the serviio parameter "levelGreaterThan" to transcode HD files with a certain "maxVBitrate" and the second one accepts what is left and use a different "maxVBitrate" than the first profile. So my wrapper use the serviio video bitrate argument to make the difference between SD & HD sources and apply the correct modifications in order to have a suitable output.

Here it is :

  Code:
#!/bin/sh

#grabb serviio FFmpeg parameters
PARAMS="$@"

#variables for selecting audio & sub tracks, for each one 0 means the first of its type
#TYPE=0 selects the first track of type "TYPE" and it can match an audio or a sub track
#just mofify the values according to your needs
AUDIO=0
SUBS=0

#Here the wrapper substitutes a part of the serviio FFmpeg output and replaces it -> that's it's purpose
#This part will have multiple effects : - select audio and sub track
#                              - surround the file path with quotes in case it contains spaces
#                              - detect if the file is a HD or SD one (serviio profiles.xml needs to be adjusted)
#                                 -> modify the bitrate value to set it to lower one than the max video bitrate
#                                 -> burn on-the-fly subs to the video

PARAMS="`echo ${PARAMS} | sed -e "s| -i /| -i '/|"`"
PARAMS="`echo ${PARAMS} | sed -e "s| -y|' -y|"`"
if `echo ${PARAMS} | grep "17000k" 1>/dev/null 2>&1`; then
   echo "HD detected"
   PARAMS="`echo ${PARAMS} | sed -e "s| -b:v 17000k| -b:v 15000k|"`"
   PARAMS="`echo ${PARAMS} | sed -e "s| -map 0:0| -filter_complex '[0:s:${SUBS}]null[subs];[0:v:0]pad=1920:1080:(ow-iw)/2:(oh-ih)/2:black[video];[video][subs]overlay'|"`"
else
   echo "SD detected"
   PARAMS="`echo ${PARAMS} | sed -e "s| -b:v 15000k| -b:v 12000k|"`"
   PARAMS="`echo ${PARAMS} | sed -e "s| -map 0:0| -filter_complex '[0:s:${SUBS}]null[subs];[0:v:0]pad=720:576:(ow-iw)/2:(oh-ih)/2:black[video];[video][subs]overlay'|"`"
fi
PARAMS="`echo ${PARAMS} | sed -e "s| -map 0:1| -map '0:a:${AUDIO}'|"`"

#Here it sends back the modified arguments to FFmmpeg
BIN="$(which ffmpeg)"
FOLDER="`dirname $0`"
echo "${BIN} ${PARAMS}" > ${FOLDER}/../log/ffmpeg-wrapper.log
eval ${BIN} ${PARAMS}

exit $?


Best regards
<<

ne0zone75

User avatar

Streaming enthusiast

Posts: 29

Joined: Thu Feb 28, 2013 10:04 pm

Location: France

Post Tue Mar 05, 2013 11:21 pm

Re: FFmpeg wrapper mini HowTo [audio & sub track selection]

Bonsoir, i improved the script code a little bit more to get it close to what i wanted; now :
- it integrates with serviio really well <=> no more filepath problems
- it features now a real log file which grows each time the server uses the wrapper

  Code:
#!/bin/sh

#Grab serviio FFmpeg parameters
PARAMS="$@"

#Variables for selecting audio & sub tracks, for each one 0 means the first of its type
#TYPE=0 selects the first track of type "TYPE" and it can match an audio or a sub track
#just mofify the values according to your needs
AUDIO=0
SUBS=0

#Here the wrapper substitutes a part of the serviio FFmpeg output and replaces it -> that's it's purpose
#This part will have multiple effects : - select audio and sub track
#                              - surround the file path with quotes in case it contains spaces
#                              - detect if the file is a HD or SD one (serviio profiles.xml needs to be adjusted)
#                                 -> modify the bitrate value to set it to lower one than the max video bitrate
#                                 -> burn on-the-fly subs to the video

FILEPATH="`echo ${PARAMS} | sed -r "s|.mkv.*|.mkv|" | sed -r "s|^.*-i ||"`"
FIXED="'"${FILEPATH}"'"
PARAMS="`echo ${PARAMS} | sed -e "s|${FILEPATH}|${FIXED}|"`"

if `echo ${PARAMS} | grep "17000k" 1>/dev/null 2>&1`; then
   echo "HD detected"
   PARAMS="`echo ${PARAMS} | sed -e "s| -b:v 17000k| -b:v 12000k|"`"
   PARAMS="`echo ${PARAMS} | sed -e "s| -map 0:0| -filter_complex '[0:s:${SUBS}]null[subs];[0:v:0]pad=1920:1080:(ow-iw)/2:(oh-ih)/2:black,setdar=16:9[video];[video][subs]overlay'|"`"
else
   echo "SD detected"
   PARAMS="`echo ${PARAMS} | sed -e "s| -b:v 15000k| -b:v 10000k|"`"
   PARAMS="`echo ${PARAMS} | sed -e "s| -map 0:0| -filter_complex '[0:s:${SUBS}]null[subs];[0:v:0]pad=720:576:(ow-iw)/2:(oh-ih)/2:black,setdar=16:9[video];[video][subs]overlay'|"`"
fi
PARAMS="`echo ${PARAMS} | sed -e "s| -map 0:1| -map '0:a:${AUDIO}'|"`"

#Here it sends back the modified arguments to FFmmpeg
BIN="$(which ffmpeg)"
FOLDER="`dirname $0`"

echo "${BIN} ${PARAMS}" > ${FOLDER}/../log/ffmpeg-wrapper.tmp
cat ${FOLDER}/../log/ffmpeg-wrapper.log >> ${FOLDER}/../log/ffmpeg-wrapper.tmp
mv ${FOLDER}/../log/ffmpeg-wrapper.tmp ${FOLDER}/../log/ffmpeg-wrapper.log

eval ${BIN} ${PARAMS}

exit $?


If you have any questions or comments, they are welcome :D

Return to Transcoding

Who is online

Users browsing this forum: No registered users and 28 guests

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.