martedì 25 novembre 2008

Java Media Framework eqepa tutorial 2: input da webcam

Introduzione
In questo tutorial vedremo come sia possibile accedere tramite il Java Media Framework all'input proveniente da webcam.
Consigliamo di leggere prima il primo tutorial che eqepa ha scritto sull'utilizzo del framework, lì sono presenti tutte le informazioni e i download necessari per iniziare ad usare il JMF.
Il codice di questo esempio è scaricabile da qui, consiglio di leggere il tutorial insieme al codice, spiegherò passo per passo il funzionamento del programma.


Iniziamo...
Caricate il progetto in NetBeans, possiamo vedere che il programma è composto da tre classi il cui funzionamento dovrebbe essere già chiaro a chi ha capito il primo tutorial presentato da eqepa:
- Main.java: contiene il cuore dell'applicazione.
- MyControllerListener.java: necessaria per il corretto import delle componenti grafiche del player.
- ContenitoreManiglie.java: necessaria per la comunicazione tra Main e MyControllerListener.

Apriamo Main.java ed analizziamola: innanzitutto vediamo che estende la classe JFrame quindi avrà una controparte grafica, inoltre essa ha come attributi un Player, un MediaLocator, un Component e un oggetto di tipo MyControllerListener.
Partiamo dal costruttore Main(): in questo metodo vengono chiamati settaggioInterfaccia(), settaggioPlayer() e poi viene chiamato il metodo setDefaultCloseOperation che associa la pressione del tasto "X" della finestra alla chiusura del programma.
Il metodo settaggioInterfaccia() registra l'oggetto di tipo Main appena istanziato (se stesso) nel contenitoreManiglie tramite il metodo statico setMain e associa un borderLayout al frame.
Passiamo ora al metodo settaggioPlayer(): innanzitutto istanziamo il mediaLocator relativo all'input della webcam tramite la funzione setMediaLocator.
Il mediaLocator descrive la posizione del contenuto multimediale che verrà poi "trattato" dal Player; per quanto riguarda la webcam come input multimediale ho trovato vari metodi per ottenerne la posizione:
uno di tali metodi, trovato qui e implementato nella funzione autoDetect() consiste nel farsi restituire una lista dei device riconosciuti nel sistema dal metodo getDeviceList del CaptureDeviceManager.
A partire da questa lista si selezionano solo i device il cui nome inizia per "vfw" (video for windows, per quanto riguarda linux la sigla da utilizzare è "v4l"). Ho provato a reimplementare tale metodo per costruire questo tutorial ma ho riscontrato molta lentezza dell'applicazione (che ancora non riesco a spiegarmi) e il fatto che il metodo getDeviceList() su menzionato non restituisce alcun elemento.
La soluzione trovata (che potrebbe essere poco professionale in quanto non generale) è stata quella di utilizzare uno dei programmini utili che l'istallazione del JMF include: jmfregistry.exe (ritrovabile nella sottocartella bin della cartella di istallazione di JMF).
Questo programma contiene tutte le informazioni dei device presenti nel sistema, quindi, anche il locator del "video device" che nel mio caso è "vfw://0". Al momento non ho controllato il funzionamento di tale programma su altri computer con webcam diversa dalla mia o con più webcam installate (a breve per un aggiornamento).
Tornando quindi al nostro codice istanziamo il nostro bel mediaLocator passando al suo costruttore la stringa del device video "vfw://0". Se il mediaLocator è stato istanziato procediamo con la creazione del Player tramite il metodo setPlayer() e associamo a quest'ultimo il ControllerListener da noi implementato.
A questo punto il player partirà e, quando sarà realizzato, chiamerà il metodo realizeComplete del ControllerListener associato ad esso, metodo che noi abbiamo prontamente ridefinito (ovverride) per chiamare la funzione setComponentiVisuali() di Main.
Infine la funzione setComponentiVisuali prende la visualComponent del player e la aggiunge al Frame.
Facciamo il run ed ecco il risultato (ovvero uno scorcio del disordine nella camera mia e di emilio):

A questo punto vi prego di riportarci bug nel codice. A presto per il prossimo tutorial dove "grabberemo" e memorizzeremo un'immagine jpeg a partire dalla webcam, punto di lancio per poter manipolare i frame provenienti dalla webcam per implementare motion e color detection.

Continua...

lunedì 17 novembre 2008

Registrazione su Blogger Italiani

Siamo lieti di annunciare che Blogger Italiani ci ha aggiunto nell'elenco dei blog indicizzati. Purtroppo il team di eqepa è attualmente sotto esami e non potrà impegnarsi molto per creare (come ci eravamo prefissati) almeno 2 guide a settimana. Quindi non potremo onorare questa nuova registrazione con contenuti freschi almeno per un pò (priorità alla laurea...).

Continua...

mercoledì 5 novembre 2008

Installare e Configurare MySql server sotto windows

Introduzione
In questo tutorial affronteremo l'installazione e sopratutto la configurazione del DBMS MySql in ambiente windows, esaminando quali sono i passi da seguire e cercando di darne una motivazione. A conclusione di questo tutorial realizzeremo un semplice installer che mette insieme tutti i passi seguiti nella trattazione.


Prima di cominciare abbiamo bisogno, ovviamente, del materiale da configurare, quindi occorre scaricare l'ultima versione di MySql disponibile. Per la lettura di questo tutorial e per la sua comprensione è conveniente scegliere la versione senza installer, in quanto alla fine saremo in grado di realizzarlo da soli.
Una volta scaricato scompattiamo l'archivio in una qualsiasi directory e partiamo.

Per prima cosa è necessario sapere che MySql mantiene le informazioni necessarie alla sua configurazione all'interno del file my.ini che, seguendo le impostazioni di default, il dbms cerca nella cartella di installazione del sistema operativo(%windir% da shell). Di conseguenza posizioneremo il nostro file my.ini all'interno della directory %windir%(e.g C:\windows).
Questa è la struttura del file già modificata opportunamente per il settaggio del motore del DB da MyIsam a Innodb(necessario per connessioni remote al db ad esempio tramite jdbc):

my.ini:

[client]
port=3306

[mysqld]
port=3306
enable-named-pipe
socket=MySQL

skip-locking
set-variable = max_connections=64
set-variable = read_buffer_size=1M
set-variable = key_buffer=8M
set-variable = max_allowed_packet=1M
set-variable = table_cache=64
set-variable = sort_buffer=512K
set-variable = net_buffer_length=8K
set-variable = myisam_sort_buffer_size=4M
server-id = 1

basedir = "full path to mysql"/
datadir = "full path to mysql"/data/

skip-bdb

innodb_data_file_path = ibdata1:10M:autoextend
set-variable = innodb_buffer_pool_size=32M
set-variable = innodb_additional_mem_pool_size=4M

set-variable = innodb_log_file_size=8M
set-variable = innodb_log_buffer_size=8M

innodb_flush_log_at_trx_commit=1

[mysqldump]
quick
set-variable = max_allowed_packet=8M

[mysql]
no-auto-rehash

[isamchk]
set-variable = key_buffer=10M
set-variable = sort_buffer=10M
set-variable = read_buffer=2M
set-variable = write_buffer=2M

[myisamchk]
set-variable = key_buffer=10M
set-variable = sort_buffer=10M
set-variable = read_buffer=2M
set-variable = write_buffer=2M

[mysqlhotcopy]
interactive-timeout


dove le righe colorate in rosso si riferiscono al passaggio di motore.
Ci concentreremo sulle righe colorate in blu relative al settaggio delle cartelle contenenti i binari di MySql e la locazione dei db, necessarie per avviare correttamente il server. Ciò che è necessario fare, dunque, è impostare correttamente le directory delle due opzioni che dipendono da dove si è estratto l'archivio iniziale. Nel mio caso saranno:

basedir = c:/MySql/
datadir = c:/MySql/data/

per tutte le altre opzioni, che non saranno trattate in questo tutorial potete fare riferimento al sito ufficiale di MySql

Inserito questo file nella win path entriamo nella directory bin e richiamiamo da shell l'eseguibile mysqld-nt seguito dal comando --console, l'output dovrebbe essere simile a questo:



Tramite questo script forziamo la lettura del file e quindi il settaggio dei parametri per il nuovo motore e per il corretto avvio del server.

Essendo questo tutorial incentrato sulla configurazione manuale di mysql, utile per un eventuale deploy assieme ad una qualsiasi nostra applicazione, quello che vorremmo avere è un server che si avvi in automatico ad ogni accensione della macchina dove è installato. Per tanto installiamo mysql come servizio invocando, sempre da riga di comando, mysqld-nt --install
cio' che dovrebbe accadere è questo:


Il servizio è stato quindi installato correttamente. Per avviarlo ci sono due strade:
1)il reboot del sistema
2)accesso alla lista dei servizi e avvio manuale, se avete eseguito correttamente tutti i passi il servizio si avvierà con successo.

Per testare che tutto funzioni eseguiamo mysqladmin seguito dal comando
ping; se il servizio è attivo allora dovreste avere un output simile a questo:


quindi ora il vostro server mysql è installato e in ascolto sulla sua porta di default fissata appunto da noi in my.ini.

Per disinstallare il servizio possiamo utilizzare mysqld-nt --remove, ma è necessario prima arrestarlo con mysqladmin -u root -p shutdown (sono necessari i privilegi di super utente per arrestare il servizio). L'output è il seguente:

NB:
la password per il super utente di default è vuota, starà a voi una volta terminata l'esecuzione modificarla.

Per usare inizialmente il nostro DBMS possiamo usare l'interfaccia messa a nostra disposizione dall'eseguibile mysql contenuto sempre nella direcoty bin.



Ora siete in grado di installare e configurare il server mysql manualmente. L'obiettivo sarà quello di creare un installer che automatizzi questo processo e che ci potrà essere utile per un futuro deployment di una nostra applicazione che faccia uso di mysql come dbms.
Ne realizzeremo uno nel prossimo tutorial.

Aspetto i vostri commenti!!!

Continua...

lunedì 3 novembre 2008

Java Media Framework eqepa tutorial 1: creiamo un lettore multimediale.

Introduzione.
Lo scopo di questo tutorial è quello di aiutare a compiere i primi passi con le JMF, framework di sviluppo java per il multimedia. Iniziamo con i link indispensabili. Lo staff di eqepa consiglia vivamente netbeans come tool di sviluppo java per la facilità di utilizzo e la sua ide di sviluppo grafica. Indispensabili inoltre le JMF che consentono un utilizzo immediato di librerie per il multimedia, scaricatele e istallatele ovviamente prima di avviare il nostro progetto.
Il codice di questo esempio lo trovate invece qui.
Per utilizzare il codice da noi fatto scompattate l'archivio e aprite la cartella "lettore_eqepa" tramite il pulsante "open project".

Prima di partire con la guida premetto che è importante conoscere un minimo la struttura e la filosofia del framework che utilizzeremo; per quanto possibile spiegherò man mano il codice ma consiglio di leggere qualche introduzione sulle jmf. Potete trovare articoli utili qui (in inglese) e qui (in italiano).
Inoltre aggiungo che il risultato di questa guida è realizzabile anche tramite un unico file (ovvero un'unica classe) ma noi applichiamo per quanto possibile le "best practices" dettate dall'ingegneria del software, ovvero al posto di fare codice velocemente preferiamo fare codice lentamente ma di qualità.
La nostra sarà una panoramica dettagliata il più possibile sulla soluzione da noi data, non si tratta "della Soluzione" ma di "una soluzione". Spero che il metodo in cui presento il tutorial sia utile, nel caso contrario vi prego di farmelo sapere. Ricordate sempre che siamo agli inizi di questa nostra avventura di eqepa e siamo più che contenti se ci aiutate a migliorare.

Ok, iniziamo.
Creeremo un lettore multimediale capace di leggere MP3 e avi.

Aprite netbeans e caricate il progetto; possiamo vedere quindi che il nostro progetto si compone di cinque classi:


-Main.java: è la nostra "main class" ovvero la classe che verrà istanziata per prima.
-InterfacciaLettore.java: è il cuore dell'applicazione, contiene tutti i metodi e le componenti visuali necessari al programma.
-MyActionListener.java: implementa l'interfaccia ActionListener, necessaria per il funzionamento del bottone (vedremo in seguito).
-MyControllerListener.java: estende la classe ControllerAdapter, necessaria per il corretto import delle componenti visuali del player(vedremo in seguito).
-ContenitoreManiglie.java: questa è una classe statica che contiene le maniglie degli oggetti istanziati. E' necessaria per la comunicazione tra le varie classi.

Nel metodo main della classe Main viene immediatamente istanziato un oggetto di tipo InterfacciaLettore e vengono visualizzate le sue componenti grafiche grazie al metodo setVisible(); passiamo quindi all'analisi della classe InterfacciaLettore.
Quello che vogliamo è selezionare un file multimediale dal filesystem e aprirlo.
A questo scopo, dopo aver "registrato" se stesso nel ContenitoreManiglie e settato il metodo di chiusura dell'applicazione, l'oggetto di tipo InterfacciaLettore istanzia, setta e aggiunge al pannello un bottone. Come molti (anzi tutti) sapranno alla pressione di un bottone si genera un evento; se al bottone viene associato un ActionListener tramite il metodo addActionListener(), alla pressione viene chiamato il metodo ActionPerformed dell'ActionListener associato al bottone. In questo caso è del tutto inutile (perchè abbiamo un solo bottone) ma associamo al bottone istanziato un ActionCommand ovvero una stringa che contraddistingue il bottone. Quando l'utente preme quindi il bottone "search file" si genererà un evento e verrà chiamato il metodo ActionPerformed del MyActionListener. Quest'ultimo metodo controlla di quale bottone si tratti (con il test sull'ActionCommand) e così fa partire il metodo ScegliFile() di InterfacciaLettore.
Quest'ultimo metodo istanzia un nuovo oggetto di tipo FileDialog (una finestra di ricerca nel filesystem) e quindi setta l'attributo filename alla stringa corrispondente all'indirizzo del file da aprire. Il return finale serve per controllare che l'utente ha selezionato o meno un file da aprire (questo è uno dei pochi controlli che abbiamo inserito, il resto lo lasciamo a voi). Torniamo quindi all'ActionListener: se l'utente ha scelto un file la stringa filename sarà diversa da "file:///nullnull" e, in questo caso proviamo a creare un lettore adatto al file selezionato richiamando (sotto le clausole try-catch) il metodo setPlayer() di InterfacciaLettore.
La creazione del player è una delle cose più accattivanti (per la sua semplicità) delle JMF; basta richiamare il metodo statico createPlayer() della classe Manager ed assegnare la maniglia che questo metodo ritorna, al nostro player.
A questo punto potremo già richiamare il metodo start() del player e vedere, anzi ascoltare i primi risultati di questa nostra avventura nelle JMF. Perchè ho detto ascoltare? Perchè con l'invocazione del metodo start() il player comincia a leggere e elaborare il file scelto ma non vedremo alcuna controparte grafica di tale elaborazione.
Per ovviare a questo problema dobbiamo invocare i metodi getVisualComponent() e getControlPanelComponent(). Il primo ci ritorna un oggetto di tipo component contenente le informazioni grafiche relative al file aperto (naturalmente questo oggetto sarà null se il file è audio) mentre il secondo ci ritorna un Component contenente dei pulsanti base e una barra di navigazione del file. A questo punto un problema a cui tutti (a parte gli utenti del nostro blog e chi ha la pazienza di leggere TUTTA la documentazione prima di fare esperimenti) vanno subito a sbattere la testa è il seguente: appena richiamato il metodo start() del player tanto vale richiamare i metodi che ci ritornano le componenti visuali e inserirle nel frame. Questo comporta sempre un'eccezione che dice "impossibile prendere le componenti grafiche di un player non realizzato".
Tale eccezione parla da sola se avete letto le introduzioni che vi ho consigliato (in particolare quella di Mokabyte).
Quindi il tempo per passare dall'istruzione start() a getVisualComponent() oppure getControlPanelComponent() non è sufficiente per la realizzazione completa del player. In rete, in particolare sui forum, si trovano soluzioni a questo problema poco "eleganti" come quella di usare il metodo Thread.sleep(int m) tra un'istruzione e l'altra per bloccare il thread del frame per m millisecondi prima di andare avanti con il return delle componenti visuali. Naturalmente Sun ha pensato a questo e noi utilizzeremo la soluzione proposta.
Possiamo tornare al nostro codice.
Associamo al player un ControllerListener creato da noi: la tecnica è sempre la stessa, come per l'actionListener, creiamo una nostra classe MyControllerListener che estende ControllerAdapter, facciamo l'override del metodo realizeComplete che viene chiamato quando il player è finalmente realizzato ed il gioco è fatto.
Quest'ultimo metodo, per comodità, richiama il metodo setComponentiVisuali() di InterfacciaLettore che richiede le componenti grafiche del player e le associa agli attributi CompCentrale e CompInBasso (mi scuso per il nome di questo attributo ma proprio non mi veniva in mente un nome migliore).
Ecco il risultato:

Interfaccia iniziale:
Scelta del file:
Player MP3:


Player AVI:
Naturalmente non pretendete che il player vi faccia vedere film in codec particolari come divx o H.264. Comunque sia i prossimi tutorial andranno ancora a fondo nella programmazione con JMF e (sempre esami permettendo) approfondiremo questo argomento.

Ora il lavoro è solo vostro: commentate!

Continua...

domenica 2 novembre 2008

Primo obbiettivo raggiunto!

Abbiamo raggiunto il primo obbiettivo (penso) di ogni blog neonato: aumentare la visibilità. A questo scopo lo staff di EQEPA ringrazia anche Il Bloggatore che ha voluto inserire senza problemi un blog come il nostro che si trova ancora allo stato embrionale.
Non ci faremo sfuggire quest'opportunità quindi ci impegneremo (esami permettendo) per offrire contenuti sempre freschi e utili.
Abbiamo pensato a molte novità da proporvi, cose che non abbiamo visto in giro sul web e che secondo noi potrebbero portare a risultati eccellenti. Ora non vi anticipiamo nulla, vi possiamo dire solo di seguirci e farci sapere che ci siete commentando i nostri post. Alla prossima!

Continua...