Archivi tag: Read Aloud ePubs

ePub 3.0 – Prove su strada

20120707-detour-christine-weddle-colorado-spring-7-dic-2008

Detour – Christine Weddle – Colorado Spring – 7 Dic 2008

Come accennavo nel post precedente, per testare la compatibilità di ePUB 3.0 verso l’esterno, la scelta migliore era quella di effettuare delle prove concrete. Sono partito da un Fixed Layout ePub, creato da me secondo le specifiche Apple. Il noto ePub ‘Illustrazioni di SteG’ (chi mi segue lo conosce da tempo), aveva bisogno di una drastica rinfrescata. Sia perché, come segnalato agli iscritti al mio blog, il codice peccava di molte leggerezze di gioventù, ma sopratutto perché volevo assolutamente che la nuova versione rispondesse ai requisiti chiesti dallo standard. Ma lo standard tardava a diventare tale, e soprattutto mancavano strumenti di verifica. Oggi che finalmente IDPF ha compiuto passi fondamentali sulle specifiche ed è a disposizione di tutti lo strumento di verifica Readium, condivido la nuova versione e descrivo in questo post, le principali opzioni di conversione operate. L’obiettivo era chiaramente quello di convertire tutte le specifiche proprietarie Apple nelle specifiche dettate dallo standard. Dopo la conversione il file si sarebbe dovuto poter leggere senza problemi con Readium (su browser Chrome) perché solo in caso positivo lo standard sarebbe stato confermato. Se oltre a questo il nuovo ePub si fosse potuto leggere di nuovo anche su iPad, il successo sarebbe stato pieno (ma su quest’ultimo punto a dire la verità ero piuttosto scettico :-)). Procediamo per gradi. Le specifiche introdotte da IDPF richiedono la dichiarazione di alcuni parametri fondamentali necessari a caratterizzare l’epub. In particolare, bisogna fare capire al sistema alcune proprietà del libro:

  1. se si tratta di layout scorrevole o layout fisso (layout);
  2. quale orientamento si preferisce (orientation);
  3. se e quando vogliamo la visualizzazione a pagine affiancate (spread).
queste tre specifiche sono raccolte nella proprietà rendition (resa, rappresentazione) e possono assumere i seguenti valori:
  1. reflowable (testo scorrevole) oppure pre-paginated (layout fisso);
  2. landscape (orizzontale), portrait (verticale), both (entrambi);
  3. none (mai), auto (scelta automatica), landscape (solo quando orizzontale), portrait (solo quando verticale), both (sempre).

Ovviamente il richiamo alla proprietà rendition deve essere giustificato da un apposito riferimento a IDPF posto all’inizio:

...

Riassumendo e per fare un esempio: i dati necessari per esprimere un  Fixed Layout da fruire indipendentemente dall’orientamento dell’eReader, ma con visualizzazione a pagine affiancate solo in caso di orientamento orizzontale, sono i seguenti:

...pre-paginatedbothlandscape
...

Restando sempre nel file content.opf, IDPF richiede la dichiarazione del ‘momento’ dell’ultima revisione del documento. Non corrisponde alla data di pubblicazione e deve essere espressa secondo la notazione UTC (Coordinated Universal Time) CCYY-MM-DDThh:mm:ssZ. Questo dato apparentemente superfluo è importante perché etichetta esattamente la versione su cui avviene la lavorazione, e soprattutto tende ad eliminare i noti problemi di cache per i quali dopo l’aggiornamento ad una nuova revisione del libro, l’eReader si ricordava ancora di quella precedente.  Questa l’espressione corretta del parametro:

...2012-07-07T08:58:00Z
...

Ultimo parametro da dichiarare nel file content è la versione: ovviamente 3.0. Le modifiche che riguardano le pagine xhtml sono solo di ‘facciata’ perché la sostanza resta invariata: EPub 3.0 non ha più bisogno del DOCTYPE e ha ridotto all’osso la dichiarazione di codifica dell’utilizzo dei caratteri:


Ultimissima modifica: la generazione di un nuovo file indice, inesistente nella 2.0: il file nav.xhtml. Deve coesistere assieme al precedente toc.ncx che non può essere eliminato per  consentire una certa retro-compatibilità con lettori più datati. Il file nav. xhtml non è altro che una lista che funge da indice. Vi invito a scaricare e aprire l’ePub per verificarne struttura e contenuti. Questo è tutto! Non grandi cose come avete visto. Superata senza nessun errore la fase di convalida con ePubCheck (verificate costantemente di utilizzare la versione più aggiornata) ho testato la lettura con Readium su Chrome. Avevo introdotto in questa nuova versione del libro, alcune specifiche che ritenevo utili e significative per verificare a fondo la compatibilità: Una pagina in Media Overlay (pagina 12) con l’inserimento di un file smil per la lettura sincronizzata e una pagina (pagina 21) contenente una semplice animazione Javascript. Il Media Overlay che avevo descritto in questo post, funziona benissimo in Readium. Unica sbavatura (su cui i programmatori stanno lavorando) è la marcatura visuale e sincronizzata della parola nel momento stesso in cui questa viene letta. La funzione nonostante sia correttamente impostata non è interpretata e la parola non viene evidenziata. Per il resto nessun altro problema. Importante impostare nelle preferenze la visualizzazione a pagine affiancate come da immagine. 20120714-readium La voce narrante a pagina 12 è la voce autentica di SteG che si è prestata con entusiasmo come sempre. Nonostante la registrazione audio non ottimale, l’esempio è più che sufficiente perché vi rendiate conto della funzionalità. Lanciate Chrome. Caricate e aprite l’epub  a pagina 12. Cliccando sul pulsante indicato in figura, partirà la lettura del testo. 20120707-read-aloud-in-readium La pagina 21 contiene invece una semplice animazione in Javascript. Funziona senza problemi (anche se in Readium soffre leggermente perché sorretta da un browser), ma la cosa importante non è tanto il codice Javascript, quanto le dichiarazioni che rispetto al codice devono essere fatte soprattutto nel file content. Vi invito ad aprire ed ispezionare l’epub a tal riguardo. Questa è la pagina: cliccando sulla miniatura della copertina si avvia l’animazione: 20120707-readium-10

Come ultimo passaggio metto in evidenza l’esito dell’introduzione del nuovo file nav.xhtml. Questa la sua rappresentazione in Readium: 20120707-readium-new-toc

e questa invece quella (un po’ più elegante) su iPad: 20120707-new-toc-in-ipad

Suggerisco di aprire l’epub e verificare tutte le specifiche tipiche del Fixed Layout ePub secondo IDPF. Controprova a ritroso: l’ePub costruito non più secondo le specifiche Apple, ma secondo lo standard dettato da IDPF funzionerà ancora su iPad? Ebbene si! Funziona esattamente come prima, compresa la marcatura visuale e sincronizzata del testo durante la lettura che invece a Readium non riesce ancora. Unico riferimento ‘proprietario’ che rimane all’interno dell’epub è il file xml com.apple.ibooks.display-options ancora presente all’interno della cartella META-INF. Ne ha ancora bisogno il  device Apple per sapere che si sta parlando di un Fixed Layout. È presumibile che questo file sparirà a breve, ma questa volta ad essere fuori standard è Apple :-). ___ Considero obsoleta la precedente versione del libro ‘illustrazioni di SteG (eliminata dal server). A brevissimo renderò È disponibile la nuova release descritta in questo post. Sarà inviata automaticamente a tutti gli iscritti (che avevano confermato l’iscrizione)  e a tutti coloro che ne faranno espressa richiesta. Che aspetti? Che ne pensi di questo importante passaggio di IDPF? Hai esperienza di portabilità verso altri eReaders?


Read Aloud ePubs: la funzionalità di lettura ad alta voce

Una delle opportunità più interessanti offerte da Apple a chi crea ePubs da leggere tramite i sui devices è la possibilità della lettura del libro ad alta voce.
Questa funzione, utilizzabile solo negli ePubs a layout fisso (rimando al post relativo per rinfrescare l’argomento), nulla ha a che vedere con la sintetizzazione della voce. Utilizza invece un opportuno file xml che associa una parte del testo ad una traccia audio registrata precedentemente.
Scopo di queste pagine è spiegare come ‘isolare’ ogni parola scritta individuandola all’interno del testo della pagina; spiegare come ‘isolare’ il suo corrispondente brano audio individuandolo all’interno della traccia audio completa e infine come effettuarne il match per darne al lettore rappresentazione ‘visiva e sonora’.

Scegliamo una pagina qualsiasi e digitiamo il testo.

Dobbiamo isolare tutte le parole che compongono il brano perché ad ogni parola dovremo attaccare una opportuna parte di codice html.
Suggerisco di immaginare il testo distribuito una parola per riga. Se noi riusciamo a numerare in progressione tutte le righe, dato che ad ogni riga corrisponde una sola parola, potremo utilizzare il numero di riga come elemento identificativo (id) di quella parola.
Vedremo nella seconda parte come agganciare questo id univoco al suo brano audio di riferimento.
Un editor di testo e qualche conoscenza di GREP (spunti e link a partire da questo indirizzo) risultano di grande aiuto per affrontare e velocizzare questa fase abbastanza noiosa.
Come editor di testo utilizzo e consiglio caldamente, Text Wrangler (gratuito) oppure suo fratello maggiore (a pagamento) BBEdit raggiungibili entrambi dal sito del produttore BareBones
Prendo come esempio la bellissima pagina Alchemy del libro Illustrazioni di SteG che già conosciamo:

20111031 - 20111024-alchemy-cut

Concentriamoci sul corpo principale del testo (sorvolando su quell’antiestetico ‘si’ che mi è rimasto li implacabile, alla fine della prima linea 🙂 ):

Vogliamo una parola sola per ogni riga, quindi dobbiamo inserire un ritorno a capo al posto di ogni spazio. Il problema è che esistono già dei ritorni a capo. Dobbiamo mantenerli riconoscibili perché in seguito ci serviranno.

Partiamo quindi da questi ultimi e li modifichiamo in modo da mantenerli riconoscibili:

Cerchiamo \r (fine linea) e sostituiamo con STOP \r

Utilizzo di GREP 01

a questo punto possiamo procedere con gli spazi. Cerchiamo ‘spazio’ e sostituiamolo con ritorno a capo. Questo il risultato:

Read Aloud Support 02

Finalmente possiamo dare un ID ad ogni parola sfruttando la numerazione delle righe (Text -> Add/Remove Line Numbers). I parametri corretti sono chiaramente indicati in figura:

Passiamo al codice xml. Quello che ci serve è:

  • la creazione di un elemento span riga per riga che contenga la nostra parola;
  • la parola dovrà essere identificata da un id univoco dato dal numero di linea preceduto da W;
  • nel caso si trovi la parola STOP questa dovrà essere lasciata fuori dall’elemento span.

In sintesi ogni parola si porterà dietro una espressione di questo tipo:

<span id=”W1”> la </span>

Vediamo come con l’uso opportuno di GREP possiamo semplificare questi passaggi:

Ogni linea del testo che compone la nostra pagina è formata da 3 elementi: (1) Numero, (2) parola e (3) ritorno a capo (eventualmente STOP e ritorno a capo). Questi tre elementi possono essere espressi con Grep in questo modo:

(\d+) Numero

(.+?) Parola

(STOP)*\r Ritorno a capo (eventualmente con la parola STOP se presente)

Il nostro pattern di ricerca sarà quindi questo:

(\d+) (.+?)(STOP)*\r

e andrà sostituito opportunamente in modo da restituire la stringa vista prima:

“<span id=” Inizio della riga dell’elemento span

“W\1”> considera il primo elemento del pattern di ricerca facendolo precedere dalla lettera W

\2 considera il secondo elemento restituito dal pattern di ricerca

</span> chiusura dell’elemento span

\3 aggiunge FUORI dall’elemento span e solo se presente la stringa STOP.

in sintesi:

<span id=”W\1”>\2</span> \3 (attenzione allo spazio prima del terzo elemento.

Applicando come pattern di ricerca e sostituzione le due stringhe appena viste, si ottiene una lunga stringa di testo di una sola linea:

Nota: cliccando dove indicato dalla freccia rossa, è possibile salvare il pattern di ricerca-sostituzione per elaborazioni future. Adesso in modo molto semplice ripristiniamo i ritorni a capo. Cerchiamo le stringhe “ STOP” (attenzione allo spazio prima della parola) e le sostituiamo con \r

Numeriamo nuovamente le righe utilizzando gli stessi parametri visti precedentemente e otteniamo:

Ultimo passaggio: convertiamo i numeri di riga in classi in modo da poter individuare le righe stesse e poterle formattare tramite il CSS:

Cerchiamo

(\d+) (.*)

e sostituiamo con:

 <p class=”line\1″>\2</p>

Abbiamo finalmente ottenuto quello che ci serviva: righe di codice in cui ogni parola è definita da un id univoco. Useremo questo id come aggancio per i brani audio. Copiamo e incolliamo il codice ottenuto all’interno del file xhtml e procediamo con la formattazione ‘grafica’ della pagina. L’argomento è già stato trattato, quindi non ci soffermiamo. Passiamo invece alla sonorizzazione del testo. L’idea pensata dagli sviluppatori su come utilizzare la traccia audio è semplice e geniale allo stesso tempo. Immaginiamo la traccia audio della pagina come una linea del tempo. Su questa linea sono registrate in sequenza tutte le parole che compongono il testo. Se troviamo il modo di etichettare ogni parola individuando il momento del suo inizio e e quello della fine, il brano audio sarà completamente mappato e a nostra disposizione. Ad ogni etichetta così determinata (parola pronunciata) sarà possibile agganciare gli ID (parola scritta) definiti precedentemente.

Semplice no? 🙂

Vediamo come procedere.

Un buon microfono e un buon editor audio sono cruciali in questa fase. Rispetto al software, Apple stessa suggerisce nelle sue linee guida, l’utilizzo di Audacity  gratuito, ottimo e semplicissimo open source.

Rispetto al microfono suggerisco una versione USB per la praticità nell’utilizzo. Io ho acquistato e utilizzato questo ottimo SnowBall.

Meglio effettuare alcune prove di registrazione per trovare la corretta posizione, per settare il microfono in funzione dell’ambiente, per impostare il corretto volume di registrazione etc. Quando siamo pronti, iniziamo la lettura salvando la traccia con un nuovo nome ogni volta che cambiamo pagina (stiamo parlando di Fixed Layout quindi ogni pagina deve essere considerata a se stante).

Quello che dobbiamo fare è individuare e isolare sulla traccia ogni singola parola in modo da poterla poi ‘agganciare’ agli id determinati precedentemente per le stringhe di testo. L’operazione richiede un pelo di pazienza, ma gli strumenti di selezione e ascolto rendono semplice la cosa. Una volta individuata la porzione di traccia corrispondente ad una parola, questa può essere etichettata (in Audacity: Command + B). Meglio lasciare vuoti i nomi delle etichette. Verranno definiti in modo automatico utilizzando ancora una volta lo strumento GREP. Saranno comunque proprio queste etichette, codificate in modo opportuno, a indicare quale porzione di traccia audio debba essere estratta dalla traccia totale, durante la lettura. La traccia audio completa deve essere essere esportata in formato m4a, mentre le etichette saranno esportate in un file di testo. E’ buona abitudine attribuire nomi di facile comprensione. Il brano di quella determinata pagina, meglio abbia un nome molto simile, se non uguale, a quello della pagina html cui fa riferimento.

La cosa più importante è invece l’esportazione delle etichette. (In Audacity File-> Export labels)

Questi sono i dati che vengono esportati e come già detto rappresentano, parola per parola, i tempi (in secondi) di inizio e fine:

Analogamente a quanto visto prima per le parole (scritte) modifichiamo ciascuna riga codificandola in modo opportuno per creare il corretto formato richiesto (SMIL). Numeriamo ogni riga (anche qui ad una riga corrisponde una e una sola parola) e procedendo di GREP otteniamo una rappresentazione riga per riga di questo tipo:

<par id=”par1″>

<text src=”page003.xhtml#W1″/>

<audio src=”audio/page003.m4a” clipBegin=”3.851610s” clipEnd=”4.509025s” />

</par>

Analizziamo quello che si vede nell’elemento par:

la seconda linea cerca il testo W1 all’interno della pagina page003.xhtml. La terza linea identifica il brano completo page00.m4a che si trova nella cartella ‘audio’ e ne estrae il brano compreso tra i secondi espressi dalla prima linea del file etichette (3.851610 e 4.509025) che come sappiamo rappresenta proprio l’espressione ‘sonora’ della parola W1.

Il file smil ottenuto conterrà tanti elementi ‘par’ quante sono le parole (o gruppi di parole) che compongono (o che abbiamo deciso che compongano) quella pagina.

Aggiungiamo l’header e il footer :

Scegliamo ancora una volta un nome strettamente legato alla pagina cui il file si riferisce (nel nostro caso page003) aggiungiamo estensione .smil e salviamo come solo testo. Ogni pagina avrà i suoi file smil, xhtml e audio e tutti ovviamente andranno dichiarati nel file content.opf. In più dovremo definire anche un’ associazione e sovrapposizione in simultanea tra file xhtml  e smil (media overlay)

<item id=”pg003″ href=”page003.xhtml” media-type=”application/xhtml+xml” media-overlay=”pg003smil” />

Se vogliamo che all’ascolto del testo sia accompagnata anche l’evidenziazione della parola letta, Apple mette a disposizione una classe da inserire nel CSS che si applica automaticamente ad ogni parola letta e su cui l’autore non può intervenire se non per deciderne il colore:

.-epub-media-overlay-active {

color: red;

}

Una volta caricato l’epub la funzionalità deve essere attivata. Nel menu di iBooks appare la nuova icona ‘altoparlante’.

Al click ci viene chiesto se procedere con l’ascolto dell’audio (è possibile anche regolare il volume) e se si vuole l’avanzamento pagina automatico o manuale.

Questo il risultato finale. Nonostante la scadente qualità del filmato sono chiaramente intuibili le potenzialità di questa funzione:

http://vimeo.com/31515563

_

Ecco, questo in buona sintesi è quello che dobbiamo sapere per iniziare ad introdurre nei Fixed Layout ePubs le funzionalità di lettura ad alta voce. Se ne potrebbe parlare ancora e molto più in profondità. Giusto per fare qualche esempio, sappiate che è possibile inserire in modo abbastanza semplice pulsanti per lo stop o l’avvio dell’ascolto (purtroppo non è ancora possibile mettere in pausa); è possibile aggiungere una colonna sonora che faccia da background alla lettura di tutto il libro, o una colonna sonora diversa pagina per pagina (per meglio enfatizzare l’atmosfera che quel brano deve suscitare). Vedremo in futuro anche queste nuove funzionalità.