Midi Player

24 marzo 2003

SCOPO

Avviare e interrompere la riproduzione di un file midi da Flash

STRUMENTI
Richiamo funzioni Javascript da Flash | Scrittura in un layer html

METODO
Il sistema di gestione e riproduzione dei file audio all’interno di una pagina html varia enormemente a seconda del browser utilizzato, delle sue diverse versioni, dei plugin installati, della piattaforma dell’utente.
Per questo motivo, il funzionamento dell’esempio è limitato a due soli browser: Internet Explorer fino alla versione 6 compresa e Netscape Navigator 7.
Naturalmente sarebbe possibile ottenere lo stesso effetto tramite l’uso dei frame, rendendolo anche accessibile ad un maggior numero di browser: ma questo renderebbe minore l’apporto dell’interazione Flash – Javascript, costringendolo alla mera richiesta di un cambio di pagina.

GESTIONE DEI MIDI
Come accennato, esistono diversi metodi di incorporare e gestire un file midi in una pagina html: anche se il tag embed funziona sia con Netscape Navigator che con Internet Explorer a partire dai browser di quarta generazione, noi useremo un sistema per il primo, e un altro per il secondo.
Perchè usarne due quando uno funziona con entrambi? Perchè lo scopo di questa tecnica non è quello di incorporare un file midi in una pagina html, e neppure quello di interromperne e riavviarne la riproduzione. Quello che vogliamo fare, è poter cambiare dinamicamente il file riprodotto.

Il tag embed, usato per Netscape Navigator, non lo permette, mentre lo permette il bgsound usato per Internet Explorer. Dovremo quindi solo modificare una proprietà con il secondo, ma addirittura riscrivere dinamicamente il codice per il primo.

.embed per Netscape Navigator

<embed src=”file.mid” [attributi]></embed>

A seconda del plugin installato per la lettura dei file midi, nella pagina html appare un diverso sistema grafico di controllo. Nel mio caso, ad esempio, dal momento che il plugin è quello del QuickTime, il controller appare così:

Controller QuickTime per i file midi

Al tag embed, possono essere aggiunti diversi attributi, per impostare ad esempio le dimensioni del controller e il numero di pulsanti. Noi ci limitiamo ad alcuni fondamentali, per ottenere il codice seguente:

<embed
src=”file.mid”
name=”musicID”
type=”audio/midi”
loop=true
autostart=true
hidden=true
mastersound>
</embed>

src – indica nome e percorso del file da riprodurre
name – è l’identificativo del file midi, per poter richiamare i metodi dell’oggetto
type – indica il tipo di file incorporato
loop – indica se il file debba cominciare da capo una volta terminata la riproduzione: può avere valore true | false | numero di loop
autostart – indica se il file audio debba iniziare a riprodursi da solo: true | false
hidden – indica, se impostato come true, che il controller del plugin non debba essere visibile: true | false
mastersound – indica la preminenza del file audio indicato

Per far riferimento al file audio incorporato, la notazione è di questo tipo:

document.embeds[id_suono]

nel nostro caso:

document.embeds['musicID']

In questo modo, è possibile interrompere la riproduzione del suono:

document.embeds['musicID'].Stop();

e avviarla:

document.embeds['musicID'].Play(true|false);

( embeds è un array associativo contenente la lista di tutti gli oggetti incorporati nella pagina tramite il tag embed )

Il codice di incorporamento verrà inserito all’interno di un layer html: quando dovremo cambiare midi, riscriveremo il contenuto del layer.

.bgsound per Internet Explorer

<bgsound src=”file.mid” [attributi]>

Con gli attributi che ci interessano:

<bgsound src=”file.mid” id=”musicID” loop=infinite autostart=true>

src – indica nome e percorso del file da riprodurre
id – è l’identificativo del file midi, per poter richiamare i metodi dell’oggetto
loop – attributo omonimo di quello del tag embed: ha le stesse funzioni, solo che il loop infinito si indica con “infinite”
autostart – indica se il file audio debba iniziare a riprodursi da solo: true | false

Per interrompere la riproduzione del suono, è sufficiente modificare la proprietà src perchè contenga una stringa vuota:

document.all['musicID'].src = “”;

per riprenderla, o per cambiare il suono riprodotto:

document.all['musicID'].src = “nuovoMidi.mid”;

IL FILE XML

I dati relativi ai midi da riprodurre, sono inseriti in un file *.xml che viene caricato dal filmato Flash: in questo modo, il numero dei file, il loro percorso e nome, il loro titolo e la loro durata possono variare a piacimento, senza che debba essere toccato ne il filmato, ne la pagina html che lo incorpora.
Il file *.xml, midi.xml, è strutturato in questo modo:

<playlist id=”midi” items=”n“>
<item id=”1″ src=”nome.mid” title=”titolo” author=”autore” duration=”mm:ss” />
<item id=”2″ src=”nome.mid” title=”titolo” author=”autore” duration=”mm:ss” />
[....................]
<item id=”n” src=”nome.mid” title=”titolo” author=”autore” duration=”mm:ss” />
</playlist>

Il nodo principale si chiama playlist, e possiede gli attributi id e items. Il primo è un generico identificatore per il nodo, il secondo il numero dei nodi figlio: nessuno dei due è utile ai fini dello script, ma servono solo come reminder per lo sviluppatore.

Sotto il nodo playlist, sono definiti i nodi items, uno per ogni file midi che vogliamo poter scegliere: non hanno un contenuto in senso stretto, ma i dati sono inseriti sotto forma di attributi:
id – identificatore ordinale del midi inserito
src – nome e percorso del file midi
title – titolo del brano contenuto nel file midi
author – nome dell’autore del brano
duration – durata del brano espressa nel formato mm:ss
Di questi attributi, solo src è necessario: gli altri servono unicamente a rendere più agevole la scelta del brano.

IL FILMATO FLASH

Il filmato è stato creato con Macromedia FlashMX, per poter usufruire dei vantaggi dei component ListBox e PushButton.
Gli oggetti sono disposti in questo modo:

Stage del filmato

Sulla sinistra abbiamo un component ListBox, con nome di istanza lista_lb. A destra abbiamo tre campi di testo dinamici, title_txt, author_txt, duration_txt, che serviranno a mostrare le informazioni sul singolo brano estratte dal file *.xml.

In basso a destra ci sono due istanze del component PushButton. Selezionando il pulsante con la scritta play, il pannello delle proprietà ci appare così:

Proprietà del pushButton

Da notare: il nome di istanza play_pb e l’etichetta “Play”.
Il pulsante per lo stop è molto simile: nome di istanza stop_pb, etichetta “Stop”.
Allo stesso frame della timeline principale in cui sono disposti gli oggetti, è associato tutto lo script del filmato. In sintesi: il filmato carica il file xml, e crea nella timeline principale un array del quale ogni elemento è un oggetto contenente le caratteristiche e i dati di un singolo brano.
U una volta terminato il caricamento, il ListBox viene popolato con i titoli dei brani, e quando si clicca su un titolo, i campi di testo a destra mostrano titolo, autore e durata del brano stesso.

Quando viene premuto il tasto play dopo aver selezionato una canzone, viene richiamata la funzione Javascript playMIDI (omonima, per semplicità, della funzione associata al pulsante play). A questa funzione, vengono passati tre parametri: il primo è fisso, ‘musicID’, e serve ad identificare il suono nella pagina.
Il secondo è preso dalla variabile currentSong, che contiene nome e percorso del midi da riprodurre relativo alla canzone selezionata nel ListBox. Il terzo, nella variabile flag, può essere true o false, e serve ad indicare se stiamo cercando di riprodurre un midi diverso dall’ultima volta che abbiamo premuto play, o se si tratta dello stesso.

// ferma la riproduzione del filmato
this.stop();
// chiama il metodo setAutoHideScrollBar del ListBox lista_lb, per nascondere
// la barra nel caso in cui gli elementi non siano sufficienti per lo scroll
lista_lb.setAutoHideScrollBar(true); // disabilita momentaneamente i pulsanti “play” e “stop”
play_pb.setEnabled(false);
stop_pb.setEnabled(false); // scrive nel listBox “caricamento in corso”
lista_lb.addItemAt(0, “caricamento in corso”, 0);
// crea un’istanza dell’oggetto XML chiamata datiXML
datiXML = new XML();
// setta la proprietà ignoreWhite come vera, in modo che non vengano
// considerati come nodi gli a capo nel file *.xml
datiXML.ignoreWhite = true;
// salva nell’istanza, tramite la variabile path, un collegamento alla timeline
// in cui l’istanza è definita: questo perchè un’istanza dell’oggetto XML
// non può usare _parent
datiXML.path = this;
// definisce la funzione da eseguire al caricamento completo dei dati passando
// il parametro “ok” che sarà true se il caricamento è andato a buon fine
datiXML.onLoad = function(ok)
{
// se il caricamento è andato a buon fine
if(ok){
// crea nella timeline principale, il cui collegamento è nella variabile path,
// un’istanza dell’oggetto Array chiamata playlist
this.path.playlist = [];
// con un ciclo for a tante iterazioni quanti sono i nodi contenenti i brani
for(var i = 0; i < this.firstChild.childNodes.length; i++){
// salva nella variabile locale att il riferimento all’array
// associativo degli attributi
var att = this.firstChild.childNodes[i].attributes;
// crea nell’array playlist, all’indice relativo al nodo, un oggetto vuoto
this.path.playlist[i] = {};
// setta la proprietà label dell’oggetto appena creato con il valore
// dell’attributo title relativo al nodo
this.path.playlist[i].label = att.title;
// sempre nell’oggetto appena creato, setta la variabile data come un
// oggetto contenente tutti gli altri dati della canzone
this.path.playlist[i].data = { src:att.src,
title:att.title,
author:att.author,
duration:att.duration};
// chiama la funzione deleteXML a livello della timeline principale
this.path.deleteXML();
}
// altrimenti (il caricamento non è andato a buon fine)
} else {
// svuota il ListBox
this.path.lista_lb.removeAll();
// inserisce al primo posto la scritta “caricamento errato”
this.path.lista_lb.addItemAt(0, “caricamento errato”, 0);
// disabilita il ListBox
this.path.lista_lb.setEnabled(false)
}
};
// definisci la funzione chiamata al termine del caricamento positivo dei dati
function deleteXML(){
// cancella l’istanza dell’oggetto XML
delete datiXML;
// associa al ListBox l’array playlist, di cui vengono mostrate le etichette
lista_lb.setDataProvider(playlist);
// setta la funzione da richiamare quando si clicca un elemento del ListBox
lista_lb.setChangeHandler(“change”);
// associa al click sui due pulsanti la funzione playMIDI e stopMIDI
play_pb.setClickHandler(“playMIDI”);
stop_pb.setClickHandler(“stopMIDI”)
}
// definisce la funzione change, da richiamare
// quando si cambia elemento nel listBox lista_lb
function change(){
// nella variabile song salva un riferimento alla proprietà data dell’oggetto
// relativo all’elemento selezionato
var song = lista_lb.getSelectedItem().data;
// nei campi di testo scrive i dati estratti dall’oggetto
title_txt.text = song.title;
author_txt.text = song.author;
duration_txt.text = song.duration;
// abilita i tasti play e stop
play_pb.setEnabled(true);
stop_pb.setEnabled(true);
}
// definisce la funzione playMIDI, richiamata quando si preme il tasto play
function playMIDI(){
// nella variabile song viene salvato un riferimento alla proprietà src
// dell’oggetto data, relativo all’elemento selezionato nel ListBox
var song = lista_lb.getSelectedItem().data.src;
// setta la variabile flag in base alla corrispondenza tra la variabile song e
// la variabile currentSong: se sono uguali, vuol dire che abbiamo premuto
// nuovamente play senza cambiare canzone nel listBox
var flag = (song == currentSong) ? true : false;
// alla variabile currentSong assegna il valore di song, per il controllo seguente
currentSong = song;
// richiama la funzione Javascript playMIDI, passando i tre parametri
// musicID, il nome e percorso del file da riprodurre, e la variabile flag
getURL(“javascript:playMIDI(‘musicID’, ‘” + currentSong + “‘, ” + flag + “)”);
}
// definisce la funzione da richiamare quando si preme il tasto stop
function stopMIDI(){
// invoca la funzione Javascript stopMIDI, passando come parametro
// il solo identificativo del suoo nella pagina
getURL(“javascript:stopMIDI(‘musicID’)”);
}
// carica i dati dal file midi.xml
datiXML.load(“midi.xml”);

LA PAGINA HTML

<HTML>
<HEAD>
<TITLE>Riproduzione MIDI da Flash</TITLE>
<script language=”JavaScript1.2″ type=”text/javascript”>
<!–
var EM1 = ‘<div id=”musicID” style=”[proprietà]“>’;
var EM2 = ‘<embed type=”audio/midi” src=”‘;
var EM3 = ‘” name=”midiMusic” [attributi]></embed>’;
var EM4 = ‘</div>’; function playMIDI(id, brano, flag) {
if(document.all){
document.all[id].src = brano;
} else if(document.getElementById){
if(flag){
document.embeds['midiMusic'].Rewind();
document.embeds['midiMusic'].Play(true);
} else {
document.getElementById(id).innerHTML = EM2 + brano + EM3;
}
}
}
function stopMIDI(id){
if(document.all){
document.all[id].src = “”;
} else if(document.getElementById){
document.embeds['midiMusic'].Stop();
}
}
//–>
</script>
</HEAD>
<BODY bgcolor=”#CCCCCC”>
<script language=”JavaScript1.2″ type=”text/javascript”>
<!–
if (navigator.appName == “Microsoft Internet Explorer”) {
document.write(‘<bgsound src=”" id=”musicID” loop=infinite autostart=true>’);
} else {
document.write(EM1 + EM2 + EM3 + EM4);
}
//–>
</script>
<OBJECT
classid=”clsid:D27CDB6E-AE6D-11cf-96B8-444553540000″
codebase=”[...]“
WIDTH=”400″ HEIGHT=”300″ ID=”playMidi”>
<PARAM NAME=movie VALUE=”playMidi.swf”>
<PARAM NAME=quality VALUE=high>
<PARAM NAME=bgcolor VALUE=#CCCCCC>
<EMBED
src=”playMidi.swf”
quality=high
bgcolor=#CCCCCC
WIDTH=”400″
HEIGHT=”300″
SWLIVECONNECT=”true”
NAME=”playMidi”
TYPE=”application/x-shockwave-flash”
PLUGINSPAGE=”http://www.macromedia.com/go/getflashplayer”>
</EMBED>
</OBJECT>
</BODY>
</HTML>

All’interno dei tag <head> della pagina ( evidenziate in viola ), sono definite le funzioni che serviranno a interrompere ed avviare la riproduzione del file midi. Nel corpo della pagina, evidenziato in verde, il codice di incorporamento del filmato che richiama le funzioni. Evidenziato in arancione, il codice Javascript che viene eseguito una sola volta al caricamento della pagina. Valuta se il browser è Internet Explorer: in caso positivo inserisce il codice con il tag bgsound, senza indicare alcun midi predefinito. In caso negativo, scrive nella pagina il codice dato dalla concatenazione di quattro stringhe contenute nelle variabili EM1, EM2, EM3 ed EM4.
EM1 – contiene l’apertura del tag <div> con i suoi attributi, e serve a inserire nella pagina un layer con z-index 1
EM2 – contiene il codice di incorporamento del suono tramite i tag embed fino alla dichiarazione del nome e percorso del suono
EM3 – contiene il codice di incorporamento embed dalla definizione del suono fino alla sua chiusura
EM4 – contiene la chiusura del tag <div>

Quindi: se visitiamo la pagina con Internet Explorer, il suono viene inserito come bgsound. Altrimenti, viene creato un layer con all’interno il suono inserito come embed.

Notazione importante: nel bgsound, il suono è identificato tramite l’id “musicID”. Nell’embed, l’dentificatore è ‘midiMusic’, dato che ‘musicID’ lo utilizziamo per identificare il layer che lo contiene:

<div id=”musicID” style=”position:absolute;[...]></div>

LE FUNZIONI JAVASCRIPT

Abbiamo visto che quando premiamo il tasto play, viene chiamata la funzione Javacript playMIDI passando tre parametri: identificativo del suono, nome del file midi, e flag indicante se stiamo riproducendo lo stesso midi di prima. Premendo il tasto stop, viene chiamata la funzione stopMIDI passando il solo identificativo del suono.

Vediamo cosa succede quando il browser è Internet Explorer:

// vengono passati i tre parametri
function playMIDI(id, brano, flag) {
// se il browser è Internet Explorer
if(document.all){
// identificando il suono nel bgsound tramite l’id, modifichiamo la
// proprietà “src” perchè contenga il riferimento al brano:
// è indifferente che venga riprodotto per la prima o seconda volta,
// e il parametro flag non viene considerato
document.all[id].src = brano;
} else if(document.getElementById){
if(flag){
document.embeds['midiMusic'].Rewind();
document.embeds['midiMusic'].Play(true);
} else {
document.getElementById(id).innerHTML = EM2 + brano + EM3;
}
}
}
// viene passato il solo identificatore del suono
function stopMIDI(id){
// se il browser è Internet Explorer
if(document.all){
// setta come “src” del bgsound una stringa vuota, fermando
// implicitamente la riproduzione
document.all[id].src = “”;
} else if(document.getElementById){
document.embeds['midiMusic'].Stop();
}
}

Se invece stiamo navigando la pagina con Netscape Navigator:

// vengono passati i tre parametri
function playMIDI(id, brano, flag) {
if(document.all){
document.all[id].src = brano;
// se il browser è Netscape Navigator
} else if(document.getElementById){
// se “flag” è vera, e quindi stiamo premendo di nuovo play
// senza aver cambiato canzone
if(flag){
// riferendosi all’identificativo del suono, e non al parametro
// id passato alla funzione, riavvolge i suono e lo fa ripartire
document.embeds['midiMusic'].Rewind();
document.embeds['midiMusic'].Play(true);
// altrimenti (abbiamo cambiato brano)
} else {
// scrive all’interno del layer html, questa volta identificato dal
// parametro id, il codice formato dal concatenamento delle stringhe
// EM2 (tag embed fino al suono), brano (nome del suono),
// EM3 (chiusura del tag embed), sostituendo completamente
// il precedente, e facendo riferimento al nuovo suono
document.getElementById(id).innerHTML = EM2 + brano + EM3;
}
}
}
// viene passato l’identificatore
function stopMIDI(id){
if(document.all){
document.all[id].src = “”;
// se il browser è Netscape Navigator
} else if(document.getElementById){
// ferma il suono
document.embeds['midiMusic'].Stop();
}
}

Quando il browser è Internet Explorer avviamo il suono cambiando la proprietà src con il nome del file da riprodurre, qualunque esso sia (le prestazioni sono le stesse): quando dobbiamo interromperlo, alla proprietà src assegniamo una stringa vuota.
Quando invece il browser è Netscape Navigator, usiamo due sistemi.
• per fermare e riavviare lo stesso suono, usiamo i metodi dell’oggetto, Stop, Rewind e Play
• quando dobbiamo cambiare il suono, riscriviamo completamente il tag embed
Perchè allora non riscrivere sempre il tag embed, svuotandolo al momento di fermare il suono, e riproponendolo al momento del riavvio?
Perchè i metodi sono molto più veloci della riscrittura del tag. Quindi, quando il brano è lo stesso, usiamo i metodi, e lo riscriviamo solo quando non possiamo farne a meno (cioè quando cambiamo il brano).

FILES
visualizza l’esempio | scarica l’esempio

Tutte le lezioni

1 ... 42 43 44

 

 

1 ... 42 43 44

Se vuoi aggiornamenti su Midi Player inserisci la tua e-mail nel box qui sotto:
 
X
Se vuoi aggiornamenti su Midi Player

inserisci la tua e-mail nel box qui sotto:

Ho letto e acconsento l'informativa sulla privacy

Acconsento al trattamento di cui al punto 3 dell'informativa sulla privacy