Salvare gli stream RealAudio in MP3

audiobook

Un amico mi ha fatto conoscere la possibilità di scaricare e salvare gli audiolibri che si possono ascoltare (in diretta) su Rai Radio Tre durante la trasmissione Ad alta voce, e (poi) in streaming sul sito web della Rai. Si tratta di grandi classici della letteratura internazionale letti da “voci capaci”, ognuno costituito da 15/20 puntate.

Visto che scaricare e convertire in MP3 una puntata alla volta era veramente noioso ho scritto uno script bash che, dato l’indirizzo di una pagina web che contiene più link a degli stream RealAudio (come le pagine della trasmissione Ad alta voce), scarica e converte automaticamente e in parallelo tutti gli stream citati.

Lo script in questione l’ho battezzato, con ben poca fantasia, savera (SAVE RealAudio). Per poterlo utilizzare è necessario avere installati, e disponibili nel PATH di sistema, i comandi curl, mplayer, lame (per output MP3) e/o ffmpeg (per il formato AAC), oltre che, naturalmente, la shell Bash. Io l’ho testato su Linux e Mac OS X ma non è escluso che, una volta installati i programmi richiesti, funzioni anche su Windows con Cygwin.

Installazione su Ubuntu Linux

Vista la grande diffusione, le istruzioni riportate sono per Ubuntu/Debian ma non sarà difficile adattarle anche a distribuzioni diverse.

  1. Installare i programmi necessari con il seguente comando dato da terminale:
    $ sudo apt-get install curl mplayer lame ffmpeg
  2. scaricare lo script da qui:
  3. spostarlo in una delle cartelle che fanno parte della variabile di ambiente PATH. Ottime scelte sono /usr/local/bin (per un’installazione di sistema) e /home/<nomeutente>/bin (solo per l’utente <nomeutente>) perché non vengono gestite dal sistema di pacchettizzazione della distribuzione e quindi non si genera alcun conflitto;
  4. attivare i permessi di esecuzione con il comando
    $ sudo chmod +x /path/to/savera

Installazione su Mac OS X

Procurarsi tutti i programmi necessari su Mac OS X è decisamente più laborioso che su Linux in quanto i vari software hanno origini diverse e si installano in modo diverso l’uno dall’altro: curl fa eccezione perché è preinstallato (almeno su Leopard), mplayer si trova come binario precompilato, lame si trova su Fink (ma non in forma binaria) e di ffmpeg si trovano solo i sorgenti. Per chi ha capito al volo questo paragrafo non resta che installare il software e provare lo script. Per tutti gli altri, non è escluso che, prima o poi, realizzi un pacchetto complessivo con tutto il software necessario (magari con un’interfaccia in AppleScript).

Uso

Lo script crea i file MP3/AAC nella cartella corrente, quindi va lanciato in una cartella creata appositamente allo scopo. Ad esempio

$ mkdir -p ~/Musica/Audiolibri/Lolita
$ cd ~/Musica/Audiolibri/Lolita

A questo punto è sufficiente lanciare savera con argomento il link alla pagina dell’audiolibro che si vuol salvare (il formato di default è Mp3):

$ savera http://www.radio.rai.it/radio3/terzo_anello/alta_voce/archivio_2004/eventi/2004_06_01_lolita/index.cfm

Le sorgenti accettate da savera sono:

  • l’URL http://&#8230; di una pagina html che contiene i link a uno o più stream (come nel caso degli audiolibri RAI);
  • l’URL http://&#8230; di un file .ram (playlist di RealPlayer);
  • l’URL rtsp://… di uno stream RealAudio;
  • un file .ram locale.

Una volta lanciato, savera scaricherà e convertirà – in parallelo – tutte le sorgenti indicate e tornerà al prompt dei comandi solo dopo aver terminato. Il tempo impiegato dipende dal numero di stream, dalla velocità del vostro collegamento ad Internet, dalla potenza di calcolo del vostro computer; se si ha una connessione ADSL sufficientemente veloce e un computer abbastanza potente, il tempo di conversione dipenderà unicamente dalla durata della puntata più lunga, in quanto l’audio viene comunque trasferito in tempo reale.

Ci sono alcune opzioni che si possono scegliere la cui documentazione viene visualizzata con l’opzione -h:

$ savera -h

Aggiornamento per Mac OS X: mi sono appena avvicinato ai Servizi e alla loro creazione con Automator. Realizzare un servizio che lanci uno script di shell è di una semplicità disarmante! Io ne ho fatto uno che è utilizzabile da Safari e usa savera per scaricare nella cartella Download tutti gli stream RealAudio linkati dalla pagina corrente. L’ho fatto e provato su Snow Leopard. Se sei interessato fai così:

  1. installa savera e tutti i programmi richiesti sul tuo Mac, come specificato sopra. La posizione prevista per savera è /usr/local/bin;
  2. scarica il file del servizio: Salva stream RealAudio.zip;
  3. copia il contenuto del file ZIP nella cartella ~/Libreria/Services (se la cartella Services non c’è ancora, creala).

D’ora in avanti, quando usi Safari, clicca la voce di menù Safari->Servizi->Salva stream RealAudio: un ingranaggio si metterà a ruotare nella barra dei menù e la cartella Download iniziarà a popolarsi con i file MP3.

Trappole

  • Se in precedenza hai già scaricato savera, scaricalo di nuovo: le versioni precedenti alla revisione SVN 313 non funzionano con il servizio di Automator!
  • Se il file scaricato con Safari ha nome savera.sh, rinominalo semplicemente savera (senza estensione) altrimenti, anche in questo caso, il servizio non funzionerà.

Appendice: lo script

Segue il contenuto dello script:

#!/bin/bash
#
# Save to MP3 or AAC files RealAudio streams extracted from web pages or directly
# supplied. An example are the audiobook streams from the Italian state
# Broadcasting Service (RAI) radio programme "Il terzo anello" at
# http://www.radio.rai.it/radio3/terzo_anello/alta_voce/archivio_2009/eventi/2009_01_12_diceriadelluntore/index.cfm
#
# Thanks to Alessandro Meiattini (http://www.meiaweb.com/).
#
# Copyright (C) 2009-2011 Alessandro Morgantini <gpz500 at technologist dot com>
#
# Released under the terms of GPL2 (http://www.gnu.org/licenses/gpl-2.0.html).
# Modified on $Date: 2011-01-25 21:26:38 +0100 (Tue, 25 Jan 2011) $
# SVN $Revision: 313 $
#set -x

# Defaults
DEFAULT_CODEC="MP3"
DEFAULT_MAX_NPROC=30

CODEC=""
COMMAND_NAME=$(basename $0)
ARG_URLS=""
MAX_NPROC=0
NPROC=0
POOL=""
URLS=""
USAGE="Usage: ${COMMAND_NAME} [options] SOURCE [SOURCE ...]
Save to MP3 or AAC files the RealAudio streams (.ram files) from the Internet

Accepted options:
  -h, --help          Print this help
  -m, --mp3           Select MP3 as output format (default)
  -a, --aac           Select AAC as output format
  -n, --nocodec       Save the streams with no conversion
  -j, --jobs=N        Set the parallelism degree to N ($DEFAULT_MAX_NPROC by default)

Valid SOURCEs are:
  an http://* web page's URL wich contains links to *.ram RealAudio playlists;
  an http://*.ram RealAudio playlist's URL;
  an rtsp://*.ra RealAudio stream's URL;
  a *.ram local RealAudio playlist.

E.g.:
$COMMAND_NAME http://www.radio.rai.it/radio3/terzo_anello/alta_voce/archivio_2009/eventi/2009_01_12_diceriadelluntore/index.cfm"
TEMP_FILES=""

# Return on the standard output the extension part (the part after the last
# period) of the argument
get_extension ()
{
	NAME=$(basename $1)
	if echo "$NAME" | grep "\." >/dev/null; then
		echo -n "$NAME" | sed 's/^.*\.\([^\.]*\)$/\1/'
	else
		echo -n ""
	fi
}

# Add a process to the pool
add_to_pool ()
{
	POOL="$POOL $1"
	NPROC=$(($NPROC + 1))
}

# Remove from the pool the terminated processes
update_pool ()
{
	local OLDPOOL="$POOL"
	local PID
	POOL=""
	NPROC=0
	for PID in $OLDPOOL; do
		ps $PID >/dev/null && add_to_pool $PID
	done
}

# Check for terminated processes in the pool
check_pool ()
{
	local PID
	for PID in $POOL; do
		if ! ps $PID >/dev/null; then
			update_pool
			break
		fi
	done
}

# Kill pool's processes
kill_pools_procs ()
{
	local PID
	for PID in $POOL; do
		kill $PID >/dev/null 2>&1
	done
}

# Command line parsing
while [ -n "$1" ]; do
	case "$1" in
		--help|-h)
			echo "$USAGE"
			exit 0
			;;
		--mp3|-m)
			if [ -z "$CODEC" ]; then
				CODEC="MP3"
			else
				echo "$COMMAND_NAME error: you can't specify more than one output format" >&2
				echo "$USAGE" >&2
				exit 1
			fi
			shift
			;;
		--aac|-a)
			if [ -z "$CODEC" ]; then
				CODEC="AAC"
			else
				echo "$COMMAND_NAME error: you can't specify more than one output format" >&2
				echo "$USAGE" >&2
				exit 1
			fi
			shift
			;;
		--nocodec|-n)
			if [ -z "$CODEC" ]; then
				CODEC="NONE"
			else
				echo "$COMMAND_NAME error: you can't specify more than one output format" >&2
				echo "$USAGE" >&2
				exit 1
			fi
			shift
			;;
		-j)
			if [ $MAX_NPROC -eq 0 ]; then
				shift
				MAX_NPROC=$1
			else
				echo "$COMMAND_NAME error: you can't specify more than one -j or --jobs option" >&2
				echo "$USAGE" >&2
				exit 1
			fi
			shift
			;;
		--jobs*)
			if [ $MAX_NPROC -eq 0 ]; then
				MAX_NPROC=$(echo "$1" | cut -d = -f 2)
			else
				echo "$COMMAND_NAME error: you can't specify more than one -j or --jobs option" >&2
				echo "$USAGE" >&2
				exit 1
			fi
			shift
			;;
		-*)
			echo "$COMMAND_NAME error: option \"$1\" unkown" >&2
			echo "$USAGE" >&2
			exit 2
			;;
		*)
			ARG_URLS="$ARG_URLS $1"
			shift
			;;
	esac
done

# Preliminary checks
if [ -z "$(which mplayer)" ]; then
	echo "Sorry: you must have mplayer installed." >&2
	exit 1
fi
if [ -z "$(which curl)" ]; then
	echo "Sorry: you must have curl installed." >&2
	exit 1
fi
if [ -z "$CODEC" ]; then
	CODEC="$DEFAULT_CODEC"
fi
echo "$COMMAND_NAME: the output format is $CODEC"
if [ "$CODEC" = "MP3" -a -z "$(which lame)" ]; then
	echo "Sorry: you must have lame installed." >&2
	exit 1
elif [ "$CODEC" = "AAC" -a -z "$(which ffmpeg)" ]; then
	echo "Sorry: you must have ffmpeg installed." >&2
	exit 1
fi
if [ $MAX_NPROC -eq 0 ]; then
	MAX_NPROC=$DEFAULT_MAX_NPROC
fi
echo "$COMMAND_NAME: the parallelism degree is $MAX_NPROC"
if [ -z "$ARG_URLS" ]; then
	echo "$COMMAND_NAME error: you must specify at least a valid URL" >&2
	echo "$USAGE" >&2
	exit 4
fi

# Retrieving URLs
for URL in $ARG_URLS; do
	if echo "$URL" | grep -i "^rtsp://.*"; then
		URLS="$URLS $URL"
	elif echo "$URL" | grep -i "^http://.*\.ram$"; then
		URLS="$URLS $(curl -s $URL | cat -v | sed 's/\^M$//')"
	elif echo "$URL" | grep -i "^http://.*"; then
		INPUTFILE=$(mktemp /tmp/savera.XXXXXXXXXX)
		curl -s "$URL" | grep "http://.*\.ram" | sed "s/^.*\(http:\/\/.*\.ram\).*$/\1/" >"$INPUTFILE"
		while read RAM; do
			URLS="$URLS $(curl -s $RAM | cat -v | sed 's/\^M$//')"
		done &2
		fi
	else
		echo "Sorry: \"$URL\" is an unkown type URL." >&2
		exit 1
	fi
done

# Check if we are behind a proxy
if [ -n "$http_proxy" ]; then
	echo "$COMMAND_NAME: sorry. Because of mplayer, $COMMAND_NAME can't work behind an http proxy."
	echo "In case you know out to use them, the URLs are saved in the file ra_urls.txt"
	[ -e ra_urls.txt ] && rm ra_urls.txt
	for URL in $URLS; do
		echo $URL >>ra_urls.txt
	done
	exit 0
fi

# Set the SIGINT handler
clean_on_exit ()
{
	kill_pools_procs
	for file in $TEMP_FILES; do
		rm -f "$file"
	done
}
trap clean_on_exit SIGINT

# Download the streams
for URL in $URLS; do
	EXT=$(get_extension "$URL")
	FILENAME=$(basename "$URL" | sed 's/\.'$EXT'$//')
	if [ "$CODEC" = "NONE" ]; then
		mplayer -quiet -noframedrop -dumpfile "$FILENAME.$EXT" -dumpstream "$URL" &
	else
		mkfifo "$FILENAME.wav" && TEMP_FILES="$TEMP_FILES $FILENAME.wav"
		mplayer -quiet -noframedrop -ao pcm:file="$FILENAME.wav" "$URL" &
		if [ "$CODEC" = "MP3" ]; then
			lame --quiet "$FILENAME.wav" "$FILENAME.mp3" &
		else
			ffmpeg -i "$FILENAME.wav" -acodec libfaac -ab 128k -f aac "$FILENAME.m4a" &
		fi
	fi
	add_to_pool $!
	while [ $NPROC -ge $MAX_NPROC ]; do
		check_pool
		sleep 0.5
	done
done
wait

# Delete all intermediate files
clean_on_exit
echo "All done!"
Advertisements

18 Pensieri su &Idquo;Salvare gli stream RealAudio in MP3

  1. Questo post è davvero interessante. Complimenti! Erano mesi che stavo cercando su internet qualcosa che mi aiutasse a trasformare in mp3 gli stream RAM, quindi ero tutto contento quando mi sono accorto di essere fra quelli che usa mac osx e non ha capito al volo la parte di lame.
    Visto che l’hai anche già ipotizzato, ti prego di realizzare il pacchetto complessivo con tutto il software necessario (magari con un’interfaccia in AppleScript)!!!
    In ogni caso, complimenti e grazie. Ciao, g.

    • …. mi sembra un ottimo consiglio per chi non è ancora così addentro al linguaggio di programmazione.
      Inoltre ho visto che ci sono un sacco di altre cose interessantissime!
      Grazie

  2. Bravo, complimenti. Sono anch’io un fanatico di ad “altavoce”. In passato i file erano dati direttamente in MP3 ora invece in CFM e per un non addetto ai lavori non è facile convertirli. Muoio dalla voglia di farmi un CD di Pinocchio e dell’Isola di Arturo che stanno leggendo in questi giorni. Ho un Mac ma non so seguire le tue istruzioni. Aspetto pertanto con ansia che tu realizzi al più presto il pacchetto complessivo. Diventeresti un beneffattore della cultura e meriteresti il Nobel.
    Con affetto,

    Paolo

    • Purtroppo il progetto di fare un’interfaccia grafica per Mac OS X langue…
      Se hai un Mac con processore Intel penso che la via più rapida sia installare un programma di virtualizzazione (VirtualBox è gratis e va benissimo…), all’interno di questo installare Ubuntu Linux e quindi seguire le istruzioni per Ubuntu…

  3. Anch’io ho apprezzato davvero molto questo script, che dovrebbe risolvere un bel po’ di problemi che mi si sono sempre presentati per salvare le serie di Ad Alta Voce.

    Purtroppo, pero’, vedo che lo script (uso debian squeeze) dopo qualche secondo si interrompe sempre con Segmentation fault e non riesco proprio a capire perche’.
    Ecco i messaggi:

    kir@papaya:~/bin$ ./savera –jobs=2 “http://www.radio.rai.it/radio3/terzo_anello/alta_voce/archivio_2009/eventi/2009_09_01_lisoladiarturo/index.cfm”
    savera: the output format is MP3
    savera: the parallelism degree is 2
    http://www.radio.rai.it/radio3/terzo_anello/alta_voce/archivio_2009/eventi/2009_09_01_lisoladiarturo/index.cfm
    ./savera: line 232: 24210 Segmentation fault mplayer -quiet -noframedrop -ao pcm:file=”$FILENAME.wav” “$URL”
    ./savera: line 232: 24223 Segmentation fault mplayer -quiet -noframedrop -ao pcm:file=”$FILENAME.wav” “$URL”

    Qualcun altro ha avuto errori simili?
    Grazie in anticipo e saluti a tutti.

  4. Beh…che dire…complimenti veramente…l’ho testato su mac os x e funziona perfettamente…è così bello recuperare il link rtsp, fare una bella playlist .ram e lasciare che faccia tutto lui…
    Solo un consiglio…io per fare quello che ho detto ho dovuto caricare la playlist suddetta in un server perché savera accetta solo link…potresti prevedere anche la possibilità di ricevere file .ram non da web.
    Per il resto è veramente ottimo

    • Grazie dei complimenti e dell’idea!
      Ho appena modificato lo script in modo che accetti anche i file .ram locali: riscaricalo e provalo.

      • Perfetto…adesso accetta anche i file .ram da locale…una bella comodità…non dovrò più caricarli ogni volta sul server…grazie…
        Volevo provare a modificarlo da solo ma non ero esattamente a mio agio con questo linguaggio purtroppo…e poi mi sembrava giusto lo facessi tu e rendessi disponibile la modifica a tutti…
        Volevo farti anche un’altra osservazione(spero tu non me ne voglia a male)…se per esempio termino lo script con ctrl+c durante il download, si chiude ma lascia attivi tutti i processi lame che aveva aperto fino a quel momento…non so se tu possa aggiungere a clean_on_exit anche la capacità di terminare i processi lame…

        Di nuovo complimenti…

      • Seguendo il tuo suggerimento ho apportato una modifica in modo che, quando esce, savera chiuda tutti i processi figli.
        Ciao!

  5. Ah…io utilizzo un mac e ho impiegato poco più di mezz’ora ad installare tutti i programmi necessari e preciso: non li avevo mai sentiti nominare fino a quel momento quindi non li conoscevo. A tutti quelli che desiderano una interfaccia per l’installazione direi di provare almeno prima di chiederla a gran voce. Sono pochi passaggi e non possono fare altro che aiutarvi anche a capire meglio come funzionano certe cose che vanno oltre alla semplice installazione di 4 programmini…potrebbe servirvi anche in futuro sapere per esempio come attivare uno script o come farlo partire…finché però tutti aspettano la pappa pronta non si va da nessuna parte…
    Scusate ma lo dovevo dire.

    Saluti.

  6. Sul mio Mac lo script sembra funzionare ma quando provo a scaricare files da questo sito rtsp://mm3.rai.it/clip1/radio3/napoli/ilcammino/2008/ilcammino2008_04_25.ra mplayer si blocca sull’output “starting playback…”. Se ammazzo il job mi da
    “Mplayer interrupted by signal 15 in module: decode_audio
    Mplayer interrupted by signal 13 in module: uninit_ao”

    Ho provato a utilizzare solo il comando Mplayer -noframedrop -dumpfile – dumpstream ma ancora si blocca su
    “Mplayer interrupted by signal 15 in module: dumpstream”

    Se faccio solo il play, lo sento senza problema. qualcuno puo’ aiutarmi a scaricare lo stream???
    Grazie

    Marco

    • Ho appena provato e… funziona: devi solo avere pazienza. Siccome la trasmissione è in streaming lo scaricamento avviene in tempo reale. La trasmissione è di 27 minuti, quindi servono 27 minuti per scaricarla e convertirla… Puoi tenere d’occhio l’evolversi del processo andando a vedere come aumenta la dimensione del file .mp3 creato. Ciao, Alessandro
      PS: la dimensione finale del file MP3 è di 13,1 MB.

  7. Sono nuovo di ambiente linux, ho copiato in file system il tuo file.
    che risulta avere l’indirizzo qui sotto.
    /usr/local/bin

    Quando da terminale do il comando relativo ai permessi mi da questo errore.

    paolo@paolo:~$ sudo chmod +x /usr/local/bin/to/savera
    [sudo] password for paolo:
    chmod: impossibile accedere a `/usr/local/bin/to/savera’: Nessun file o directory
    paolo@paolo:~$

    Potresti cortesemente aiutarmi.

    Grazie Paolo

  8. Le sono davvero molto grato per avere ideato questo utilissimo script, e non vorrei sembrare incontentabile nel chiederle se ha valutato l’eventualità che i file di output possano essere numerati progressivamente.
    Fra l’altro lo scaricamento sul mio desktop ubuntu avviene in pochi minuti (tutte le puntate)
    grazie

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...