* > aac streaming with webplayer (JWplayer)

Tutorials, tips and tricks.

Moderator: moderators

* > aac streaming with webplayer (JWplayer)

Postby delcypher » Tue Aug 10, 2010 8:26 pm

I've been struggling with this for a few days. I thought I'd share the progress I made. This will be put on the wiki when I get the time.

I wanted to see if I could stream AAC audio to the web player. I tried...

* faac (You cannot use a MPEG4 container (-w) option and write to standard output, this is either a bug or a "feature"). Without this option it creates a file with a ADTS container which the web player can't use.

* Nero AAC encoder. This can't write to standard output.

I tried using process substiution (bash) and named pipes (using mkfifo command) but this doesn't work.

* ffmpeg can't write mp4 a container to standard output as it requires seekable output.

The solution I found was to use a flv container. I did this by using the following transcoding chain (just one step)

Code: Select all
ffmpeg -i %s -acodec libfaac -ab %bk -f flv -

mp3 > aac
flac > aac
wav > aac

Note the maximum bitrate average bitrate that libfaac supports is 152kbit/s. But if a higher bit-rate is specified then libfaac will just use 152.

This works with the web player, note that you will need to disable all the " * > mp3" transcoders for the web player (.e.g flac > mp3). I created a new player called "aac-player" that only transcodes to AAC audio.

Libfaac can use a quality option with a range 10 to 500 instead of a average bitrate.

I wrote a bash wrapper script that is invoked as follows
Code: Select all
aacenc-wrapper %s %b

that scales bit-rate [32,320] to a range of [10,500] linearly. The code for it is as follows

Code: Select all
#Wrapper script to linearly scale bit-rate [32,320] to quality range [10,500]
#For * > aac conversion for webplayer streaming (JWPlayer) in Subsonic
# usage aacencwrapper FILENAME BITRATE

#Maximum & minimum quality values to pass to libfaac

#calculate Quality
QUALITY=$(echo "scale=2; ($MAX_Q - $MIN_Q)*($BITRATE - 32)/(288) + $MIN_Q" | bc)

#round calculated quality
QUALITY=$(printf %.0f $(echo $QUALITY))

echo "Using Quality: $QUALITY (from $BITRATE kbit/s)" 1>&2

#check input file exists
if [ ! -r "$INPUT" ]; then
        echo "File $INPUT does not exist, transcode cancelled!" 1>&2
        exit 1;

#execute command
ffmpeg -i "$INPUT" -acodec libfaac -aq $QUALITY -f flv -

Please note:

* This may require a recent version of ffmpeg. It must be compiled with libfaac support and the faac library must be present (or statically linked, I'm not sure if that's possible though)

* This should work with VLC as an external player but I haven't tested it.

* This method will NOT work for streaming AAC to the android subsonic application as subsonic requires AAC audio to be in a MP4 container which as previously mentioned cannot be written to standard output.
Posts: 109
Joined: Tue Jun 01, 2010 10:39 am

Postby stozher » Sun Dec 12, 2010 5:47 pm

Thanks for tutorial delcypher! I found some documents on the Internet and I think that will have useful for society...

Video/Audio Encoding Cheat Sheet for FFmpeg:

flac > aac/flv | flac | aac | <Step 1>

AAC 48kHz Stereo HQ: ffmpeg -i %s -f flv -vn -acodec libfaac -ar 48000 -ab 192k -ac 2 -map_meta_data 0:0 -

AAC 44.1kHz Stereo HQ: ffmpeg -i %s -f flv -vn -acodec libfaac -ar 44100 -ab 160k -ac 2 -map_meta_data 0:0 -


FAAC 1.18 beta (www.audiocoding.com):

Note: VBR output bitrate depends on -q AND -c, so you should only vary the default setting -q 100 -c 16000 if you know what you're doing and/or want to experiment with other cutoff frequencies at a given quality setting.

The ABR setting with -a is an approximate average bitrate that does not use a bit reservoir, i.e -a 64 and -q 100 at 44.1 kHz will result in exactly the same output file.

The following list should give some orientation for useful -q and -c settings, based on FAAC v1.17. The resulting VBR bitrates are referring to an average sounding stereo file with 16bit, 44.1 kHz, i.e. ct_reference.wav in this case. Multiplexing these AAC files to MP4 with e.g. mp4creator will result in a ~3 kbps lower bitrate because of the stripped ADTS headers:

-q 130 -c 22000 -m 4 (~218 kbps)
-q 120 -c 20000 -m 4 (~194 kbps)
-q 110 -c 18000 -m 4 (~158 kbps)
-q 100 -c 16000 -m 4 (~129 kbps)
-q 90 -c 14000 -m 4 (~103 kbps)
-q 80 -c 12000 -m 4 (~79 kbps)
-q 70 -c 10000 -m 4 (~62 kbps)

The added -m 4 switch does not change the bitrate or sound of course, but is recommended for most AAC/MP4 players that use an updated FAAD2-based plugin from this year (Winamp 2.x, foobar2000 etc.) or can't decode MPEG-2 AAC LC files like QuickTime 6. Philips Expanium users should not use this switch, because their CD portable does not know MPEG-4 AAC files.

http://www.audiocoding.com/downloads.html (faac-1.28.zip/faac-1.28/docs/faac.html)
Last edited by stozher on Sun Jan 09, 2011 7:57 pm, edited 6 times in total.
User avatar
Posts: 313
Joined: Tue Nov 16, 2010 10:56 am
Location: Sofia, Bulgaria

Postby stozher » Sun Dec 12, 2010 9:59 pm

AAC ABR Stereo Tests:

"Advanced Audio Coding (AAC) is a standardized, lossy compression and encoding scheme for digital audio. Designed to be the successor of the MP3 format, AAC generally achieves better sound quality than MP3 at similar bit rates."

"The quality for stereo is satisfactory to modest requirements at 96 kbit/s in joint stereo mode; however, hi-fi transparency demands data rates of at least 128 kbit/s (VBR). The MPEG-2 audio tests showed that AAC meets the requirements referred to as "transparent" for the ITU at 128 kbit/s for stereo, and 320 kbit/s for 5.1 audio."


Tested only one file (16bit/44.1kHz, actual bandwith of file is a 19.3 kHz)...

ffmpeg -i test.wav -f flv -vn -acodec libfaac -ar <SAMPLE RATE> -ab <ABR BIT RATE> -ac 2 test.f4a

-ar 48000
-ab 224 -> 171.8kbits/s
-ab 192 -> 171.8kbits/s (max for this file)
-ab 160 -> 166.4kbits/s
-ab 128 -> 134.4kbits/s (hi-fi transparent)
-ab 112 -> 118.4kbits/s
-ab 96 -> 102.4kbits/s (low requirements)
-ab 80 -> 86.4kbits/s
-ab 64 -> 70.6kbits/s (ffmpeg default)

-ar 44100
-ab 192 -> 157.9kbits/s
-ab 160 -> 157.9kbits/s (max for this file)
-ab 128 -> 133.9kbits/s (hi-fi transparent)
-ab 112 -> 117.8kbits/s
-ab 96 -> 101.9kbits/s (low requirements)
-ab 80 -> 85.8kbits/s
-ab 64 -> 69.9kbits/s (ffmpeg default)
User avatar
Posts: 313
Joined: Tue Nov 16, 2010 10:56 am
Location: Sofia, Bulgaria

Postby ktjensen » Mon May 02, 2011 2:05 pm

Am a windows 7 user. wish I understood how to set this up. Need an AAC or AAC+ home server audio application, to reduce bandwidth; and stream all my audio over my skinny pipe (32MBPS or 48 MBPS) connection

FStream on the Iphone is supposedly the best client for AAC streams
Posts: 1
Joined: Mon May 02, 2011 2:00 pm

Postby 3R3 » Tue May 03, 2011 6:11 pm

with your original script I get sub-crappy quality. possibly the lowest setting bc of some printf typo. s really rumblinbg like back in the days...

so I just changed the execute parameter for quality to "$2"k and the "-aq" to "-ab" so it gives bitrates in the form of XXk, the form my ffmpeg expects. This works fine but is not so flexible. I'll report back when I've gone over it again with more time. thx for the handy script though!

User avatar
Posts: 332
Joined: Mon May 04, 2009 2:09 pm
Location: Germany

Re: * > aac streaming with webplayer (JWplayer)

Postby lildadou » Sat Mar 09, 2013 6:04 pm

--- Version française disponible plus bas ---

I write script for stream HE-AAC v2 (or other AAC version) with a MP4 container. It means that this method works for Android's and HTML5 client!!!!
Due to use a file buffering, with method introduce few additionnal seconds of latency.

First, I recommends install libuuid1 for generate good randomly file names. But you can also, use my very crapy method (uncomment the line).
Add this script on your $userfolder/.subsonic/var/transcode/aac-convert.sh (do not forget add eXecutable permissions).
Code: Select all
username="your home name"

echo -e "Input: $1 \n\
Output: /tmp/$tmpid.m4a \n\
Bitrate: $2 \n\
ffmpeg stderr:\n" >> /home/$username/.subsonic/aac-convert.log

/usr/local/bin/ffmpeg -i "$1" -codec:a libaacplus -ab $2 /tmp/$tmpid.m4a 2>> /home/$username/.subsonic/aac-convert.log

echo -e "\n\n\n" >> /home/$username/.subsonic/aac-convert.log

cat /tmp/$tmpid.m4a

Adapt the script:
- choose a file name generation method
- change the value of username variable
- adapt the aac encoding library to use. Here it's for HE-AAC v2 (allows max 64k bitrate)
- adapt temporary folder but remember that /tmp file are trashed automatically :)

Into Subsonic>Parameters>Encoding>add a transcoding.
Destination: m4a
Stage 1: aac-convert.sh %s %bk

Next, Subsonic>Parameters>Players and change activated encoders.

---- For frenchie's country man -----
J'ai écrit un petit script pour streamer en HE-AAC v2 (ou autre AAC) dans un container MP4. Cela signifie que vous pourrez streamer en AAC vers Android ou vers des lecteurs full-HTML5. Etant donné qu'à 64kbps le HE-AAC v2 est déjà très bon, ça nous fera des économies de 3G super-interressante.

Je sous recommande d'installer le package libuuid1 (Ubuntu) qui nous servira à générer des noms de fichiers aléatoire. Mais vous pouvez aussi ne pas le faire et utiliser la ligne de code dégueux qui se passe de libuuid1.
Ajouter ensuite le script dans $userfolder/.subsonic/var/transcode/aac-convert.sh
et évidement, n'oublier chmoder pour ajouter les droits d'execution.
Code: Select all
username="your home name"

echo -e "Input: $1 \n\
Output: /tmp/$tmpid.m4a \n\
Bitrate: $2 \n\
ffmpeg stderr:\n" >> /home/$username/.subsonic/aac-convert.log

/usr/local/bin/ffmpeg -i "$1" -codec:a libaacplus -ab $2 /tmp/$tmpid.m4a 2>> /home/$username/.subsonic/aac-convert.log

echo -e "\n\n\n" >> /home/$username/.subsonic/aac-convert.log

cat /tmp/$tmpid.m4a

Le gros du script en place, adapter-le un peu:
- choisissez la méthode de génération d'aléa
- changer la variable qui contient votre nom d'utilisateur (ou virez le code qui sert au debuggage)
- changez éventuellement la librairie utilisée pour encoder votre audio. Dans cet exemple j'utilise libaacplus (non fourni par défaut) qui permet une compression en HE-AAC v2 jusque 64kbps ; c'est franchement bon!
- adapter éventuellement le dossier qui contiendra les fichier temporaires. Mais rester dans /tmp, je crois que Linux se charge de faire le ménage de temps en temps.

Après allez dans Subsonic>Paramètres>Encodage> Ajouter un transcodage
Destination: m4a
Etape 1: aac-convert.sh %s %bk

Après allez dans Subsonic>Paramètres>Lecteurs et activer le nouvel encodeur sur les lecteurs qu'il vous plaira
Posts: 7
Joined: Mon May 16, 2011 8:48 am

Re: * > aac streaming with webplayer (JWplayer)

Postby lildadou » Mon Mar 25, 2013 2:06 pm

I present a slightly improved version.
Now, encoded name file use SHA for better performance. If file are already into tmp folder then audio file doen't re-encoded.
Futhermore tmp folder can be customized and will be created automatically if it doesn't exist.

Code: Select all
if [ ! -d $tmpoutfolder ]
        mkdir -p $tmpoutfolder
tmpid=`echo "$1" | sha1sum`


echo -e "Input: $1 \n\
Output: $tmpout \n\
Bitrate: $2 " >> /home/$username/.subsonic/aac-convert.log
if [ ! -f $tmpout ]
        echo -e "ffmpeg stderr:\n" >> /home/$username/.subsonic/aac-convert.log
        /usr/local/bin/ffmpeg -i "$1" -codec:a libaacplus -ab $2 $tmpout 2>> /home/$username/.subsonic/aac-convert.log
        echo -e "ffmpeg: Cache matching!\n" >> /home/$username/.subsonic/aac-convert.log

echo -e "\n\n\n" >> /home/$username/.subsonic/aac-convert.log
cat $tmpout
Posts: 7
Joined: Mon May 16, 2011 8:48 am

Re: * > aac streaming with webplayer (JWplayer)

Postby lildadou » Mon Mar 25, 2013 10:22 pm

I make a mistake into the first line of my previous post.
You must replace #/bin/sh by #!/bin/bash :oops:
Posts: 7
Joined: Mon May 16, 2011 8:48 am

Return to Tutorials

Who is online

Users browsing this forum: No registered users and 2 guests