Manipolazione file audio da command line, alcuni esempi

Della serie “Il potere della Linea di Comando” o anche “May the force (of the Command Line) be with you” vediamo come manipolare file audio da linea di comando tramite le utility che si possono trovare sui sistemi GNU/Linux.

In particolare, i tool utilizzati oggi sono:

  • cuetools: “set of utilities for working with Cue Sheet (cue) and Table of Contents (toc) files“.
  • shntool: “multi-purpose tool for manipulating and analyzing WAV files”
  • vorbis-tools: comandi vari per la generazione e manipolazione di file OGG

Obiettivo: dato un album contenuto in un unico file in formato FLAC e indicizzato tramite un file CUE, generare un file OGG per ogni traccia.

L’operazione è composta da due fasi:

  • Dividere il file FLAC in tanti file, uno per traccia
  • Convertire i file ottenuti in OGG cercando di inserire anche qualche tag estratto dal CUE

Prima proposta di soluzione (semplice ma sbagliata)

Passo (1): Generazione di tanti file WAV uno per traccia dandogli come nome split-trackNN.wav dove NN è il numero della traccia.

$ cuebreakpoints cue_file.cue | shnsplit audio_file.flac

Passo (2): conversione in formato OGG.

$ oggenc *.wav

Per fare tutto con un unico comando è anche possibile dire a shnsplit di effettuare direttamente la conversione in OGG:

$ cuebreakpoints cue_file.cue | shnsplit -o 'cust ext=ogg oggenc - -o %f' audio_file.flac

con questo comando si creano direttamente i file split-trackNN.ogg.

Seconda soluzione (leggermente più complicata, ma migliore)

Un metodo alternativo per leggere il file CUE consiste nel farlo leggere direttamente al comando shnsplit tramite l’opzione -f. In questo modo il comando cuebreakpoints non è più necessario e soprattutto, come vedremo, sarà facile dare ai file generati un nome più significativo.

Il comando è:

$ shnsplit -o 'cust ext=ogg oggenc - -o %f' -f cue_file.cue audio_file.flac

NOTA: Un problema minore di questo modo di lavorare è che, almeno in alcuni casi, viene creato anche un file di indice 00 che contiene un “pre-gap”. Di fatto è un file molto breve senza audio. Non ho trovato un modo per evitare di generarlo, per cui se viene creato va semplicemente cancellato dopo la conversione.

Il grosso vantaggio dell’opzione -f è invece che leggendo il file CUE direttamente è possibile nominare i file che vengono creati in modo automatico utilizzando le informazioni di traccia presenti nel file CUE. L’opzione da utilizzare è -t.

Per esempio per creare i file nel formato NN_-_TrackTitle.ogg (NN = track number) si può utilizzare il seguente comando:

$ shnsplit -o 'cust ext=ogg oggenc - -o %f' -t "%n_-_%t" -f cue_file.cue audio_file.flac

Se si vuole, si può anche utilizzare l’opzione -m per evitare l’uso di caratteri speciali nei nomi di file. Per esempio, per utilizzare il carattere underscore al posto degli spazi si può dare il seguente comando:

$ shnsplit -o 'cust ext=ogg oggenc - -o %f' -t "%n_-_%t" -m \ _ -f cue_file.cue audio_file.flac

Come inserire i tag nei file OGG

Vediamo infine come inserire le informazioni di album e traccia (tag) nei file OGG generati. E’ tutto molto semplice, basta utilizzare il comando cuetag:

$ cuetag cue_file.cue *.ogg

N.B: per evitare di avere errori ricordarsi di cancellare il file pregap di indice 00 eventualmente creato da shnsplit.

Per controllare il valore dei tag inserito nei file OGG si può utilizzare il comando vorbiscomment.

$ vorbiscomment file_ogg.ogg

CREDITS: Siti consultati:

Manipolazione file PDF, altri esempi

Oggi un amico mi ha passato alcune pagine scannerizzate da una rivista in formato PDF (un file per pagina).

Primo esercizio unire le pagine. Come detto in un precedente post, per fare queste cose uso tool command line, in particolare anche qui si presta bene  pdftk. Per unire più file basta il comando:

user@host:~$ pdftk file1.pdf file2.pdf file2.pdf output output_file.pdf

E i tre file indicati vengono incollati insieme nel file output_file.pdf.

Secondo esercizio. Non ero soddistatto dalla dimensione a mio parere eccessiva del file risultante (dovuta alla dimensione dei file di partenza) e allora ho cercato un modo per ridurre la dimensione. A parte il fatto che sicuramente esisteranno altri metodi usando anche il solito pdftk, ho trovato una soluzione curiosa che consiste nel convertire il file PDF prima in formato Postscript poi indietro nuovamente in formato PDF. Il tutto utilizzando i tool command line che vengono con un altro programma, Ghostscript.

I comandi da dare sono i seguenti:

user@host:~$ pdf2ps output_file.pdf output_file.ps

user@host:~$ ps2pdf output_file.ps new_file.pdf

Il file intermedio, output_file.ps, essendo Postscript è ben più grosso del PDF originario, ma il PDF risultante dal secondo passo è (almeno nel mio caso) 5 volte più piccolo di quello di partenza, senza notare una perdita significativa nella qualità del risultato. Probabilmente il comando ps2pdf utilizza automaticamente un qualche algoritmo di compressione, fatto sta senza particolare fatica ho ottenuto il risultato richiesto.

Un potente programma per manipolare file PDF: pdftk

Ultimamente mi sto appassionando alle scienze economiche e una delle prime cose che ho imparato è che se ci sono due modi di fare una cosa allo stesso modo, è meglio scegliere quella più economica, che sia in termini di spesa o di tempo da investirci.

Questo principio trova una grande applicazione sull’uso degli applicativi da linea di comando sui PC con GNU/Linux. Uno dei grandi vantaggi di questa piattaforma è infatti la disponibilità di comandi molto potenti da lanciare da terminale, con i quali è possibile fare praticamente qualsiasi cosa.

Vediamo allora un’applicazione del principio di economia (spero si dica così): è davvero necessario spendere soldi e installare complessi applicativi grafici che portano via spazio disco e risorse al sistema per fare delle semplici operazioni come estrarre delle pagine da un documento PDF?

Sicuramente no. Infatti per fare operazioni di questo tipo basta un semplice applicativo command line come pdftk (PDF toolkit).

Supponiamo di voler estrarre da un documento PDF di 100 pagine le pagine da 10 a 20. Usando pdftk questa cosa si fa facilmente aprendo un terminale ed inserendo il seguente semplice comando:

user@host:~$ pdftk input_file.pdf cat 10-20 output output_file.pdf

Questo comando estrae dal file input_file.pdf le pagine salvandole nel file output_file.pdf.

Con questo semplice ma potente programma è ovviamente possibile fare anche molte altre cose, ma per oggi il mio tempo si è esaurito. Provate a dare un’occhiata alla man page o alla documentazione sul sito del programma.

Un potente programma per effettuare backup: rsync

Un ringraziamento preventivo a Matteo, che a suo tempo, in un progetto in cui lavoravamo insieme, si occupò di determinare le migliori opzioni da utilizzare con il comando rsync per l’implementazione delle operazioni descritte in questo articolo.

Una delle utility più interessanti per effettuare copia di file, sincronizzazione di directory e backup nell’ecosistema GNU/Linux è il programma rsync. Come molto spesso capita, dietro l’apparenza banale di una utility command line si nasconde un programma molto potente che laconicamente si autodefinisce “a fast, versatile, remote (and local) file-copying tool“.

In questo articolo si dimostrerà come utilizzare la funzionalità di sincronizzazione tra directory offerta dal programma per copiare il contenuto di una directory in una seconda area. L’applicazione è ovvia: effettuare il backup della prima directory (che nel seguito chiameremo “primaria”) nella seconda (definita “secondaria”).

Per rendere più interessante la dimostrazione supporremo che le due directory risiedano su due PC diversi (ma le stesse operazioni possono essere effettuate anche con le due aree poste sullo stesso PC). Naturalmente occorre che i due PC siano connessi in rete possibilmente senza firewall nel mezzo che potrebbero bloccare le porte necessarie a rsync per lavorare.

La configurazione rsync scelta è quella client-server:

  • lato directory primaria si manterrà il programma in esecuzione come demone (server) pronto a rispondere alle interrogazioni dei client
  • lato directory secondaria si lancerà il comando da linea di comando (client); al termine di ogni sincronizzazione il programma esce.

Nel seguito indicheremo ip_server l’indirizzo IP del server e con ip_client quello del client.

Installazione

Normalmente rsync è già presente di default sulle più diffuse distribuzioni GNU/Linux. Nel caso non fosse presente, installarlo seguendo le procedure standard della distribuzione. Per esempio su Debian/Ubuntu e derivati dare il comando:

sudo apt-get install rsync

Configurazione e startup demone lato server

Per prima cosa definiamo la directory di cui si vuol effettuare il backup. Supponiamo sia /home/user/workarea. Supponiamo che al suo interno sia presente un unico file di nome foo.bar.

Come seconda cosa occorre preparare il file di configurazione per il server rsync. Supponiamo sia /home/user/rsyncd.conf. Nel nostro esempio il suo contenuto deve essere il seguente:

[WorkArea]
path=/home/user/workarea/
log=/home/user/logs/rsyncd.log
max verbosity

A questo punto per lanciare il server il comando da dare è il seguente:


user@host:~$ sudo rsync --daemon --config=/home/user/rsyncd.conf
user@host:~$ _

Se si controlla con il comando ps si vedrà il server in esecuzione.

Sincronizzazione lato client

Prima di effettuare la sincronizzazione vera e propria può essere utile lanciare il comando in modalità “dry-run”: si interroga il server per capire se deve essere effettuata un’operazione di sincronizzazione, cioè se lato server ci sono dei file nuovi o se alcuni file sono stati modificati. Per effettuare l’operazione il comando da dare è il seguente:


user@host:~$ rsync --dry-run -v --force --delete -a --port=873 <ip_server>::WorkArea workarea_backup
created directory workarea_backup
./
foo.bar
sent 36 bytes received 77 bytes 226.00 bytes/sec
total size is 56 speedup is 0.50 (DRY RUN)

Dall’output del comando si capisce che c’è la directory root della workarea modificata e il file foo.bar  modificato. Si capisce anche che verrebbe creata la directory di destinazione del backup, workarea_backup. Vediamo nel dettaglio il significato dei parametri utilizzati:

  • --dry-run: non effettua alcuna operazione, mostra solo le operazioni che verrebbero effettuate se non ci fosse questa opzione
  • -v: aumenta la verbosità delle informazioni mostrate a schermo
  • --force: forza la cancellazione delle directory non più esistenti anche se non vuote
  • --delete: se da server sono stati cancellati dei file ancora presenti nell’area di backup (come risultato di una precedente sincronizzazione), questi vengono cancellati
  • --port=873: cerca il server sulla porta 873 (la porta standard del comando rsync)
  • <ip_server>::WorkArea: indirizzo IP del server e “stanza” del file di configurazione con le informazioni dell’area da sincronizzare
  • workarea_backup: directory locale dove salvare il contenuto della sincronizzazione. Da notare che il contenuto di questa directory viene modificato in modo da rispecchiare il contenuto dell’area sul server, per cui eventuali file estranei verrebbero cancellati.

A questo punto, per effettuare la sincronizzazione ripetere il comando senza l’opzione –dry-run:

user@host:~$ rsync -v --force --delete -a --port=873 <ip_server>::WorkArea workarea_backup
created directory workarea_backup
./
foo.bar
sent 36 bytes received 77 bytes 226.00 bytes/sec
total size is 56 speedup is 0.50 (DRY RUN)

Verificare il contenuto della directory workarea_backup: adesso contiene il file foo.bar presente sul server.

D’ora in avanti, per mantenere aggiornata la directory di backup, basterà ripetere periodicamente il comando sul client.

Bonus track: uso di netcat per controllare lo stato di una porta

Infine un “bonus track” per vedere come lato client si può utilizzare la utility netcat per controllare se il server è attivo. Questo può essere utile soprattutto in script per controllare che il server sia presente prima di inoltrare i comandi visti in precedenza.

Come dice la sua manpage, “The nc (or netcat) utility is used for just about anything under the sun involving TCP or UDP“. In questo caso noi la useremo dal client per controllare che il server rsync sia in esecuzione. La porta su cui sta in ascolto il server rsync è la 873. Il comando netcat da dare per controllare se il server è attivo è il seguente:

user@host:~$ nc -z -n -w 1 <ip_server> 873
user@host:~$ _

Il significato delle opzioni è il seguente:

  • -z: effettua uno scan della porta senza inviare pacchetti
  • -n: non usa DNS
  • -w 1: imposta il timeout di attesa della risposta a 1 secondo

Il comando come spesso capita sulla command line di sistemi GNU/Linux, laconicamente, non scrive niente. Per controllare l’esito dell’interrogazione occorre verificare il valore ritornato dal comando tramite l’analisi della variabile $?. Se il valore di questa variabile è 0 vuol dire che il server è attivo (qualcuno è in ascolto sulla porta 873), altrimenti il server non risponde (nessuno è in ascolto sulla porta 873.

L’analisi della valore di ritorno del comando nc può essere fatto tramite il comando echo:

user@host:~$ echo $?
0
user@host:~$ _

o tramite, per esempio, tramite il seguente snippet di codice bash:

nc -z -n -w 1 <ip_server> 873
if [ $? -eq 0 ]; then
echo "rsync server is running!"
else
echo "rsync server not running"
fi

Screencasting su linux

Lo Screencasting è la procedura utilizzata su un PC, o altro dispositivo, per registrare video e audio dal desktop. Attraverso l’uso di opportuni software è possibile ottenere uno screencast, un video, corredato di traccia audio che descrive, di solito meglio di 1.000 parole, una procedura da seguire su PC. Di esempi di screencast è pieno il mondo, a titolo di esempio qui sotto se ne può vedere uno tratto dal sito Pragmatic Programming (che tralaltro screencast li produce e li vende).

Realizzare screencast è facile. Esistono vari software per farlo, alcuni gratuiti, altri a pagamento. Qui descriverò un metodo per macchine linux. Il programma da utilizzare è recordmydesktop.

Per installarlo su macchine Debian/Ubuntu è possibile utilizzare il seguente comando, (anche se l’equivalente esiste sicuramente per le altre distribuzioni):

sudo apt-get install recordmydesktop

Una volta ottenuto il software, per registrare l’intero desktop basta lanciare il comando:

recordmydesktop

una volta terminata la registrazione interrompere il programma con Ctrl-C e lasciare terminare l’encoding del file multimediale. Il file generato dal programma è in formato OGV. Non entro nel merito dei formati multimediali perché l’argomento è vasto e complesso e attualmente fuori dalla mia portata. L’unica cosa che vale la pena menzionare è che il formato OGV non è ben supportato da macchine non linux e anche YouTube per esempio sembra non gestirlo (a dire il vero oggi non ho provato).

Il file ottenuto va quindi convertito in un formato video più “tradizionale” (qualunque cosa questo significhi) e per farlo si possono utilizzare vari programmi. Qui menziono quelli che ho provato io:

  • mencoder: per esempio con il seguente comando:

mencoder -idx <file_input.ogv> -ocv lavc -oac mp3lame -o <file_output.avi>

si ottiene un file AVI. Nella prova fatta stanotte, nel file risultante dalla conversione, ho però ottenuto un disallineamento tra la traccia audio e quella video che di fatto rendeva il prodotto inutilizzabile.

  • avconv: questo programma è l’evoluzione del famoso ffmpeg (quest’ultimo ad oggi dichiarato obsoleto) e a tutti gli effetti lo sostituisce. Trattasi di un programma molto complesso e potente con molte opzioni che permettono di determinare il formato e la qualità della traccia audio e video risultante sul file di output. Con il seguente comando sono riuscito a convertire un OGV in modo corretto e a farlo riprodurre senza problemi da YouTube:

avconv -i <file_input.ogv> -f avi -c:v mpeg4 -b:v 800k -g 300 -bf 2 -c:a mp2 <file_output.avi>

Al momento non sono molto soddisfatto della qualità del video, e non sono riuscito a codificare la traccia audio in MP3, ma almeno il file risultate ha una dimensione gestibile e funziona.

Per oggi solo un’ultima nota. Spesso per uno screencast risulta utile registrare il contenuto di un’unica finestra. Per fare questo con recordmydesktop basta utilizzare l’opzione --windowid. Per esempio:

recordmydesktop --windowid 0x2a00006

Per scoprire il window id della finestra da registrare, lanciare per esempio il comando:

xwininfo | awk '/xwininfo: Window id/{print $4}'

e  cliccare con il mouse sulla finestra di interesse.

Per oggi è tutto.