S3ldonPress

JMF in un applet

Posted on | maggio 31, 2009 | 8 Comments

Qualche settimana fa lavorando alla mia tesi sono incappato in un problema che mi ha tenuto fermo per qualche giorno. Cercando in giro per la rete mi sono accorto che non è un problema di pochi ma di soluzioni praticamente non si vede traccia. Io dopo vari tentativi sono riuscito a risolvere. Vediamo di che si tratta.

JMF (Java Media Framework) è appunto un framework che permette di integrare vari media (per es. video e audio, ma anche streaming rtp) in applicazioni Java. Il primo problema che si incontra nell’utilizzo di JMF sta nel fatto che il supporto è stato abbandonato dalla Sun anni orsono e dunque JMF si presenta come un utile supporto per applicazioni multimediali ma allo stesso tempo è estremamente vecchio poichè i codec multimediali supportati risalgono all’età della pietra. Come spesso accade in questi casi è la comunità open source a farsi carico del problema. Infatti in giro si trovano varie soluzioni ed estensioni che permettono di utilizzare JMF con librerie native, per es. di utilizzare JMF con ffmpeg, ossia di essere in grado di leggere i più comuni formati e codec multimediali. Per il mio progetto la scelta è caduta su FOBS ma si potrebbe utilizzare tranquillamente anche FMJ. Una volta aggiunti i codec giusti a JMF mediante il JMFRegistry viene modificato il file jmf.properties che conterrà le informazioni per caricare i giusti codec. Bene, una volta fatto ciò non hanno più problemi ad utilizzare JMF con qualsivoglia media.

La mia necessità era di integrare il player che sto realizzando in un applet, all’interno di una pagina web. Ora, utilizzando Eclipse e avviando l’applet da lì non avevo nessun tipo di problema, tutto funzionava correttamente. Nel momento in cui però andavo ad integrare il codice dell’applet in una pagina html non funzionava una mazza. Perchè? Perchè l’applet non riusciva a caricare il giusto file jmf.properties e ne creava uno di default con i codec base di JMF. Come fare a far caricare la giusta configurazione? Dopo giorni, grazie anche e soprattutto all’aiuto e alla disponibilità di Werner, sono arrivato al dunque. Vediamo come. Come prima cosa occorre posizionare il file jmf.properties nello stesso path del file .class dell’applet. Dopodichè si può utilizzare la seguente classe,di cui riporto per intero il codice, per inizializzare correttamente JMF:

/*
 * Copyright 2009 Markus Koller
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.OptionalDataException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import com.sun.media.util.Registry;

/**
 * Helps initializing JMF from a JMF.properties file not on the root of the classpath.
 * This also works for webstart!
 * @author Markus Koller
 */
public class JMFInitializer {
 public static void initJMF(URL url) throws IOException {
 InputStream in = null;
 try {
 in = url.openStream();
 if (in == null) {
 throw new IllegalArgumentException("No such jmf properties file: " + url);
 }
 readJMFRegistry(in);
 } finally {
 if (in != null) {
 try {
 in.close();
 } catch (IOException e) {}
 }
 }
 }

 private static void readJMFRegistry(InputStream ris) throws IOException {
 ObjectInputStream ois = null;
 try {
 ois = new ObjectInputStream(ris);

 int tableSize = ois.readInt();
 int version = ois.readInt();
 if (version > 200) {
 System.err.println("Version number mismatch. There could be errors in reading the registry");
 }
 HashMap<String, Object> hash = new HashMap<String, Object>();
 for (int i = 0; i < tableSize; i++) {
 String key = ois.readUTF();
 try {
 Object value = ois.readObject();
 hash.put(key, value);
 } catch (ClassNotFoundException e) {
 throw new RuntimeException("Class not found for jmf registry entry", e);
 } catch (OptionalDataException e) {
 throw new RuntimeException("Invalid jmf properties content", e);
 }
 }
 for (Map.Entry<String, Object> entry : hash.entrySet()) {
 Registry.set(entry.getKey(), entry.getValue());
 }
 } finally {
 if (ois != null) {
 try {
 ois.close();
 } catch (IOException e) {}
 }
 }
 }
}

Tale classe va richiamata nell’init() dell’applet prima di creare il player JMF in questo modo:

JMFInitializer.initJMF(this.getClass().getResource("jmf.properties"));

Bene ora l’applet inizializzerà correttamente JMF e caricherà i codec giusti dal file .properties. A questo punto potreste incappare in un altro problema, problema relativo alle restrizioni di sicurezza dell’applet. Infatti c’è da ricordare che un applet gode di restrizioni di sicurezza per evitare che applicazioni malevoli possano commettere atti impuri. Per evitare tali restrizioni è buona norma quella di firmare digitalmente l’applet. Per sapere come fare vi rimando a questa guida.

Se avete problemi non esitate a contattarmi e per quel che posso proverò a darvi una mano.

 

Similar Posts:

Easy AdSense by Unreal

Comments

8 Responses to “JMF in un applet”

  1. billigflug
    giugno 12th, 2009 @ 10:32

    Great article and Great article and interesting website.

  2. Anonimo
    giugno 12th, 2009 @ 21:58

    Ciao sono Enrico,
    ho letto Ciao sono Enrico,
    ho letto il tuo articolo, l’ho trovato interessante e volevo provare a far funzionare il codice ma non riesco ad installare FOBS, nel senso che , seguo le istruzioni del sito, ma non mi fà aggiungere niente come plugin e via dicendo….hai qualche consiglio da darmi a proposito. Ti ringrazio e buona giornata

  3. s3ldon
    giugno 13th, 2009 @ 01:53

    ti consiglio di scaricare il ti consiglio di scaricare il pacchetto di FOBS già compilato per Linux, lo trovi a questo indirizzo http://sourceforge.net/project/downloading.php?group_id=105646&filename=fobs4jmf-0.4.1-ubuntu-edgy.tar.gz&a=11503287
    scompattalo e avrai tutto a disposizione, nel senso che puoi utilizzare il file jmf.properties che trovi nel pacchetto e che include la configurazione per i codec di ffmpeg di FOBS.
    Una cosa che ho dimenticato di scrivere nell’articolo e che aggiungerò è che devi anche copiare il file libfobs4jmf.so in nel library_path di java che trovi al path della tua jre nella cartella /lib/i386.
    Fammi sapere se ti funziona

  4. Enrico
    giugno 13th, 2009 @ 10:50

    x Windows Scusa l’insistenza ma per windows la cosa funziona in maniera analoga. Nel senso sovrascrivo il jmf properties e le per le lib le metto sotto il library_path???
    Grz

  5. s3ldon
    giugno 13th, 2009 @ 11:07

    non l’ho mai provato per non l’ho mai provato per windows però immagino che sia esattamente la stessa cosa. Ma che tipo di problema hai?

  6. Enrico
    giugno 13th, 2009 @ 11:37

    Devo cercare di leggere dei Devo cercare di leggere dei file con codec h.264 da un applet. Di base JMF non lo permette, quindi ho cercato un pò in giro kme fare e la tua soluzione mi cade a pennello.
    Ora ho scaricato questo pacchetto per Windows http://sourceforge.net/project/showfiles.php?group_id=105646&package_id=117443&release_id=619671 e ho provato ad eseguire le istruzioni del sito http://fobs.sourceforge.net/.
    Per testare la cosa sto cercando di far leggere il file da JMFStudio ma continua a dirmi formato non riconosciuto.
    Il punto è ke all’interno del pacchetto scaricato c’è un file Fobs_jmstudio, ke credo mi emuli JMFStudio, ke legge il file in questione.

    Ora, ho sovrascritto il file properties e mi vede, in registry, i plugin ma lo stesso JMF nn mi legge il video….
    Puoi aiutarmi in qualke modo???
    Grz x quello fatto fin ora

  7. s3ldon
    giugno 13th, 2009 @ 11:48

    hai aggiunto nel classpath hai aggiunto nel classpath dell’applet il file fobs4jfm.jar? ricorda che l’applet da pagina web legge soltanto file jar, quindi anche le tue classi contenenti l’applet devono essere messe in un pacchetto jar e poi passate come parametro all’applet. Per spiegarmi meglio, mettiamo che tu hai 10 classi e l’applet vera è propria sta nella classe appletEsempio.class. Nel file HTML che vai a scrivere, l’applet deve essere caricata così:

    applet CODE=”appletEsempio.class” ARCHIVE=”tueClassi.jar,jmf.jar,fobs4jmf.jar” width=”100%” height=”100%”

    Ricordati che per far caricare il giusto jmf.properties questo deve stare nel pacchetto tueClassi.jar, nello stesso path di appletEsempio.

    In tutti i casi ti consiglio quando carichi l’applet, di mostrare la console di java in modo da poter sapere precisamente quale errore viene chiamato

  8. Enrico
    giugno 13th, 2009 @ 12:21

    Ti ringrazio… farò un pò Ti ringrazio… farò un pò di prove e ti farò sapere.
    Buona giornata e ankora grazie

Leave a Reply





  • Meta

  • Archivi

  • Similar Posts

  • Articoli recenti

  • Commenti recenti

  • Tag

  • Visitors Online

  • Blog sotto licenza Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License
    Creative Commons License