You Tube nei sistemi embedded

You Tube nei sistemi embedded

YouTube è in realtà un sito web che permette la condivisione dei suoi contenuti tra tutti i suoi utenti. Ciò che rende interessante YouTube è il ricorso alla tecnologia Adobe Flash al fine di consentire la riproduzione dei contenuti multimediali che vi sono presenti, al pari di Google video. In questo articolo vedremo alcune considerazioni da tenere presente per realizzare un lettore embedded dei contenuti di YouTube. YouTube è stato fondato nel febbraio 2005 da Chad Hurley, Steve Chen e Jawed Karim ed erano stati tutti dipendenti di PayPal.

YouTube è il leader nel settore dei video online ed è il principale contenitore planetario di contenuti multimediali. Grazie a YouTube diventa possibile, e relativamente facile, caricare e condividere videoclips; basta, infatti, collegarsi al sito www.youtube.com attraverso la rete mondiale utilizzando diversi strumenti quale telefonia mobile o netbook. YouTube è diventato negli anni uno strumento essenziali per la diffusione delle informazioni: tutti possono ricevere e trovare notizie sugli eventi correnti, reperire video sui loro hobbies.

layer_j2me

La popolarità di YouTube è vasta, poiché consente l’upload di video creati da chiunque. Infatti, YouTube ospita show televisivi, video musicali e personali fatti in casa dagli utenti della rete. I video ospitati su YouTube possono inoltre essere facilmente inclusi in siti web e blog utilizzando direttamente il codice HTML fornito da YouTube.

Quali sono le caratteristiche da tenere presenti se si vuole creare un’applicazone embedded in grado di leggere i contenuti multimediali su YouTube? Sicuramente l’argomento è abbastanza interessante per chi, magari, ha l’esigenza di realizzare un lettore embedded di contenuti multimediali presente in rete. Un framework di questo tipo deve essere in grado di offrire un’integrazione di una serie di componenti software in grado di rispondere a diversi requisiti, tra cui la possibilità di leggere un file multimediale su diversi formati. Quali sono i requisiti tipici di questa applicazione? Sicuramente una delle prime cose che occorre soddisfare è la possibilità di collegarsi, mediante una connessione di rete, a YouTube su dispositivi che dispongono di una JVM adatta (al pari delle applet nelle pagine web).

mi_dlet

Sun si è sempre orientata nel segmento embedded tanto da realizzare negli anni diverse versioni di Java intese come estensioni delle caratteristiche standard del linguaggio, pensiamo solo a PersonalJava, JavaPhone, JavaTV o embedded Java. L’approccio iniziale di Java verso il mondo embedded ha poi avuto un’evoluzione mirata a realizzare un ambiente di lavoro facilmente integrabile con ricche prestazioni e caratteristiche tecniche. Da un insieme di moduli dove ognuno era in grado a soddisfare una determinata esigenza a J2ME: una piattaforma comune di lavoro modulare ed espandibile in grado di coprire una vasta gamma di piattaforme embedded.

Architettura J2ME

La piattaforma Java viene divisa in tre edizioni. La Java 2 Standard Edition (J2SE) utilizzata per lo sviluppo di applicazioni convenzionali da desktop mentre Java 2 Enterprise Edition (J2EE) è rivolto alla programmazione di impresa, con particolare enfasi sullo sviluppo dal lato server, tramite l’uso di Enterprise JavaBeans, applicazioni web (servlets e JavaServer Pages), CORBA, e XML. Infine, Java 2 Micro Edition (J2ME), sottoinsieme di J2SE, è orientato verso i dispositivi portatili che non possono supportare un’implementazione totale di J2SE. La figura 1 pone in evidenza l’architettura J2ME. L’architettura pone l’accento sui concetti di configurazione e profilo, oltre alla presenza di un sistema operativo che, per i dispositivi mobile, è di solito Symbian e, come è ovvio, la Java Virtual Machine.

Esiste una differenza sostanziale tra configurazione e profilo. Nel primo caso, con configurazione ci si vuole riferire ad un insieme o classe di apparati in senso orizzontale, mentre per profilo identifica un singolo dispositivo nella classe in senso verticale. Nel primo caso possiamo disporre di un insieme di librerie comuni per determinate categorie di dispositivi, quali cellulari; viceversa, nel secondo caso, possiamo disporre,al contrario, librerie specifiche per un determinato dispositivo. E per questa ragione eventuali applicazioni scritte per quel dispositivo può non essere utilizzabili per un altro. In J2ME esistono due tipi di configurazioni a seconda dell’applicazione coinvolta: dispositivi portatili e plug-in. Il punto chiave è che ogni configurazione è specifica per una famiglia di dispositivi con capacità simili. Ad oggi, sono definite due configurazioni, entrambe prevedono connettività alla rete, fissa o wireless: la Connected Device Configuration (CDC) tipicamente per box TV e sistemi di navigazione per auto e la Connected Limited Device Configuration (CLDC) per cellulari,PDA.

youtube-search-download

Occorre precisare che non esiste una distinzione netta fra le due configurazioni. La configurazione che interessa a noi è la Connected Limited Device Configuration, o CLDC, realizzata appositamente per dispositivi che dispongono di dimensioni di memoria ridotte, dalle decine a qualche centinaio di Kb, e con processori, RISC o CISC, a 16 o 32 bit con basso consumo. I dispositivi che rientrano in questa categoria utilizzano una connessione senza fili, wireless, con alimentazione a batteria. Inoltre, per questa particolare configurazione la virtual machine da utilizzare è la Kilobyte Virtual Machine, KVM.

YouTUBE su embedded

Per realizzare un’applicazione embedded in grado di gestire i contenuti di YouTube è possibile ricorre alla tecnologia J2ME con le relative librerie MIDP e CLDC: questa tecnologia si basa su Java. Il vero motore di Java è la virtual machine; infatti, il compilatore Java trasforma il linguaggio di programmazione in un insieme di bytecode, successivamente la Java Virtual Machine (JVM) interpreta i bytecode Java per eseguire il programma. L’applicazione che andremo a realizzare sarà in grado di leggere i contenuti multimediali e di procedere al loro reperimento nella rete. L’applicazione sarà in grado di trattare i formati video MP4, FLV e 3GP. L’acronimo J2ME sta per Java 2 Micro Edition è ed stata realizzata appositamente da Sun per rispondere alle esigenze dell’embedded e dell’elettronica di consumo. J2ME permette la programmazione delle MIDlet, piccoli programmi dell’ordine delle decine di kb, in grado di essere eseguiti.

Listato 1 – Scheletro di una MIDlet

import javax.microedition.midlet.*;
public class MyMIDlet extends MIDlet
{
//costruttore
public MyMIDlet() { }
//metodi base:
public void startApp() { }
public void pauseApp() { }
public void destroyApp(boolean unconditional)
{ }
}

Listato 2 – “ciao mondo”

package it.unict.dmi.j2me.helloj2me;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
//Primo esempio di MIDlet.
//La classe estende MIDlet e visualizza solo un messaggio di benvenuto
public class HelloJ2ME_a1 extends MIDlet
{
private Display mDisplay;
private Form mForm;
public void startApp()
{
if (mForm==null)
{
//Creo il form dove inserire un messaggio
mForm=new Form(“Ciao Mondo!”);
//Ottengo un display per la MIDlet
mDisplay=Display.getDisplay(this);
}
//Imposto il form corrente nel display
mDisplay.setCurrent(mForm);
}
public void pauseApp() {}
public void destroyApp(boolean b)
{
//Notifico alla JVM la distruzione della MIDlet
notifyDestroyed();
}
//MAIN
public static void main(String a[]) throws Exception
{
it.unict.dmi.j2me.test.J2METest.exec(HelloJ2ME_a1.class);
}
//FINE MAIN
}

Configurazione CLDC

La configurazione CDLC è stata realizzata appositamente per dispostivi con risorse limitate, quali telefonia mobile o PDA (Personal Digital Assistant). Per supportare correttamente una configurazione di questo tipo occorre utilizzare un profilo dedicato a seconda dell’applicazione che si vuole realizzare. Così, i profili che si possono prendere in considerazione sono il MIDP (Information Device Profile) o il PDAP (Personal Digital Assistant Profile) che estende CLDC per sfruttare le prerogative migliori dei PDA, quali la presenza di una maggiore memoria e la disponibilità di un display migliore. Possiamo ricordare gli altri profili utilizzabili: il Foundation Profile che aggiunge classi J2SE al CDC, ma non per l’interfaccia utente o il Personal Profile (con configurazione CDC) che ridefinisce PersonalJava come profilo J2ME. Inoltre, il Personal Basis Profile che risulta simile al Personal Profile (con configurazione CDC e Foundation Profile), ma implementa una user interface più semplice e, per ultimo, il Game Profile (con configurazione CDC) che contiene le classi specifiche per sviluppare giochi.

Come si è gia scritto, il CLDC è utilizzata con pochi centinaia di Kb di memoria, almeno 128 KB utilizzati per la macchina virtuale e le librerie, mentre possono essere richieste almeno 32 KB per l’ambiente runtime e per l’allocazione degli oggetti Java. È necessario poi disporre di connettività verso una rete anche di tipo wireless e di un sistema operativo, seppur semplice, ma privo di alcuni funzionalità tipiche di un sistema di questo tipo quali il multitasking o un file system. Il sistema operativo deve essere in grado, ad ogni modo, di mandare in esecuzione la KVM mediante uno schedulatore. La CLDC definisce le caratteristiche del linguaggio e della KVM supportata. Ad esempio, la CLDC non deve gestire la notazione floating point e per questa ragione le classi di J2SE che trattano valori in floating-point non sono supportati e i metodi che ritornano valori floating point non sono presenti. Sono supportate solo tre classi di errori a runtime, in particolare java.lang.Error, java.lang.OutOfMemoryError e java.lang.VirtualMachineError.

Listato 3- YouTube

public class YouTube extends MIDlet implements CommandListener {
private static final int APP_STARTED = 0;
private static final int APP_ACTIVE = 1;
private static final int APP_DESTROYED = 2;
private static final Command CMD_OK = new Command(“OK”, Command.OK, 1);
private static final Command CMD_CANCEL = new Command(“Cancel”, Command.CANCEL, 1);
private static final Command CMD_BACK = new Command(“Back”, Command.BACK, 1);
private static final Command CMD_SAVE = new Command(“Save”, Command.SCREEN, 1);
private static final Command CMD_REFRESH = new Command(“Refresh”, Command.SCREEN, 1);
private static final Command CMD_SEARCH = new Command(“Search”, Command.ITEM, 2);
private static final Command CMD_DOWNLOAD = new Command(“Download”, Command.ITEM, 2);
private static final Command CMD_DELETE = new Command(“Delete”, Command.ITEM, 2);
private static final Command CMD_DOWNLOADSCR = new Command(“Downloads Screen”, Command.SCREEN, 2);
private static final Command CMD_SEARCHSCR = new Command(“Search Screen”, Command.SCREEN, 2);
private static final Command CMD_SETTINGS = new Command(“Settings”, Command.SCREEN, 2);
private static final Command CMD_ABOUT = new Command(“About”, Command.SCREEN, 2);
private static final Command CMD_EXIT = new Command(“Exit”, Command.EXIT, 2);
private static final String BIG_APPLICATION_ICON = “/icons/icon-big.png”;
private static final String VIDEO_FORMAT_NAMES[] = {“MP4 (High Definition)“, “MP4 (Good Quality)“,
“FLV (Medium Quality)“, “3GP (Low Quality)“, “3GP (Lowest Quality)“};
private static final String VIDEO_FORMAT_EXTENSIONS[] = {“mp4”, “mp4”, “flv”, “3gp”, “3gp”};
private static final int VIDEO_FORMAT_IDS[] = {22, 18, 5, 17, 13};
———-
if (command == CMD_SEARCH) {
SearchString = SearchSearchStringTextField.getString();
final String search_string = SearchString;
if (!search_string.equals(“”)) {
if (BgOperationThread == null || !BgOperationThread.isAlive()) {
BgOperationThread = new Thread() {
public void run() {
try {
ShowProgressMessage(“Searching YouTube...”);
SearchClass.MakeSearch(search_string);
ShowSearchForm();
} catch (Exception ex) {
ShowErrorMessage(ex.toString(), SearchForm);
}
}
};
BgOperationThread.start();
}
}
} else if (command == CMD_DOWNLOADSCR) {

Inoltre il metodo finalize è rimosso da java.lang.Object per semplificare il compito del garbage collector. L’interfaccia nativa Java, JNI, non è supportata e non si possono usare le classi Reflection per ottenere informazioni sulla JVM in esecuzione. La KVM non supporta poi la classe ThreadGroup, di conseguenza non si possono lanciare (o fermare) più thread insieme. Le classi definite dal CLDC e i suoi profili stanno nel package o nei sottopackage di javax.microedition, per identificare facilmente le specifiche classi del CLDC. Inoltre, la CLDC si occupa di fornire un insieme minimo di librerie, di gestire gli stream di I/O, si occupa della sicurezza e nel networking. 

Listato 4- Search

public class SearchClass extends Object {
private static final String YOUTUBE_SEARCH_URL =
“http://gdata.youtube.com/feeds/api/videos”;
private static final String YOUTUBE_SEARCH_SORT_ORDER = “relevance”;
private static final String YOUTUBE_SEARCH_START_INDEX = “1”;
private static final String YOUTUBE_SEARCH_MAX_RESULTS = “25”;
private static final String YOUTUBE_SEARCH_ALT = “atom”;
private static final String USER_AGENT = “YouTube”;
private static Vector SearchResults = null;
public static Vector GetSearchResults() {
return SearchResults;
}
public static void MakeSearch(String search_string) throws Exception {
Exception exception = null;
HttpConnection connection = null;
InputStream stream = null;
InputStreamReader stream_reader = null;
try {
connection = (HttpConnection)Connector.open(YOUTUBE_SEARCH_URL +
“?vq=” +
UtilClass.URLEncodeUTF8(search_string) +
“&orderby=” + YOUTUBE_SEARCH_SORT_ORDER +
“&start-index=” + YOUTUBE_SEARCH_START_INDEX
+
“&max-results=” + YOUTUBE_SEARCH_MAX_RESULTS
+
“&alt=” + YOUTUBE_SEARCH_ALT);
connection.setRequestMethod(HttpConnection.GET);
connection.setRequestProperty(“User-Agent”, USER_AGENT);
stream = connection.openDataInputStream();
stream_reader = new InputStreamReader(stream, “utf-8”);
TreeBuilder builder = new TreeBuilder();
Node root = builder.createTree(stream_reader);
SearchResults = new Vector();
if (root.getName().equals(“feed”)) {
for (int i = 0; i < root.children.size(); i++) {
Node entry = (Node)root.children.elementAt(i);
if (entry.getName().equals(“entry”)) {
int video_duration = 0;
String video_title = “”;
String video_url = “”;
for (int j = 0; j < entry.children.size(); j++) {
Node item = (Node)entry.children.elementAt(j);
if (item.getName().equals(“title”)) {
if (item.attributes.get(“type”) != null &&
item.attributes.get(“type”).equals(“text”)) {
video_title = item.getText();

}
} else if (item.getName().equals(“media:group”)) {
for (int k = 0; k < item.children.size(); k++) {
Node media_item = (Node)item.children.elementAt(k);
if (media_item.getName().equals(“media:player”) && media_item.attributes.
get(“url”) != null) {
video_url = (String)media_item.attributes.get(“url”);
} else if (media_item.getName().equals(“yt:duration”) &&
media_item.attributes.get(“seconds”) != null) {
try {
video_duration = Integer.parseInt((String)media_item.attributes.
get(“seconds”));
} catch (Exception ex) {
// Ignore
}
}
}
}
}
if (video_duration != 0 && !video_title.equals(“”) && !video_url.equals(“”)) {
SearchResults.addElement(new VideoClass(video_duration, video_title,
video_url));
}
}
}
} else {
throw (new Exception(“Invalid XML data”));
}
} catch (Exception ex) {
exception = ex;
SearchResults = null;
} finally {
if (stream_reader != null) {
try {
stream_reader.close();
} catch (Exception ex) {
// Ignore
}
}
if (stream != null) {
try {
stream.close();
} catch (Exception ex) {
// Ignore
}
}
if (connection != null) {
try {
connection.close();
} catch (Exception ex) {
// Ignore
}
}
}
if (exception != null) {
throw (exception);
}
}
}

Profilo MIDP

Il Mobile Information Device Profile (MIDP) è un profilo J2ME, Java 2 Micro Edition, che si basa sulla configurazione CLDC ed è utilizzato tipicamente per applicazioni mobili. Mentre la CLDC mette a punto alcune considerazioni generali il profilo MIDP aggiungono e integrano funzionalità presenti alfine di ottenere l’esecuzione, gestione e realizzazioni di applicativi Java nel segmento del mobile. Per raggiungere questo scopo è necessario disporre di un profilo che permetta di instaurare e stabilire connessioni http per terminali wireless, così come fa MIDP. Non solo, il profilo MIDP deve anche gestire il ciclo di vita delle applicazioni (figura 2), o MIDlet, la gestione della GUI, il salvataggio persistente dei dati, l’interazione tra l’utente e l’applicazione e la cattura e gestione degli eventi. Le operazioni supportate da MIDP sono realizzate nei package presenti in tabella 1. Le applicazioni sono anche chiamate MIDlet e devono essere realizzate per funzionare su qualsiasi dispositivo senza alcuna modifica.

package_in_midp

La scrittura di una MIDlet è abbastanza semplice ed intuitiva. Per prima cosa si deve estendere la classe javax. microedition.midlet.MIDlet e implementare i metodi startApp(), pauseApp() e destroyApp(). Il nome di una MIDlet deve essere conforme alla convenzione delle classi Java. Il ciclo di vita della MIDlet è svolto chiamando i metodi startApp(), pauseApp() e destroyApp(), dichiarati abstract nella classe MIDlet. Il metodo startApp() deve essere implementata per iniziare l’esecuzione o per farla ripartire, la pauseApp() deve contenere i comandi per la sospensione dell’applicazione. Infine, la destroyApp() deve contenere i comandi per la terminazione. I metodi startApp() e pauseApp() sono public e non hanno né valore di ritorno, né parametri; al contrario il metodo destroyApp(), oltre ad essere pubblico e non ritornare un valore, dispone di un parametro booleano settato a true se la terminazione della MIDlet è incondizionata, e false se la MIDlet può lanciare una MIDletStateChangeException.

Il listato 1 mostra lo scheletro di una MIDlet, mentre al listato 2 possiamo vedere una piccola applicazione: la visualizzazione sullo schermo di un dispositivo mobile la stringa “Ciao Mondo!”. MY_YouTube A questo punto siamo pronti a definire la nostra applicazione: disponiamo, infatti, di tutta l’attrezzatura. Al listato 3 si pone in evidenza un estratto della nostra applicazione con l’interfaccia verso il comando Search, implementato nel listato 4, di un contenuto multimediale. Le figure 3, 4 e 5 mostrano sul terminale mobile le fasi dell’applicazione. Torneremo in un successivo articolo per definire con maggiore precisione l’implementazione realizzata.

Per gentile concessione di:
rivista firmware

Leave a Reply