Current Page: Greybox » Authoring » Course ID: medieninformatik » Modules » Module ID: m06 » Learning Units » Unit ID: 3_02
Last Modified:Tuesday, 2015-05-05 - 08:09:02
 
Tools: ValidatePreview XML Preview HTML Preview PDF
Alternative: Printable HTML

 

Learning Unit ID: 3_02
Title: Echtzeiterfassung mit JMF - Capturing
Abstract: In dieser LU wird das Erfassen von Echtzeitdaten mit Hilfe von JMF präsentiert. Dabei wird sowohl das Audio- wie auch das Videocapturing durch Code-Beispiele erläutert. Außerdem wird auf das JMF Ereignismodell eingegangen.
 
Status:

 

Version: 7.1
History:

Acronyme und Wordanführungszeichen done.

Reschtschreibung gecheckt.

Unbekannte Character ausgebessert.

Sourcecode repariert.

Sourcecode formatiert.


Author
Author 1: Bernhard Tatzmann E-Mail: bernhard@isys.uni-klu.ac.at
Author 2: (empty) E-Mail: (empty)
Author 3: (empty) E-Mail: (empty)
Author 4: (empty) E-Mail: (empty)
Author 5: (empty) E-Mail: (empty)
Organization: Universität Klagenfurt - Institut für Informatik-Systeme

Content

Einleitung

1

Auto

  • JMF ermöglicht es:
    • analoge Daten in Echtzeit zu erfassen
    • anschließend zu bearbeiten
    • darzustellen (zu "rendern") / zu speichern

 

 

  • JMF Registry Editor:
    • Capture Device muss hier eingetragen werden
    • Ist in der Installation des JMF464 Performance Pack (siehe Das Java Media Framework) enthalten
    • Hinzufügen eines an das System angeschlossenen Devices über die Schaltfläche "Detect Capture Devices" in der Karteikarte "Capture Devices"

JMF Registry Editor PC

Um ein Capture Device ansprechen zu können muss es im JMF Registry Editor aufscheinen

JMF Registry Editor PDA_Phone

Um ein Capture Device ansprechen zu können muss es im JMF Registry Editor aufscheinen

Der CaptureDeviceManager

Ansprechen von eingetragenen Devices über die Methoden der Klasse CaptureDeviceManager:

  • Erstellung eines CaptureDeviceInfo Objekts durch CaptureDeviceManager.getDevice(String deviceName)
  • Objekt enthält alle unterstützten Formate der Quelle
  • Zur Erzeugung eines Player oder Processor Objekts ist ein MediaLocator Objekt nötig
  • Erhält man durch Anwenden der getLocator Methode auf das erhaltene Informationsobjekt:

Erzeugen eines Player Objekts mit Hilfe einer Erfassungsquelle

Capture DeviceInfo dev_info = CaptureDeviceManager.getDevice(device_name);
Player player = Manager.createRealizedPlayer(dev_info.getLocator());

Auto

Ist kein Device-Name bekannt:

  • CaptureDeviceManager.getDeviceList(Format format) erzeugt einen Vektor, der die Informationsobjekte aller registrierten Devices enthält, die das angegebene Format unterstützen.
  • Bsp.:
    • Ausgabe aller registrierten Geräte mit
      • linearem Encoding
      • 44,1 kHz Abtastrate (engl.: sample rate)
      • 16 Bit Abtastgröße (engl.: sample size)
      • 2 Kanälen

Abfrage von registrierten Quellen

Vector device_list = CaptureDeviceManager.getDeviceList(
                        new AudioFormat("linear", 44100, 16, 2));

2

Auto

Mittels JMF464 ist es möglich, analoge Daten in Echtzeit zu erfassen, anschließend zu bearbeiten und schließlich darzustellen (zu "rendern") oder zu speichern. JMF464 unterstützt eine Vielzahl von Audio und Videoquellen, die zur Erfassung verwendet werden können (http://java.sun.com/products/java-media/jmf/2.1.1/formats.html). Während Audio Daten über Soundkarten und Mikrofone erfasst werden können, werden ebenso diverse Video Erfassungskomponenten (engl.: Capturing Devices) wie z.B. Webcams für die Erfassung von Video Daten unterstützt.

Um ein Capture Device unter JMF464 ansprechen zu können, muss es im JMF464 Registry Editor (siehe Abb. JMF464 Registry Editor) eingetragen werden. Dieses Werkzeug ist in der Installation des JMF464 Performance Pack (siehe Das Java Media Framework) enthalten. Das Hinzufügen eines an das System angeschlossenen Devices erfolgt über die Schaltfläche "Detect Capture Devices" in der Karteikarte "Capture Devices".

JMF Registry Editor PC

Um ein Capture Device ansprechen zu können muss es im JMF Registry Editor aufscheinen

JMF Registry Editor PDA_Phone

Um ein Capture Device ansprechen zu können muss es im JMF Registry Editor aufscheinen

Der CaptureDeviceManager

Wurde ein Device gefunden, so kann es nun über die Methoden der Klasse CaptureDeviceManager angesprochen werden:

  • Wenn der Name eines bestimmten Devices bekannt ist, kann zunächst mit der statischen Methode CaptureDeviceManager.getDevice(String deviceName) ein CaptureDeviceInfo Objekt des angegebenen Eingabegeräts angefordert werden. Dieses Objekt enthält alle unterstützten Formate der Quelle. Zum Erzeugen eines Player oder Processor Objekts (siehe Das Java Media Framework) ist jedoch ein MediaLocator Objekt nötig. Dieses erhält man durch Anwenden der getLocator Methode auf das erhaltene Informationsobjekt:

Erzeugen eines Player Objekts mit Hilfe einer Erfassungsquelle

Capture DeviceInfo dev_info = CaptureDeviceManager.getDevice(device_name);
Player player = Manager.createRealizedPlayer(dev_info.getLocator());

Auto

  • Ist der Name nicht bekannt, kann mit der Methode CaptureDeviceManager.getDeviceList(Format format) ein Vektor erzeugt werden, der die Informationsobjekte aller registrierten Devices enthält, die das angegebene Format unterstützen. Ein möglicher Aufruf wäre z.B.:

Abfrage von registrierten Quellen

Vector device_list = CaptureDeviceManager.getDeviceList(
                        new AudioFormat("linear", 44100, 16, 2));

Auto

Hier werden alle registrierten Geräte ausgegeben, die ein Audioformat mit linearem Encoding, 44,1 kHz Abtastrate (engl.: sample rate), 16 Bit Abtastgröße (engl.: sample size) und 2 Kanälen unterstützen.

Erfassung von Audiodaten

1

Auto

  • Applet zum Erfassen und Wiedergeben von Audiodaten zu erstellen, die durch ein Mikrofon geliefert werden
    • Verwendung der GUI404 Kontrollkomponenten des Player Objekts (player.getControlPanelComponent())

Erfassung von Audiodaten

   //Suche das erste verfügbare Capture Device, das das angegebene Format
   //unterstützt
   java.util.Vector device_list = CaptureDeviceManager.getDeviceList(
   new AudioFormat("linear", 44100, 16, 2));
   CaptureDeviceInfo dev_info =
      (CaptureDeviceInfo) device_list.firstElement();
   //Erzeuge einen realized Player mit Hilfe der CaptureDeviceInfo 
   player = Manager.createRealizedPlayer(dev_info.getLocator());
   //Füge die Kontrollkomponenten des Players zum GUI hinzu
   setLayout(new GridLayout(1, 1));
   add(player.getControlPanelComponent());

Erfassung von Audiodaten

Verwendung des Applets

2

Auto

Mit Hilfe oben genannter Funktionen ist es nun möglich, ein Applet zum Erfassen und Wiedergeben von Audiodaten zu erstellen, die durch ein Mikrofon geliefert werden. Zum Steuern der Wiedergabe werden dem GUI404 noch die Kontrollkomponenten des Player Objekts (player.getControlPanelComponent ()) hinzugefügt:

Erfassung von Audiodaten

import javax.media.*;
import java.awt.*;
import java.applet.*;
import java.net.URL;
import javax.media.format.AudioFormat;
public class AudioCapturer
 extends Applet {
  private Player player = null;
  public void init() {
    try {
      //Suche das erste verfügbare Capture Device, das das angegebene Format
      //unterstützt
      java.util.Vector device_list = CaptureDeviceManager.getDeviceList(
      new AudioFormat("linear", 44100, 16, 2));
      CaptureDeviceInfo dev_info =
        (CaptureDeviceInfo) device_list.firstElement();
      //Erzeuge einen realized Player mit Hilfe der CaptureDeviceInfo 
      player = Manager.createRealizedPlayer(dev_info.getLocator());
    }
    catch (Exception e) {
      System.out.println(e.toString());
    }
    //Füge die Kontrollkomponenten des Players zum GUI hinzu
    setLayout(new GridLayout(1, 1));
    add(player.getControlPanelComponent());
  }
  public void processEvent(AWTEvent e) {
    if (e.getID() == Event.WINDOW_DESTROY) {
    player.stop();
    System.exit(0);
    }
  }
  public static void main(String args[]) {
    Frame f = new Frame("MyMediaPlayer");
    AudioCapturer player = new AudioCapturer();
    player.init();
    player.start();
    f.add("Center", player);
    f.setSize(400, 30);
    f.show();
  }
}

Erfassung von Audiodaten

Verwendung des Applets

Nach klicken des Play-Buttons werden die Audiodaten des am System angeschlossenen Mikrofons über die Lautsprecher wieder ausgegeben. Zur Verwendung des Applets ist eine lokale Installation des Java Media Frameworks(http://java.sun.com/products/java-media/jmf/2.1.1/download.html) nötig.

 

Erfassung von Videodaten

1

Auto

  • Zur Erfassung von Videodaten, sind im Wesentlichen dieselben Schritte wie oben notwendig
  • Zusätzlich: Hinzufügen der visuellen Komponente des Player (player.getVisualComponent()) Objekts zum GUI404

Erfassung von Videodaten

   //Suche das erste verfügbare Capture Device, das das angegebene Video
   //Format unterstützt
   java.util.Vector device_list = CaptureDeviceManager.getDeviceList(new
   javax.media.format.RGBFormat());
   CaptureDeviceInfo dev_info =
      (CaptureDeviceInfo) device_list.firstElement();
   
   //Erzeuge einen realized Player mit Hilfe der CaptureDeviceInfo 
   player = Manager.createRealizedPlayer(dev_info.getLocator());
   setLayout(new BorderLayout());
   //Füge die visuellen Komponenten des Players zum GUI hinzu
   add(player.getVisualComponent(), BorderLayout.CENTER);
   add(player.getControlPanelComponent(), BorderLayout.SOUTH);

Erfassung von Videodaten

Verwendung des Applets

2

Auto

Um die Daten einer gewählten Video-Eingabequelle am Bildschirm darzustellen, sind im Wesentlichen dieselben Schritte wie oben notwendig. Zusätzlich ist es nötig, dem GUI404 die visuelle Komponente des Player (player.getVisualComponent()) Objekts hinzuzufügen. Ein Applet, das Videodaten von einer Webcam in Echtzeit im Browser darstellt, könnte folgendermaßen aussehen:

Erfassung von Videodaten

import javax.media.*;
import java.awt.*;
import java.applet.*;
import java.net.URL;
public class VideoCapturer
 extends Applet {
  private Player player = null;
  public void init() {
    try {
      //Suche das erste verfügbare Capture Device, das das angegebene Video
      //Format unterstützt
      java.util.Vector device_list = CaptureDeviceManager.getDeviceList(new
      javax.media.format.RGBFormat());
      CaptureDeviceInfo dev_info =
        (CaptureDeviceInfo) device_list.firstElement();
   
      //Erzeuge einen realized Player mit Hilfe der CaptureDeviceInfo 
      player = Manager.createRealizedPlayer(dev_info.getLocator());
    }
    catch (Exception e) {
      ;
    }
    setLayout(new BorderLayout());
    //Füge die visuellen Komponenten des Players zum GUI hinzu
    add(player.getVisualComponent(), BorderLayout.CENTER);
    add(player.getControlPanelComponent(), BorderLayout.SOUTH);
  }
  public void processEvent(AWTEvent e) {
    if (e.getID() == Event.WINDOW_DESTROY) {
      player.stop();
      System.exit(0);
    }
  }
  public static void main(String args[]) {
    Frame f = new Frame("MyMediaPlayer");
    VideoCapturer player = new VideoCapturer();
    player.init();
    player.start();
    f.add("Center", player);
    f.setSize(400, 300);
    f.show();
  }
}

Erfassung von Videodaten

Verwendung des Applets

Nach klicken des Play-Buttons wird das Videobild einer an das System angeschlossenen Webcam über den Bildschirm ausgegeben. Zur Verwendung des Applets ist eine lokale Installation des Java Media Frameworks(http://java.sun.com/products/java-media/jmf/2.1.1/download.html) nötig.

Abspeichern von Echtzeitdaten

1

Auto

Zum Abspeichern der erfassten Daten in einer Datei ist statt einem Player ein Processor nötig:

Vorgangsweise:

Erzeugung eines DataSource Objekts und eines Processors

DataSource source = Manager.createDataSource(dev_info.getLocator());
Processor processor = Manager.createProcessor(source);

Konfiguration der Prozessors

processor.configure();
//Wait until processor is configured
Thread.sleep(2000);

Auswahl des Datenausgabeformats

ContentDescriptor descr =
   new FileTypeDescriptor(FileTypeDescriptor.QUICKTIME);
processor.setContentDescriptor(descr);

Realisieren Processors

processor.realize();
//Wait until processor is realized
Thread.sleep(2000);

Erzeugen der Datensenke zum Abspeichern der Daten

MediaLocator destination = new MediaLocator("file://test.mov");
sink = Manager.createDataSink(processor.getDataOutput(),destination);

Öffnen der Datensenke und Initiierung des Datentransfers

sink.open();
sink.start();
processor.start();

Stoppen des Ausgangsdatenstroms und schließen der Datensenke (Reihenfolge!)

processor.stop();
processor.close();
sink.close();

Anwendung des JMF Ereignismodells

  • Ereignisbehandlungssystem:
    • Informiert alle JMF464 Objekte über den aktuellen Status des Mediensystems
    • Ermöglicht unter Anderem das Reagieren auf Fehlerereignisse
    • Bsp.:
      • Ausfallen von Datenquellen
    • JMF464 Objekte machen auf Ereignisse durch senden von MediaEvent Objekten aufmerksam
      • Zur Behandelung solcher Ereignisse ist Implementierung des entsprechenden Listener Interfaces nötig
      • Außerdem ist Listener bei jenem Objekt zu registrieren , das das Ereignis "empfängt"

Auto PC

Klassenhierarchie des JMF Ereignismodells

Auto PDA_Phone

Klassenhierarchie des JMF Ereignismodells

Auto

Ergänzungen zu obigem Beispiel durch DataSinkListener Objekt:

Auto
public class ...
 implements DataSinkListener {
  ...
  sink = Manager.createDataSink(processor.getDataOutput(), destination);
  sink.addDataSinkListener(this);
  sink.open();
  ...
  public synchronized void dataSinkUpdate(DataSinkEvent event) {
    if (event instanceof DataSinkErrorEvent) {
      ...
    }
    else if (event instanceof EndOfStreamEvent) {
      ...
    }
  }

  ...

2

Auto

Bisher wurden die erfassten Daten nur in Echtzeit dargestellt, jedoch nicht gespeichert. Um die erfassten Daten in einer Datei abspeichern zu können, ist statt dem oben verwendeten Player Objekt eine Processor Instanz nötig. Im Folgenden werden die nötigen Schritte anhand eines Beispiels erläutert.

  • Es wird wiederum die getLocation Methode auf das Informationsobjekt der Datenquelle angewendet, um ein DataSource Objekt zu erhalten, das dem Prozessor übergeben wird:

Auto

DataSource source = Manager.createDataSource(dev_info.getLocator());
Processor processor = Manager.createProcessor(source);

Auto

  • Anschließend muss der Prozessor noch konfiguriert werden:

Auto

processor.configure();
//Wait until processor is configured
Thread.sleep(2000);

Auto

  • Um das Datenausgabeformat zu wählen, muss die Methode setContentDescriptor auf den Prozessor angewendet werden:

Auto

ContentDescriptor descr =
   new FileTypeDescriptor(FileTypeDescriptor.QUICKTIME);
processor.setContentDescriptor(descr);

Auto

  • Anschließend muss der Processor realisiert werden:

Auto

processor.realize();
//Wait until processor is realized
Thread.sleep(2000);

Auto

  • Als nächstes muss die Datensenke zum Abspeichern der Daten erzeugt werden. Beim Erzeugen wird eine Datenquelle und ein Ziel angegeben werden. Mit der Methode getDataOutput erhält man die Ausgabequelle des Prozessors. Als Ziel wird ein MediaLocator Objekt angegeben, das auf eine Datei verweist:

Auto

MediaLocator destination = new MediaLocator("file://test.mov");
sink = Manager.createDataSink(processor.getDataOutput(),destination);

Auto

  • Öffnen der Datensenke, Initiierung des Datentransfers der Datensenke und des Processors durch Aufruf der Methode start():

Auto

sink.open();
sink.start();
processor.start();

Auto

  • Soll die Aufnahme beendet werden, so muss zunächst der Ausgangsdatenstrom seitens des Prozessors gestoppt werden. Erst danach darf die Datensenke geschlossen werden. Wird diese Reihenfolge nicht eingehalten, so kann es zum Speichern fehlerhafter Daten kommen. Dies geschieht, wenn die Datensenke vor dem Prozessor geschlossen wird. In diesem Fall schreibt die Senke unter Umständen eine falsche Datenlänge in den Datei-Header, da ihr noch nicht bekannt ist, wann der Prozessor gestoppt wird.

Auto

processor.stop();
processor.close();
sink.close();

Anwendung des JMF Ereignismodells

JMF464 verfügt über ein Ereignisbehandlungssystem, das alle JMF464 Objekte über den aktuellen Status des Mediensystems informiert JS04. Es ermöglicht unter Anderem das Reagieren auf Fehlerereignisse wie das Ausfallen von Datenquellen. Sollte im obigen Programm beispielsweise ein Problem beim Schreiben in die Datensenke auftreten oder die Datensenke keine Daten mehr erhalten, so ist es möglich auf diese Ereignisse zu reagieren.

JMF464 Objekte machen auf Ereignisse durch senden von MediaEvent Objekten aufmerksam. Von der Klasse MediaEvent leiten sich die Klassen ControllerEvent und DataSinkEvent ab (siehe Abb. Klassenhierarchie des JMF464 Ereignismodells). Um solche Ereignisse behandeln zu können ist es nötig, das entsprechende Listener Interface zu implementieren sowie den Listener bei jenem Objekt zu registrieren, das das Ereignis "empfängt".

Auto PC

Klassenhierarchie des JMF Ereignismodells

Auto PDA_Phone

Klassenhierarchie des JMF Ereignismodells

Auto

Im Folgenden werden die nötigen Ergänzungen zu obigem Beispiel für ein DataSinkListener Objekt skizziert:

Auto
public class ...
 implements DataSinkListener {
  ...
  sink = Manager.createDataSink(processor.getDataOutput(), destination);
  sink.addDataSinkListener(this);
  sink.open();
  ...
  public synchronized void dataSinkUpdate(DataSinkEvent event) {
    if (event instanceof DataSinkErrorEvent) {
      ...
    }
    else if (event instanceof EndOfStreamEvent) {
      ...
    }
  }
  ...

Zusammenfassung

2

Auto

In dieser LU wurden die Grundlagen zur Erfassung von Audio und Videodaten mittels JMF464 eingeführt. Zur Illustration dieser Funktionalitäten wurden zwei Applets präsentiert, die Audio- bzw. Videodaten erfassen und über Lautsprecher bzw. über den Bildschirm wieder ausgeben. Außerdem wurde das Abspeichern von Echtzeitdaten in JMF464, sowie das JMF464 Ereignismodell erläutert.

Bibliographie

2

Auto

AG04

ED04

JS04


Notes
(empty)