§ 33. Come pubblicare gli archivi audio online

Indice dei sottoparagrafi
1. Il problema da risolvere
2. Con quali file lavoriamo
3. Quali tecnologie utilizziamo
4. Prepariamo i file per la pubblicazione
5. Mostriamo l’elenco dei file caricati nella directory
6. Creiamo i link al player audio e ai testi
7. Creiamo la pagina con il player e i testi
8. Cosa possiamo aggiungere
9. Un esempio funzionante del metodo descritto

A marzo del 2022 al sottoscritto è capitato di pubblicare, sulla versione russa di questo sito, una parte degli archivi audio di una emittente radiofonica russa chiusa proprio in quel periodo storico per dei motivi politici (era fortemente sgradita al regime politico vigente). Dal punto di vista tecnico, la pubblicazione sopraindicata è stata una esperienza professionale nuova e, di conseguenza, ha spinto l’autore a stilare un articolo utile al fine di non dimenticare (o riepilogare mentalmente) le nuove nozioni acquisite nel corso del lavoro. Il testo potrebbe rivelarsi utile anche ai lettori italiani. A chi, eventualmente, legge bene in russo conviene vedere l’articolo originale, tutti gli altri rimangano su questa pagina.
Procediamo con l’ordine.

1. Il problema da risolvere
Immaginiamo di voler/dover pubblicare su un sito web un archivio di file audio: una alta quantità di file che per qualche motivo non è destinata a crescere nel tempo (o, almeno, non crescere con una buona costanza e/o frequenza). Pubblicando tale archivio dobbiamo dunque realizzare i seguenti punti elencati nell’ordine di priorità:
– indicare, per ogni file audio, il suo argomento e/o titolo, la data della prima pubblicazione ufficiale, i nomi degli autori e la durata;
– fornire ai visitatori del sito la possibilità non solo di scaricare i file, ma anche di ascoltarli direttamente dal sito;
– aggiungere la possibilità di leggere con gli occhi il testo relativo al file audio (che può essere la trascrizione di una trasmissione radiofonica, il testo di una canzone etc. etc.);
– pubblicare i materiali aggiuntivi in qualche modo connessi ai file audio pubblicati.

2. Con quali file lavoriamo
Supponiamo di avere una serie di file *.mp3 con l’audio e di file *.txt con i relativi testi (in particolare, quest’ultimo formato mi sembra il più facilmente integrabile nelle pagine web; nel corso dell’articolo spiegherò perché i testi non vengono inclusi direttamente nel codice delle pagine o inseriti attraverso un CMS). Ogni coppia dei file ha i nomi uguali (per esempio, brano001.mp3 e brano001.txt con la numerazione che va dal file più datato al file più recente): tra poco capirete il perché.
Tutti i file vengono banalmente caricati sul server, nella directory appositamente creata: per esempio, nella directory archivio/audio (il cui indirizzo assoluto sarà https://sito.it/archivio/audio).

3. Quali tecnologie utilizziamo
Di tutte le conoscenze tecniche disponibili nella testa del sottoscritto sono stati scelti i linguaggi PHP, HTML, CSS e XML. Tutti gli altri linguaggi di programmazione e di markup che possono apparirvi utili, non sono stati presi in considerazione per una serie di motivi tecnicamente giustificati (a volte anche a causa della scarsa conoscenza, ahahaha).

4. Prepariamo i file per la pubblicazione
L’utilizzo di un database per la gestione degli archivi che per qualche motivo non saranno più aggiornati (oppure aggiornati molto raramente) è uno spreco criminale di risorse. È assolutamente sufficiente creare per il nostro [ognuno dei nostri] archivio un file xml statico con i metadati di ogni file audio.
Di conseguenza, nel nostro file brani.xml per ogni file audio scriviamo una struttura di questo tipo:

<puntata ntid="brano001">
     <trasmissione>Le avventure degli archivi</trasmissione>
     <conduttori>Tizio Rossi e Caio Verdi</conduttori>
     <data>12 aprile 2014</data>
     <durata>45:50</durata>
     <topic>Alla ricerca degli archivi segreti di Sempronio Bianchi...</topic>
</puntata>

Come potete vedere, il file xml contiene tutte le informazioni che abbiamo pianificato di visualizzare sulla pagina web dell’archivio (si riveda il primo sottoparagrafo).
Notate che l’identificatore delle informazioni relative ai singoli file audio (brid) ha lo stesso nome dei rispettivi file *.mp3 e *.txt e varia nella parte numerica assieme a essi. Il fatto è che intendo utilizzare l’identificatore non solo per «ripescare» le informazioni necessarie dalla tabella, ma anche per generare automaticamente i link dei file audio e di testo.

5. Mostriamo l’elenco dei file caricati nella directory
In realtà, una delle mie idee folli iniziali era quella di ottenere l’elenco dei file caricati nella directory con la funzione PHP scandir(), estraendo in contemporanea i metadati direttamente dai tag ID3 dei file mp3. Il codice che mi era venuto funzionava visualizzando il risultato atteso, era molto semplice, breve e quasi universale: esattamente come quei codici che ritengo ideali. La pagina web con il risultato visualizzato, però, ci impiegava una infinità a caricarsi… In presenza di particolarmente tanti mp3 da analizzare provocava, addirittura, il blocco del computer. Di conseguenza, avevo compreso tutta la profondità della mia stupidità ed ero tornato alla idea di progettare un file xml.
Come avete già avuto modo di vedere sopra, nel file xml non sono indicati non solo i nomi dei file, ma nemmeno i percorsi assoluti che portino verso di essi. Questa scelta è stata adottata per raggiungere due obiettivi. In primo luogo, volevo fare un file xml più leggero possibile. In secondo luogo, nessuno può essere sicuro al 100% di riuscire a mantenere gli stessi URL per tutta la vita. Di conseguenza, al fine di evitare di dover, in un giorno futuro, riscrivere manualmente gli indirizzi (oppure dimenticare di farlo nel momento critico), ho deciso di costruire quegli indirizzi in una modalità più automatizzata possibile. Per iniziare, ho dovuto scrivere questo:

$protokol = (!empty($_SERVER['HTTPS']) && 'off' !== strtolower($_SERVER['HTTPS'])?"https://":"http://");
$domen = $_SERVER[SERVER_NAME];
$koren = $protokol.$domen;
$dir = 'archivio/audio'; // la directory dei file mp3
$images = $koren.'/images/archivimp3'; // il percorso delle immagini utilizzate
$url = ((!empty($_SERVER['HTTPS'])) ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; // determiniamo url della pagina corrente

Avrei preferito un codice più breve, ma non l’ho ancora inventato.
Solo a questo punto si può leggere il file xml (la cui struttura è già stata mostrata sopra), scoprire l’identificatore di ogni file audio e visualizzare sulla pagina dell’archivio, per ogni file audio dell’archivio, un rettangolo-contenitore con tutte le informazioni utili. Notate che nel link del file mp3 ci metto – proprio come avevo pianificato – il nome dell’identificatore preso dal file xml (si vedano le righe 4, 7 e 17 del codice):

$xml = simplexml_load_file("$dir/brani.xml");
$i = 0; // questo valore serve per la lettura corretta del file xml
foreach ($xml as $puntata) {
$path = $xml->puntata[$i]['brid'];
$i++; // contiamo le puntate presenti nell'archivio
echo "<div class=singlevypusk><div class=singlevypuskimg>"; // il div della puntata e il div della immagine
echo "<a href='$koren/$dir/$path.mp3'>"; // creaiamo il link del file mp3 (per il download)
echo "<img src='$images/radio.jpg' title='Scaricare il file mp3' />"; // quella immagine grande che troviamo in ogni rettangolo-contenitore
echo "</a></div>"; // chiudiamo il link del file mp3
echo "<div class=singlevypusktxt>";
echo '<b>L&rsquo;argomento:</b> '.$puntata->topic.'<br />'; // l'argomento della puntata
echo '<b>I conduttori:</b> '.$puntata->conduttori.'<br />'; // i nome dei conduttori
echo '<b>La data della trasmissione:</b> '.$puntata->data.'<br />'; // la data della trasmissione in onda
echo '<b>La durata:</b> '.$puntata->durata.'<br />'; // la durata della puntata
echo '</div>';
echo '<div class=singlevypuskpic>';
echo "<a href='$koren/$dir/$path.mp3'><img src='$images/downloadaudio.png' title='Scaricare il file mp3' /></a><br />"; // creaiamo il link del file mp3 (per il download)
echo "<a href='".$url."sluhaivsjotak?search=$path'><img src='$images/listenaudio.png' title='Ascoltare sul sito' /></a><br />"; // creaiamo il link del player audio
echo "<a href='".$url."sluhaivsjotak?search=$path'><img src='$images/readtext.jpg' title='Leggere la trascrizione' /></a>"; // creaiamo il link della trascrizione
echo "</div></div>"; // chiudiamo il rettangolo-contenitore
}

Il risultato che il visitatore vedrà sullo schermo è una serie di questi blocchi (rettangoli-contenitori) generati automaticamente dal codice:

La variabile i che avete visto nel codice serve solo per contare i file mp3 e visualizzare la loro quantità totale:

6. Creiamo i link al player audio e ai testi
Nella parte destra di ogni rettangolo (si veda l’immagine sopra) sono presenti tre pittogrammi, il cui significato è secondo me chiaro a tutti (o no?). Renderli funzionanti è facilissimo.
Come avete già visto nel listing N3, il link per il download di ogni singolo brano viene generato sempre con le stesse variabili (compresa la variabile path che contiene l’identificatore preso dal file xml):

echo "<a href='$koren/$dir/$path.mp3'><img src='$images/downloadaudio.png' title='Scaricare il file mp3' /></a><br />"; // creaiamo il link del file mp3 (per il download)

Ci resta creare i link che portino al player audio e al testo della trascrizione. Penso che per tutti gli utenti dell’archivio sia più comodo trovare quei materiali – il player e il relativo testo – su una pagina unica: proprio (e solo) per questo motivo i due link sono identici (anche essi vengono generati con l’aiuto delle variabili che conoscete già):

echo "<a href='".$url."sluhaivsjotak?search=$path'><img src='$images/listenaudio.png' title='Ascoltare sul sito' /></a><br />"; // creaiamo il link del player audio
echo "<a href='".$url."sluhaivsjotak?search=$path'><img src='$images/readtext.jpg' title='Leggere la trascrizione' /></a>"; // creaiamo il link della trascrizione

Come potete immaginare, una persona media non ha abbastanza tempo e voglia per creare manualmente decine o centinaia di pagine, una per ogni singola coppia audio-testo. È molto più facile e comodo crearne una sola: si troverà all’indirizzo https://sito.it/archivio/audio/ascoltaaudio e in base alla richiesta GET (quella che inizia dai punti interrogativi nei link del listing appena visto) avrà i contenuti che corrispondono, in sostanza, alla variabile che ha lo stesso nome dell’identificatore. Non so se vi sia chiaro il concetto. Se non lo capite subito, provate a rileggere…
E poi andiamo avanti.
Come ho già scritto più in alto, il nome dell’identificatore di ogni porzione delle informazioni nella tabella xml è uguale al nome del rispettivo file mp3. L’ultimo elemento del link generato con l’aiuto della variabile path «si chiama» come l’identificatore. Di conseguenza, sulla pagina del player e del testo dovremo solamente aprire di nuovo il file xml e trovare le informazioni con l’identificatore che «fa parte» del link.
Ma prima di procedere vediamo bene il traguardo raggiunto. Il codice completo della pagina sulla quale vengono visualizzati la lista dei file audio e i rispettivi link al player e al testo è dunque questo:

$protokol = (!empty($_SERVER['HTTPS']) && 'off' !== strtolower($_SERVER['HTTPS'])?"https://":"http://");
$domen = $_SERVER[SERVER_NAME];
$koren = $protokol.$domen;
$dir = 'archivio/audio'; // la directory dei file mp3
$images = $koren.'/images/archivimp3'; // il percorso delle immagini utilizzate
$xml = simplexml_load_file("$dir/brani.xml");
$i = 0; // questo valore serve per la lettura corretta del file xml
foreach ($xml as $puntata) {
$path = $xml->puntata[$i]['brid'];
$i++; // contiamo le puntate presenti nell'archivio
echo "<div class=singlevypusk><div class=singlevypuskimg>"; // il div della puntata e il div della immagine
echo "<a href='$koren/$dir/$path.mp3'>"; // creaiamo il link del file mp3 (per il download)
echo "<img src='$images/radio.jpg' title='Scaricare il file mp3' />"; // quella immagine grande che troviamo in ogni rettangolo-contenitore
echo "</a></div>"; // chiudiamo il link del file mp3
echo "<div class=singlevypusktxt>";
echo '<b>L&rsquo;argomento:</b> '.$puntata->topic.'<br />'; // l'argomento della puntata
echo '<b>I conduttori:</b> '.$puntata->conduttori.'<br />'; // i nome dei conduttori
echo '<b>La data della trasmissione:</b> '.$puntata->data.'<br />'; // la data della trasmissione in onda
echo '<b>La durata:</b> '.$puntata->durata.'<br />'; // la durata della puntata
echo '</div>';
echo '<div class=singlevypuskpic>';
echo "<a href='$koren/$dir/$path.mp3'><img src='$images/downloadaudio.png' title='Scaricare il file mp3' /></a><br />"; // creaiamo il link del file mp3 (per il download)
echo "<a href='".$url."sluhaivsjotak?search=$path'><img src='$images/listenaudio.png' title='Ascoltare sul sito' /></a><br />"; // creaiamo il link del player audio
echo "<a href='".$url."sluhaivsjotak?search=$path'><img src='$images/readtext.jpg' title='Leggere la trascrizione' /></a>"; // creaiamo il link della trascrizione
echo "</div></div>"; // chiudiamo il rettangolo-contenitore
}
echo "<div style=\"clear: both\">La quantit&agrave; dei file audio nell&rsquo;archivio: $i</div>";

Ora che abbiamo finito con la visualizzazione dell’elenco, passiamo alla creazione della seconda pagina: quella dedicata al singolo file audio e al relativo testo.

7. Creiamo la pagina con il player e i testi
La prima parte del codice di questa seconda pagina dovrebbe esservi già chiara: automatizziamo la costruzione dell’indirizzo del file, leggiamo la richiesta GET e inseriamo il codice HTML del player con l’indirizzo del file mp3 corrispondente alla richiesta.

$protokol = (!empty($_SERVER['HTTPS']) && 'off' !== strtolower($_SERVER['HTTPS'])?"https://":"http://");
$domen = $_SERVER[SERVER_NAME];
$koren = $protokol.$domen;
$dir = 'archivio/audio'; // la directory dei file mp3
$fileinfo = $_GET['search'];
$fileinfo = htmlspecialchars($fileinfo);
echo "<center><audio controls preload='auto' src='$koren/$dir/$fileinfo.mp3' type='audio/mp3'></audio></center><br />";

Carichiamo il file xml:

$xml = simplexml_load_file("$dir/brani.xml");

Dopo di che dobbiamo vedere gli elementi del file a partire dal primo (il quale, in realtà, è numerato nella logica del xml come 0) alla ricerca di quello avente l’identificatore che corrisponde al link / URL del file audio. È per questo che ho dovuto scrivere il seguente codice, senza dimenticare di precisare che l’analisi degli elementi xml deve necessariamente partire dal primo (i=0).

$i = 0;
foreach ($xml as $puntata) {
$brid = $xml->puntata[$i]['brid'];
$i++;
if ($brid == $fileinfo)
{
echo '<div class=sluhainfo><h3>'.$puntata->topic.'</h3><br />La data della trasmissione: '.$puntata->data.'.<br />I conduttori: '.$puntata->conduttori.'.</div>';
$tracklist = $dir.'/'.$fileinfo.'.txt'; // il file con la trascrizione
if (file_exists($tracklist)) {echo '<div class=sluhaitxt>'.file_get_contents($tracklist).'</div>';} // mostriamo il contenuto del file txt
else {echo 'La trascrizione non &egrave; ancora pronta.<br /><br />';}
echo "<div class=sluhainfo><a href='$koren/$dir/$fileinfo.mp3' >Potete inoltre scaricare il file mp3.</a>.</div>";
}
}

Ora, se qualcuno volesse vedere la soluzione nel suo complesso, riporto il codice completo della pagina con il player e il testo del file scelto dal visitatore del nostro archivio.

$protokol = (!empty($_SERVER['HTTPS']) && 'off' !== strtolower($_SERVER['HTTPS'])?"https://":"http://");
$domen = $_SERVER[SERVER_NAME];
$koren = $protokol.$domen;
$dir = 'archivio/audio'; // la directory dei file mp3
$fileinfo = $_GET['search'];
$fileinfo = htmlspecialchars($fileinfo);
echo "<center><audio controls preload='auto' src='$koren/$dir/$fileinfo.mp3' type='audio/mp3'></audio></center><br />";
$xml = simplexml_load_file("$dir/brani.xml");
$i = 0;
foreach ($xml as $puntata) {
$brid = $xml->puntata[$i]['brid'];
$i++;
if ($brid == $fileinfo)
{
echo '<div class=sluhainfo><h3>'.$puntata->topic.'</h3><br />La data della trasmissione: '.$puntata->data.'.<br />I conduttori: '.$puntata->conduttori.'.</div>';
$tracklist = $dir.'/'.$fileinfo.'.txt'; // il file con la trascrizione
if (file_exists($tracklist)) {echo '<div class=sluhaitxt>'.file_get_contents($tracklist).'</div>';} // mostriamo il contenuto del file txt
else {echo 'La trascrizione non &egrave; ancora pronta.<br /><br />';}
echo "<div class=sluhainfo><a href='$koren/$dir/$fileinfo.mp3' >Potete inoltre scaricare il file mp3.</a>.</div>";
}
}

Grazie alla organizzazione dell’archivio appena descritta, l’ipotetica aggiunta dei nuovi file audio (qualora dovessero essere creati o trovati), ci richiederà solo due azioni manuali: caricare i nuovi file (mp3 e txt) nella nostra directory e aggiungere le relative informazioni nel file xml.
Infine, il file CSS necessario per la pubblicazione del nostro archivio audio non ha alcunché di particolare: il perfezionamento dell’aspetto grafico di tutti gli elementi visivi creati nel corso di questo lavoro è un compito puramente manualistico. Di conseguenza, non tento di caricare l’articolo di informazioni che avete già in testa.

8. Cosa possiamo aggiungere
Volendo possiamo aggiungere alcune funzionalità potenzialmente apprezzabili al nostro archivio pubblicato. Per esempio, potremmo aggiungere il rss-feed per i file audio (creando un altro file xml particolare e alcuni script in linguaggio Go). Oppure, potremmo aggiungere la possibilità di scaricare i testi direttamente in pdf (una cosa realizzabile anche in PHP). Ma questi sono degli argomenti troppo grandi per essere aggiunti al presente articolo.
Ora mi limito a dire che ogni archivio deve essere comodo da consultare. Questo significa, per esempio, che un archivio fatto bene deve avere anche uno strumento di ricerca interna. Quest’ultima è facile da aggiungere all’esempio trattato nel presente articolo.
Supponiamo di voler permettere di effettuare la ricerca tra i titoli dei file audio dell’archivio. Il meccanismo di ricerca più semplice che potremmo inventare funzionerà in due situazioni: se il visitatore ha inserito il titolo esatto (ma non è detto che se lo ricordi) oppure se ha inserito qualche parola facente parte del titolo (in pratica, una o più parola/e chiave). Quindi controlliamo che il campo di ricerca non sia vuoto e poi andiamo a confrontare il suo contenuto con i campi dei titoli nel file xml. E poi visualizziamo la lista di tutti i risultati linkati attraverso un ciclo foreach:

if (!isset($_POST['searcharg'])) echo "";
elseif ($_POST['searcharg']) $searcharg = $_POST['searcharg']; // creiamo la variabile per il testo della ricerca
?>
<div style="width: 100%; clear: both">
<form method="post"><input type="search" class="searchinputecho" name="searcharg" id="searcharg" value="<?=$searcharg?>" placeholder="cosa cerchi?" required> <input type="submit" value="  Cerca  " class="searchbuttecho">
<?php
if(!isset($_POST['searcharg'])) echo "";
elseif ($_POST['searcharg'])
{
$data = 'https://sito.it/archivio/audio/brani.xml';
$xml = new SimpleXMLElement(file_get_contents($data));
$result = $xml->xpath('puntata/topic');
echo '<br>I risultati della ricerca:<br>';
$p = 0;
$x = 0;
foreach ($result as $node)
{
     if (mb_stripos($node, $searcharg) === false ) echo ""; else { $brid = $xml->puntata[$x]['brid']; echo '<br>&ndash;&nbsp;<a href=https://sito.it/archivio/audio/ascoltaaudio?search='.$brid.'>'.$node.'</a><br>'; $p++; }
     $x++;
}
if ($p == 0) { echo "<br>la Sua ricerca non ha prodotto risultati...<br>"; }
echo "<br><i>Qualora tra i risultati della ricerca dovesse mancare una puntata che secondo voi è sicuramente esistita, provate a cercare una (o più) parola chiave potenzialmente presente nel suo titolo, oppure consultate la lista completa riportata di seguito.</i><br>";
}
?>
</form></div>

È un meccanismo talmente semplice che non so nemmeno in quale sua parte debba essere spiegato.

9. Un esempio funzionante del metodo descritto
A questo punto non mi resta altro che completare il presente paragrafo di Inerario con un esempio funzionante di quanto descritto. In qualità di tale esempio vi propongo l’archivio delle trasmissioni radiofoniche di Pyotr Mamonov dedicate alla sua musica preferita.
Bene, ora siete un po’ più preparati alla pubblicazione degli archivi audio online. Alle persone che volessero utilizzare lo stesso metodo per la pubblicazione di un archivio dei file video è sufficiente fare appena due cambiamenti: sostituire l’estensione .mp3 con quella dei video e, nel codice della seconda pagina, il player audio con il player video.
Spero che la mia soluzione sia comprensibile a tutti e utile almeno ad alcuni!