Howto convert mp3-Streams to aac+ Streams in Linux

Was ist der Unterschied zwischen aac+ und mp3?

MPEG-4 High Efficiency Advanced Audio Coding (kurz HE-AAC), auch AAC+ v1 genannt, ist ein lizenzpflichtiger Audio-Codec, der Moving Picture Experts Group (MPEG). Der Standard liefert bei niedrigen Bitraten vergleichsweise gute Ergebnisse und eignet sich daher besonders für Live-Streams.


Im Verhältnis zu mp3 bietet aac+ auch bei niedrigen Bitraten (32kbit) eine akzeptable gute Qualität. Allerdings ist aac+ ein lizenzplfichtiger Audio-Codec und für Linux gibt es dafür nicht wirklich viel Software, welche dieses Format encoden können. Decoder gibt es wie Sand am Meer, aber wenn man eben in aac+ Streamen möchte und die Daten als mp3 vorliegen, so braucht man dazu einen Encoder der die Daten von mp3 nach aac+ konvertiert.

Motivation

Ein Bekannter hat mich gestern deshalb gefragt, ob ich dafür eine Lösung parat hätte. Ich habe dann mal etwas ausgefuchst, um einfach den mp3 Stream von Antenne Bayern in aac+ zu konvertieren.

Benötigte Software

Folgende Software wird benötigt:

Dies reicht aus um den Stream konvertieren zu können und als aac+ Stream weiter verwenden zu können. Ich gehe davon aus dass Du als User in der Lage bist, shoutcast, mp4tools und mplayer zu installieren.

Let’s do it!

Ich habe dafür auf einem VServer einen user “streaming” angelegt und bin in das Home-Dir des Users gewechselt. Entpacke dort den shoutcast Server. Zunächst müssen wir mit mkfifo einen Fifo erstellen, über den wir später den Stream von Antenne Bayern durchschleusen:

~# mkfifo streamin

Dann müssen wir ein kleines Script schreiben, welches die encodierten aac+ Daten an den Shoutcast-Server übergibt:


#!/usr/bin/php
<?php
$address = "192.168.200.10";
$port = 8000;
$sock = fsockopen($address,($port+1),&$errno, &$errstr, 10);
fputs($sock,"changeme\r\n"); // Passwort ändern!
$res = fgets($sock);
wlog($res);
fputs($sock,"icy-name:my Server
icy-genre:
icy-url:http://www.shoutcast.com
icy-irc:%23shoutcast
icy-icq:0
icy-aim:N%2FA
icy-pub:1
icy-br:32
content-type:audio/aacp
icy-reset:1


");
$res = fgets($sock);
wlog($res);
$fd = fopen("php://stdin","r");
while (!feof($fd)) {
$buf = fgets($fd,512);
//wlog("Sending 512 bytes");
fputs($sock,$buf);
}
fclose($fd);
function wlog($msg) {
$fd = fopen("/tmp/ss.log","a");
fputs($fd,$msg."\n");
fclose($fd);
}
?>

Adresse und Port müssen angepasst werden, so dass hier der installierte Shoutcast Server angesprochen wird. Das Script habe ich bei mir als “simple_server.php” gespeichert und die Modes 755 gesetzt, damit dieses direkt über die Console gestartet werden kann (sollte das nicht funktionieren, fehlt php-cli!).

Nun haben wir schon alles was wir benötigen um zu starten:

aacplusenc streamin – 32 | ./simple_server.php & mplayer -ao pcm:file=streamin http://mp3.webradio.antenne.de:80

Dies erzeugt uns den aac+ Stream, welchen man dann z.B. mit VLC oder Winamp über den installierten Shoutcast Server abspielen kann.

36 thoughts on “Howto convert mp3-Streams to aac+ Streams in Linux

  1. Hi is it also possible to stream a local music folder to an icecast server and if yes what should be done? Thank you.

  2. PHP Fatal error: Call-time pass-by-reference has been removed in simple_server.php on line 5

    woran könnte das liegen? php-ci ist installiert

    1. replace

      $sock = fsockopen($address,($port+1),&$errno, &$errstr, 10);

      with
      $errno = “”;
      $errstr = “”;
      $sock = fsockopen($address,($port+1),$errno, $errstr, 10);

      and try again…

  3. habe das gleiche problem wie gendalus

    mplayer: could not connect to socket
    mplayer: No such file or directory
    Failed to open LIRC support. You will not be able to use your remote control.

  4. Hallo,

    danke für die Anleitung. Wenn das Ganze klappt, dann hat mir das seeeeehr viel weitergeholfen. Aber noch geht es nicht ganz.
    Ich starte den Server:
    /sc_serv_1.9.8_Linux$ ./sc_serv
    […]
    Event log:
    [SHOUTcast] DNAS/Linux v1.9.8 (Feb 28 2007) starting up…
    [main] pid: 17316
    [main] loaded config from sc_serv.conf
    [main] initializing (usermax:32 portbase:8100)…
    [main] No ban file found (sc_serv.ban)
    [main] No rip file found (sc_serv.rip)
    [main] opening source socket
    [main] source thread starting
    [main] opening client socket
    [source] listening for connection on port 8101
    [main] Client Stream thread [0] starting
    [main] client main thread starting
    [source] connected from 127.0.0.1
    [source] icy-name:my Server ; icy-genre:
    [source] icy-pub:1 ; icy-br:32 ; icy-url:http://www.shoutcast.com
    [source] icy-irc:%23shoutcast ; icy-icq:0 ; icy-aim:N%2FA
    [dest: 64.12.243.203] starting stream (UID: 0)[L: 1]{A: SHOUTcast Directory Tester}(P: 0)
    [dest: 64.12.243.203] connection closed (0 seconds) (UID: 0)[L: 0]{Bytes: 12917}(P: 0)
    [yp_add] yp.shoutcast.com added me successfully
    [source] no data (30s timeout). disconnecting.

    Währendessen in einem anderen Terminal:
    aacplusenc streamin – 32 | ./server.php & mplayer -ao pcm:file=streamin http://127.0.0.1:8000
    [2] 17366

    *************************************************************
    * Enhanced aacPlus Encoder
    * Build Sep 22 2011, 21:58:25
    * Matteo Croce
    *************************************************************

    MPlayer SVN-r1.0~rc3+svn20090426-4.4.3 (C) 2000-2009 MPlayer Team
    mplayer: could not connect to socket
    mplayer: No such file or directory
    Failed to open LIRC support. You will not be able to use your remote control.
    […]

    Gibt es Tips woran es liegen könnte, dass der Socket nicht erkannt wird oder so?? Der Stream kommt von einer zweiten SC instanz die natürlich mit einer anderen sc_serv.conf läuft.
    Wäre für Hilfe echt dankbar.

  5. Hallo,

    hat jemand schon das Problem gefixt wieso sich die Streamin.php immer abschießt? Dies scheint offensichtlich dann zu passieren, wenn der Source-Stream unterbrochen wird.

    Ist das eigentlich v1 oder v2 AAC+?

  6. Hallo,

    Eine Frage hätte ich dann noch;) das Perlscript kann sich nicht wiederverbinden, PHP meldet mir wenn der Stream länger unterbrochen ist folgendes:

    “PHP Notice: fputs(): send of 65 bytes failed with errno=32 Broken pipe in /home/name/Testserver-Mplayer/simple_server.php on line 27”

    Für einen Tip wäre ich dankebar.

  7. Hallo,

    Super Arbeit !!!! Danke, jetzt kann ich NSV auf dem Server trennen und hab jetzt auch einen reinen Audio Stream!

    Vielen Danke!!!

    MfG

  8. Hallo,
    Ich habe die Anleitung genau befolgt und es scheint bis auf einen kleinen Felhler alles zu funktionieren. Nur sagt er mit das er kein “ADTS File” erstellen kann…. Alles startet, er verbindet siuch mit dem server und dann wenn er versucht die wiedergabe zu “starten” sagt er das er kein adts file erstellen kann und dann kommt die meldung “MPlayer interrupted by signal 13 in module: play_audio”

    Was mache ich falsch?

    gruß
    Arsimael

    1. Das scheint mir mehr daran zu liegen, dass deine Quelle bereits aac ist und Du eventuell nicht die libs zum decoden von aac im mplayer compiliert hast.

  9. Der Darwin-Server (freie alternative zu Apple’s Quicktime-Streaming-Server) verwendet RTSP als Protokoll. Der AAC+ Stream sollte über RTP an Darwin zugeliefert werden (dazu gehört eine Beschreibungsdatei, die SDP = Session Description Protokoll).

    Abgeholt wird der Stream vom Nutzer über RTSP. Dies macht vorallem im Mobile-Streaming-Sektor sinn, da viele mobile Endgeräte (allen voran Sony-Ericson-Handys) RTSP-fähige Realplayer integriert haben und somit die bandbreitenarmen Streams in bester Qualität abgreifen können. Shoutcast können mobile Endgeräte ohne Zusatzsoftware (und die gibt es oft nicht) leider nicht verarbeiten. Genau das möchte ich jedoch realisieren.
    Any idea ?

    1. Prinzipiell sollte das gehen, sofern man den simple_server.php etwas umbaut. Mir ist allerdings keine PHP-Klasse zum streamen für RTSP/RTP bekannt und eine 1-min Googlesuche hat hier auch auf die Schnelle nichts gebracht.
      Theoretisch kann man auch mit einer anderen Script-Sprache oder Programm streamen, welches RTP beherrscht…

  10. Gibt es eine Möglichkeit, mit diesem Verfahren an einen Darwin-Server zu streamen, incl. der Erstellung der SDP ?
    Was muss ich tun ?

    1. Gute Frage – allerdings kann ich die so kaum beantworten. Welches Protokoll verwendet denn der Darwin-Server? Was meinst Du mit “Erstellung der SDP?”

  11. Sehr geiles tut, hab es mal ausprobiert hab zwar paar anlaufschwierigkeiten gehabt aber nun läuft es 1A

    die quali von aacplusenc kommt zwar nicht ganz an die von z.B. Winamp Encoder ran aber es ist kostenlos uns immernoch wesentlich besser als MP3 mit 32Kbit

  12. Hat sich schon geklär, du solltest evttl noch sagen, dass sie ihr shoutcast pw (das zum streamen) eintragen sollen, wo changeme steht
    fputs($sock,”changeme\r\n”); <<<— daaa

    greez
    TheRealLink

  13. jaa, nurr wenn ich den port auf 8011 setze (mein shoutcast port läuft auf 8010) dann spuckt er mir ein fehler aus (Zeile 27 im php Skript)
    setze ich den port im script auf 8010 dann steht der stream weiterhin auf offline

  14. hmm, ok, nett wäre auch noch wenn du mir evtl. mal genau sagen könntest, wohin der stream genau geht.

  15. Und wie muss ich die sc_serv.conf verändern, damit der auf die streamin zugreift? oder muss ich das php file als backupfile angeben?

    mfg
    trl

    1. Überhaupt nicht – das PHP Script leitet den transcodierten Stream ja direkt zu Shoutcast, welcher diesen dann streamt. Die FIFOs werden nur zum transcodieren verwendet und shoutcast greift darauf überhaupt nicht direkt zu.

  16. Hallo!

    Wie meldet sich das Skript denn am AAC Shoutcast Server an? Irgendwo müsste ich doch Benutzernamen und Passwort eingeben können..
    Oder encodet der DJ direkt auf das Skript. Irgendwie steige ich da noch nicht ganz durch! Danke

    Gruß

    Nimda05

    1. Das Skript ist dazu gedacht, direkt auf dem Server zu laufen und den Stream als mp3 von einem Shoutcast Server zu holen, transcodieren und dann direkt lokal an einen weiteren Shoutcast-Server zu streamen – hierbei wird dann kein User/Passwort benötigt.

  17. Hallo,
    und wie bekomme ich einen aac+ Stream in mp3 Stream umgewadelt?
    Danke im Vorraus 😉

    Gruß
    Dado

  18. Mit aufhaenging meine ich, das mplayer den stream zwar “empfaengt” aber der weitere weg ueber das php zum destination server nicht mehr einwandfrei laeuft.

    die php laeuft nicht mehr weiter und ende .

    es kann sein das das eventuell was mit den streamtiteln zu tun gat ( aenderung im schnitt alle 15 sec ) was ich aber bezweifel …

    wenn ich wieder ueber eine anstaendige leitung verfuege kann ich mal aufm root nachsehen . momentan sind mir dahingehend die haende gebunden …

  19. hallo,
    halo das System habe ich soweit zum laufen bekommen …
    ich habe lediglich das problem, das troz streamwatch
    sich das ganze nach 3 4 tagen haengt und sich abschiesst.

    ergo ist das leider momentan nicht wirklich tauglich um 24/7 transcoding von mp3 streams zu betreiben

    malsehen was die zukunft bringt , obs vielleicht doch irgendwann ne waschechte loesung gibt dieses Vorhaben zu verwirklichen.

    1. Keine Ahnung, bei mir funktioniert das mit dem Antenne Bayern Stream eigentlich sehr stabil. Was meinst Du denn mit “aufhaengen” – es wird ja sicherlich eine Fehlermeldung angezeigt – wie lautet diese denn?

  20. eine frage habe ich jedoch noch,
    bei deinem beispiel greifst du ja den antenne stream ab. dieser ist bekanntlich 24/7 online ohne reconnect.

    was ich festgestellt habe ist, das wenn sich bei meinem server der moderator einklinkt und die playlist kickt, reicht die kurze zeit aus das der “transcoder” abschmiert.

    besteht eine möglichkeit das zu fixen ?

    1. Prinzipiell ja.

      Schreibe ein Shell-Script, welches eine While-Schleife durchläuft. Also z.B. while (1) {…} bei jedem reconnect startest Du dann einfach alles wieder von vorne. Sollten nicht mehr als ein paar Zeilen sein:

      Leg ein File an: streamwatch.pl:

      #!/usr/bin/perl

      while (1) {
      system(“aacplusenc streamin – 32 | ./simple_server.php & mplayer -ao pcm:file=streamin http://mp3.webradio.antenne.de:80“);
      }

      dann:
      perl streamwatch.pl

      Du kannst das auch als screen starten:

      screen -dmS mystream perl streamwacht.pl

      mit STRG+A+D detachest Du den Screen, mit screen -r mystream holst Du den Screen zurueck.

  21. ach damn it. entschuldige war mein fehler ich habe das mkfifo im falschen ordner gehabt : P

  22. Hmm naja mplayer rennt aacplusenc auch …
    sc_serv sowieso
    der encoder greift den source stream auch erfolgreich ab,
    aber die source wird beim sc_serv immer sofort nach connect gedroppt. kA wieso ??

  23. Hallo,

    ich hab das hier mal alles nach diese Anleitung gemacht…

    Folgende Meldungen bekomme ich:

    Starten des SHOUTCast Servers:
    alster019:/etc/init.d # ./SI-SHOUTCast_AAC start
    Starte SI-AACP Server (Listner Server SHOUTcast)
    ***********************************************
    ** SHOUTcast Distributed Network Audio Server
    ** Copyright (C) 1998-2004 Nullsoft, Inc. All Rights Reserved.
    ** Use “sc_serv filename.ini” to specify an ini file.
    ***********************************************
    done
    alster019:/etc/init.d #

    Soweit OK… Server Läuft…

    Nun der rest:

    alster019:/home/rdt-technik/StreamSystem # aacplusenc streamin -32 | ./aacStream.php & mplayer -ao pcm:file=aacStreamIn http://127.0.0.1:15000/live
    -bash: aacplusenc: command not found
    : No such file or directoryhp
    ./aacStream.php: line 2: =: command not found
    : command not foundne 2:
    ./aacStream.php: line 3: =: command not found
    : command not foundne 3:
    ./aacStream.php: line 4: syntax error near unexpected token `(‘
    ‘/aacStream.php: line 4: `$sock = fsockopen($address,($port+1),&$errno, &$errstr, 10);
    [1] 6875
    MPlayer 1.0rc1-3.3.5 (C) 2000-2006 MPlayer Team
    CPU: AMD Opteron(tm) Processor 148 (Family: 15, Model: 39, Stepping: 1)
    CPUflags: MMX: 1 MMX2: 1 3DNow: 1 3DNow2: 1 SSE: 1 SSE2: 1
    Compiled with runtime CPU detection.
    Can’t open joystick device /dev/input/js0: No such device
    Can’t init input joystick
    mplayer: could not connect to socket
    mplayer: Connection refused
    Failed to open LIRC support. You will not be able to use your remote control.

    Playing http://127.0.0.1:15000/live.
    Resolving 127.0.0.1 for AF_INET6…
    Couldn’t resolve name for AF_INET6: 127.0.0.1
    Connecting to server 127.0.0.1[127.0.0.1]: 15000…
    Cache size set to 320 KBytes
    Cache fill: 0.00% (0 bytes)
    ICY Info: StreamTitle=’Dido – Don`t Leave Home’;StreamUrl=’http://www.sound-inferno.de’;

    Audio file file format detected.
    ==============================================
    Opening audio decoder: [mp3lib] MPEG layer-2, layer-3
    mpg123: Can’t rewind stream by 680 bits!
    AUDIO: 44100 Hz, 2 ch, s16le, 96.0 kbit/6.80% (ratio: 12000->176400)
    Selected audio codec: [mp3] afm: mp3lib (mp3lib MPEG layer-2, layer-3)
    ==============================================
    [AO PCM] File: aacStreamIn (WAVE)
    PCM: Samplerate: 44100Hz Channels: Stereo Format s16le
    [AO PCM] Info: Faster dumping is achieved with -vc null -vo null -ao pcm:fast
    [AO PCM] Info: To write WAVE files use -ao pcm:waveheader (default).

    MPlayer interrupted by signal 2 in module: ao2_init
    [1]+ Exit 2 aacplusenc streamin -32 | ./aacStream.php
    alster019:/home/rdt-technik/StreamSystem #

    1. Wie bekomme ich den aacplusenc Installiert..? (System suse 9.3)
    2. Wie soll sich das phpscript auf dem Server einloggen um überhaupt Streamen zu können..?

    Wäre klasse wenn dir dazu noch was einfallen täte..

    LG DJ Dac

Comments are closed.