Subsonic Transcoding Script

Tutorials, tips and tricks.

Moderator: moderators

Subsonic Transcoding Script

Postby poctum » Thu Jun 19, 2014 4:43 pm

I created this script and thought I would share it for anyone who may find it useful.

Problems:
* Can't set maxbitrate for every user, is a user specific setting.
* Can set a bitrate in the transcode, though this will try to upsample lower quality audio making larger files.
* Can't set VBR for users or players through Subsonic, I prefer VBR.
* I prefer OGG for iSub (Apple) for original FLAC files, and don't want to transcode MP3 to another codec. Will leave Mp3 as Mp3's though transcode lossless codecs to OGG.

Solution:
* Transcoding script to check incoming file bitrate and file type, reducing bitrate if to high or pass-through if lower.
* Will check requested codec and use if necessary.

Notes:
* This runs on FreeBSD 10
* I prefer SOX over FFMPEG, but the commands are easily changeable.
* Will need to create separate transcoding if you plan to use OGG, since the WebPlayer and some other devices do not support OGG.

How it works:
* FilePath, Preferd Codec and Max Bitrate are sent via Subsonic arguments (ie. custom-script.sh %s ogg 180 or custom-script.sh %s mp3 180 )
* Script determines Bitrate of File and File codec type.
* if File is Mp3 and below Max Bitrate, it is pass-through and sent right to player. No transcoding.
* if file is Mp3 and above Max Bitrate, it is transcoded to VBR using 150-195kbps (Lame setting 3) (adjustable)
* if file is not Mp3 and user wants Mp3, it is transcoded VBR using 150-195kbps (Lame setting 3)
* if file is not Mp3 and user wants Ogg, it is transcoded to ogg with VBR/Compression value of 8 (adjustable)
* if all else fails, it is transcoded to Mp3 VBR using 150-195kbps


Code: Select all
#!/bin/sh
###############################################################################
# Author: poctum
# Date: 2014/07/18
#
# Usage: custom-script.sh <File> <PreferedCodec> <MaxPassThroughBitrate>
# Example Command: custom-script.sh %s mp3 170
#                           custom-script.sh %s ogg 170
#
#
# INFILE = File to be transcoded
# CODEC = requested out codec, for example convert flac to ogg(out) or mp3.
# QUALITY = Output quality for VBR mp3 and OGG [http://sox.sourceforge.net/sox.html]
#      MP3-VBR kbps: 0=220-260, 1=190-250, 2=170-210, 3=150-195, 4=140-185, 5=120-150, 6=100-130, 7=80-120
#      OGG-VBR kbps: -1=Highest Compression/Lowest Quality -- to -- 10 Lowest Compression, highest quality
# MAXBITRATE = Max bitrate allowed to not be transcoded.. ie, any file under 170k will not be transcoded.
#
# Debug Info (Set DEBUG=TRUE for output):
#  IF = Input File Type
#  BR = Input File Bitrate
#  MR = Max Bitrate allowed for passthrough
#  TC = Transcoded, Yes or No
#  CR = Codec Requested
#  CU = Codec Used
#  ST = Step/Area file was processed in
#
# Use Sox:
#  $SOX "$INFILE" $SOX_OPTS -t mp3 -C $MP3_QLTY -
#  $SOX "$INFILE" $SOX_OPTS -t ogg -C $OGG_QLTY -
#
# Use FFMpeg:
#  $FFMPEG -i "$INFILE" -acodec libmp3lame -q $MP3_QLTY -vn -v 0 -f mp3 -
#
###############################################################################
NAME=custom-script.sh
DEBUG=TRUE

# Locations of various programs required
SOX=/usr/local/bin/sox
FFMPEG=/usr/local/bin/ffmpeg
CAT=/bin/cat
XARGS=/usr/bin/xargs
SED=/usr/bin/sed

# Defaults and other variables
INFILE=$1
CODEC=mp3
QUALITY=4
MAXBITRATE=170
OGG_QLTY=5
MP3_QLTY=-3.2
AAC_QLTY=3
SOX_OPTS='--guard --multi-threaded -V0'

# Set variables to passed objects, if they are set
if [ -n "$2" ]; then CODEC=$2; fi
if [ -n "$3" ] && [ $3 -gt 0 ]; then MAXBITRATE=$3; fi

###############################################################################
# Send data to StdOut for echo's to show up in subsonic.log
debugout()
{
    if [ $DEBUG == TRUE ]; then
        echo "$@" 1>&2
    fi
}

# Capture the INFILE type and then trim it
# Will output mp3, ogg, flac, etc..
FILETYPE=`$SOX --i -t "$INFILE" | $XARGS`

# Capture the INFILE bitrate, and then trim it.
# Note - FLAC and others will come across as 1.01M and such.
BITRATE=`$SOX --i -B "$INFILE" | $SED 's/k//' | $XARGS`

# Checking if the file is an mp3, or we have requested mp3 or null.
# if the file is mp3, and below our MaxBitrate threshold, we will pass it through
# if not, we will transcode it down a bit, but not change codecs.

if [ $FILETYPE == mp3 ] || [ $CODEC == mp3 ] ; then
    if [ $FILETYPE == mp3 ] && [ $BITRATE -le $MAXBITRATE ] ; then
        # Bitrate is below requirements, send through as is.
        debugout " IF:$FILETYPE; BR:$BITRATE; MR:$MAXBITRATE; TC:NO; CR:$CODEC; CU:mp3; ST:1 [pass-through]"
        $CAT "$1"
    else
        # Bitrate is to high or file is not mp3, transcoding to mp3
        debugout " IF:$FILETYPE; BR:$BITRATE; MR:$MAXBITRATE; TC:YES; CR:$CODEC; CU:mp3; ST:2 [mp3 > mp3]"
        $SOX "$INFILE" $SOX_OPTS -t mp3 -C $MP3_QLTY -
    fi

# File is not mp3 - most likely lossless, and better codec is requested.
elif [ $CODEC == ogg ]; then
    debugout " IF:$FILETYPE; BR:$BITRATE; MR:$MAXBITRATE; TC:YES; CR:$CODEC; CU:ogg; ST:3 [$FILETYPE > ogg]"
    $SOX "$INFILE" $SOX_OPTS -t ogg -C $OGG_QLTY -
elif [ $CODEC == aac ]; then
    debugout " IF:$FILETYPE; BR:$BITRATE; MR:$MAXBITRATE; TC:YES; CR:$CODEC; CU:aac; ST:4 [$FILETYPE > aac]"
    $FFMPEG -i "$INFILE" -acodec libfdk_aac -vbr $AAC_QLTY -vn -v 0 -f adts -
else
    # Default on no match above.
    debugout " IF:$FILETYPE; BR:$BITRATE; MR:$MAXBITRATE; TC:YES; CR:$CODEC; CU:mp3; ST:5 [$FILETYPE > mp3]"
    $SOX "$INFILE" $SOX_OPTS -t mp3 -C $MP3_QLTY -
fi


edit: added AAC
poctum
 
Posts: 3
Joined: Fri Mar 18, 2011 5:09 pm

Re: Subsonic Transcoding Script

Postby spitf1r3 » Tue Aug 19, 2014 12:46 pm

Hi,

Thanks for the script!
I have a question, though:
For AAC, I'd like to add some parameters, depending on requested bitrate:

if <=96kbits
Code: Select all
-profile:a aac_he_v2 -cutoff 17500
to use HE-AAC-v2

if >96kbits, but < 160 kbits
Code: Select all
-profile:a aac_he -cutoff 18000
to use HE-AAC

any Idea, how I should go about this?
I don't want to enforce bitrate, and will want to set
Code: Select all
-vbr 5
on all AAC encodings, but still want to have choice of quality, based on what client requests.

EDIT:
Figured it out, here's what I did (replacing whole AAC block):
Code: Select all
elif [ $CODEC == aac ]; then
   if [ $MAXBITRATE -le 96 ]; then
        debugout " IF:$FILETYPE; BR:$BITRATE; MR:$MAXBITRATE; TC:YES; CR:$CODEC; CU:aac; ST:4 [$FILETYPE > aac_he-v2]"
        $FFMPEG -i "$INFILE" -acodec libfdk_aac -vbr $AAC_QLTY -vn -v 0 -profile:a aac_he_v2 -cutoff 17500 -f adts -
   elif [ $MAXBITRATE -ge 97 ] && [ $MAXBITRATE -le 159 ]; then
        debugout " IF:$FILETYPE; BR:$BITRATE; MR:$MAXBITRATE; TC:YES; CR:$CODEC; CU:aac; ST:4 [$FILETYPE > aac_he]"
        $FFMPEG -i "$INFILE" -acodec libfdk_aac -vbr $AAC_QLTY -vn -v 0 -profile:a aac_he -cutoff 18000 -f adts -
   else
        debugout " IF:$FILETYPE; BR:$BITRATE; MR:$MAXBITRATE; TC:YES; CR:$CODEC; CU:aac; ST:4 [$FILETYPE > aac]"
        $FFMPEG -i "$INFILE" -acodec libfdk_aac -vbr $AAC_QLTY -vn -v 0 -f adts -
   fi
spitf1r3
 
Posts: 4
Joined: Tue Aug 19, 2014 12:08 pm

Re: Subsonic Transcoding Script

Postby DavidMikky » Mon Sep 15, 2014 1:00 pm

Figured it out, here's what I did (replacing whole AAC block):
DavidMikky
 
Posts: 2
Joined: Mon Sep 15, 2014 12:59 pm

Re: Subsonic Transcoding Script

Postby DavidMikky » Mon Sep 15, 2014 1:01 pm

Figured it out, here's what I did (replacing whole AAC block):






_____________
…..Em Mikky…..
DavidMikky
 
Posts: 2
Joined: Mon Sep 15, 2014 12:59 pm


Return to Tutorials

Who is online

Users browsing this forum: No registered users and 2 guests