Posteado por: albalba | Mayo 28, 2008

Práctica 12

Bienvenidos señoras y señores lectores a la …ÚLTIMA PRÁCTICA DE OCA!!! BIEEEEEEEEEEEEEEEN!!! Ahora tan solo… queda…empollarla….TAN SOLOOOOOOOOOOOOOO!!!

Pues bien, como anécdota comentar que tuvimos que empezar la clase a oscuras jaja, ya que se fue la luz en las aulas y el pasillo pero no en los ordenadores. Al poco tiempo, nuestras plegarias fueron escuchadas XD, Y SE HIZO LA LUZ. Momento en el que, aunque hubiese luz, llegó el infierno.

JMF nos resultó más raro que complicado. Resulta que es otra librería que hay que instalar aparte, e incluso tiene API PROPIO!!!

Lo primero que hicimos fue cotillear el API nuevo, muy parecido al de siempre, pero en el fondo, muy diferente.

Tras esto, para poder utilizarlo, hay que configurarlo en la máquina. Para ello se podía lograr de tres maneras.

Con javac –classpath…. se le dice a la máquina que use este nuevo classpath y se olvide del otro, pero el precio que pagamos es que esta sentencia, sólo vale para un uso del compilador.

En cambio, con la sentencia set CLASSPATH=”.;/ruta completa/jmf.jar;/ruta completa/sound.jar; la ventana se queda configurada mientras se encuentre abierta. En el momento que la cierres y la vuelvas a abrir deberás colocar la sentencia completa de nuevo.

La forma de dejarlo configurado ya para “jamás de los jamases”, es configurarlo en panel de control, bla bla bla, variables de entorno, variables de sistema, como cuando se instala el classpath de java desde cero. Ay (suspiro), aquella época en el que nuestro mayor problema era configurar el java en el ordena de nuestra casa, ay! Bueno, que como ya existe el classpath, le añadimos las nuevas rutas del JMF y santas pascuas.

El objetivo de la práctica, era crear mediante las herramientas que nos ofrece Java Media Framework, un VDCMediaPlayer, vamos, un programa que tenga botones de play, stop,… para el video, y un visualizador.

Para todo esto, hay que utilizar una ventana JFrame de Swing, extraer su contentPane y añadir sus componentes visuales mediante add. Es más fácil leerlo que hacerlo. En el API encontramos lo siguiente sobre él:

 

javax.media
Interface Player

All Known Subinterfaces:

Processor

All Known Implementing Classes:

MediaPlayer



public interface Player

extends MediaHandler, Controller

Player is a MediaHandler for rendering and controlling time based media data. Player extends the Controller interface. Player provides methods for obtaining AWT components, media processing controls, and a way to manage other Controllers.

How a Player Differs from a Controller

Player relaxes some restrictions that a Controller imposes on what methods can be called on a Started Controller. It also provides a way to manage groups of Controllers.

Methods Restricted to Stopped Players

The following methods cannot be invoked on a Started Player. If they are, ClockStartedError is thrown.

  • setTimeBase
  • syncStart
  • deallocate
  • addController
  • removeController

Methods Allowed on Started Players

Unlike a Controller, the following methods are legal on a Player in the Started state:

  • setMediaTime
  • setRate

Invoking these methods on a Started Player might initiate significant and time-consuming processing, depending on the location and type of media being processed. These methods might also cause the state of the Player to change. If this happens, the appropriate TransitionEvents are posted by the Player when its state changes.

For example, a Player might have to enter the Prefetching state to process a setMediaTime invocation. In this case, the Player posts a RestartingEvent, a PrefetchCompleteEvent, and a StartEvent as it moves from the Started state to Prefetching, back to Prefetched, and finally back to the Started state.

Methods that are Illegal on Unrealized Players

As with Controller, it is illegal to call the following methods on an Unrealized Player:

  • getTimeBase
  • setTimeBase
  • setMediaTime
  • setRate
  • setStopTime
  • getStartLatency

It is also illegal to call the following Player methods on an Unrealized Player:

  • getVisualComponent
  • getControlPanelComponent
  • getGainControl
  • addController
  • removeController

The Player throws a NotRealizedError if any of these methods are called while the Player is in the Unrealized state.

Start Method

As a convenience, Player provides a start method that can be invoked before a Player is Prefetched. This method attempts to transition the Player to the Started state from whatever state it’s currently in. For example, if the Player is Unrealized, start implicitly calls realize, prefetch, and Clock.syncStart. The appropriate TransitionEvents are posted as the Player moves through each state on its way to Started.

RestartingEvent

If setMediaTime or setRate cause a perceptible delay in the presentation of the media, the Player posts a RestartingEvent and transitions to the Prefetching state. The previous state and target state of a RestartingEvent is always Started. RestartingEvent is a subclass of StopEvent.

DurationUpdateEvent

Because a Player cannot always know the duration of the media it is playing, the Duration interface defines that getDuration returns Duration.DURATION_UNKNOWN until the duration can be determined. A DurationUpdateEvent is generated when the Player can determine its duration or the if its duration changes, which can happen at any time. When the end of the media is reached, the duration should be known.

Managing other Controllers

In some situations, an application might want to use a single Player to control other Players or Controllers. A single controlling Player can be used to invoke start, stop, setMediaTime, and other methods on the entire group. The controlling Player manages all of the state transitions and event posting.

It is also possible to construct a simple Controller to update animations, report on media time-line progress, or provide other timing-related functions. Such Controllers can operate in sync with a controlling Player.

Adding a Controller

To have a Player assume control over a Controller, use the addController method. A Controller can not be added to a Started  Player. If addController is called on a Started Player, a ClockStartedError is thrown. An Unrealized  or Started;Controller cannot be added to a Player; a NotRealizedError is thrown if the Controller is Unrealized; a ClockStartedError is thrown if the Controller is Started.

Once a Controller has been added, the Player:

  • Invokes setTimeBase on the Controller with the Player's TimeBase. If this fails, addController throws an IncompatibleTimeBaseException.
  • Synchronizes the Controller with the Player using setMediaTime, setStopTime, and setRate.
  • Takes the added Controller's latency into account when computing the Player's start latency. When getStartLatency is called, the Player returns the greater of: its latency before the Controller was added and the latency of the added Controller.
  • Takes the added Controller's duration into account when computing the Player's duration. When getDuration is called, the Player returns the greater of: its duration before the Controller was added and the duration of the added Controller. If either of these values is DURATION_UNKNOWN, getDuration returns DURATION_UNKNOWN. If either of these values is DURATION_UNBOUNDED getDuration returns DURATION_UNBOUNDED.
  • Adds itself as a ControllerListener for the added Controller so that it can manage the events that the Controller generates. (See the Events section below for more information.)
  • Invokes control methods on the added Controller in response to methods invoked on the Player. The methods that affect managed Controllers are discussed below.

Once a Controller has been added to a Player, methods should only be called on the Controller through the managing Player. It is not defined how the Controller or Player will behave if methods are called directly on an added Controller. You cannot place a controlling Player under the control of a Player that it is managing; the resulting behavior is undefined.

When a Controller is added to a Player, the Player does not transition the added Controller to new state, nor does the Player transition itself forward. The Player either transitions back to the realized state if the added Controller is realized or prefetching or it stays in the prefetched state if the both the Player and the added Controller are in the prefetched state. If the Player makes a state transition as a result of adding a Controller the Player posts a TransitionEvent.

Removing a Controller

To stop a Player from managing another Controller, call removeController. The managing Player must be Stopped before removeController can be called. A ClockStartedError is thrown if removeController is called on a Started Player.

When a Controller is removed from a Player's control, the Player:

  • Resets the Controller's TimeBase to its default.
  • Recalculates its duration and posts a DurationUpdateEvent if the Player's duration is different without the Controller added.
  • Recalculates its start latency.

Setting the Media Time and Rate of a Managing Player

When you call setMediaTime on a Player that’s managing other Controllers, its actions differ depending on whether or not the Player is Started. If the Player is not Started, it simply invokes setMediaTime on all of the Controllers it’s managing.

If the Player is Started, it posts a RestartingEvent and performs the following tasks for each managed Controller:

  • Invokes stop on the Controller.
  • Invokes setMediaTime on the Controller.
  • Invokes prefetch on the Controller.
  • Waits for a PrefetchCompleteEvent from the Controller.
  • Invokes syncStart on the Controller

The same is true when setRate is called on a managing Player. The Player attempts to set the specified rate on all managed Controllers, stopping and restarting the Controllers if necessary. If some of the Controllers do not support the requested rate, the Player returns the rate that was actually set. All Controllers are guaranteed to have been successfully set to the rate returned.

Starting a Managing Player

When you call start on a managing Player, all of the Controllers managed by the Player are transitioned to the Prefetched state. When the Controllers are Prefetched, the managing Player calls syncStart with a time consistent with the latencies of each of the managed Controllers.

Calling realize, prefetch, stop, or deallocate on a Managing Player

When you call realize, prefetch, stop, or deallocate on a managing Player, the Player calls that method on all of the Controllers that it is managing. The Player moves from one state to the next when all of its Controllers have reached that state. For example, a Player in the Prefetching state does not transition into the Prefetched state until all of its managed Controllers are Prefetched. The Player posts TransitionEvents normally as it changes state.

Calling syncStart or setStopTime on a Managing Player

When you call syncStart or setStopTime on a managing Player, the Player calls that method on all of the Controllers that it is managing. (The Player must be in the correct state or an error is thrown. For example, the Player must be Prefetched before you can call syncStart.)

Setting the Time Base of a Managing Player

When setTimeBase is called on a managing Player, the Player calls setTimeBase on all of the Controllers it’s managing. If setTimeBase fails on any of the Controllers, an IncompatibleTimeBaseException is thrown and the TimeBase last used is restored for all of the Controllers.

Getting the Duration of a Managing Player

Calling getDuration on a managing Player returns the maximum duration of all of the added Controllers and the managing Player. If the Player or any Controller has not resolved its duration, getDuration returns Duration.DURATION_UNKNOWN.

Closing a Managing Player

When close is called on a managing Player all managed Controllers are closed as well.

Events

Most events posted by a managed Controller are filtered by the managing Player. Certain events are sent directly from the Controller through the Player and to the listeners registered with the Player.

To handle the events that a managed Controller can generate, the Player registers a listener with the Controller when it is added. Other listeners that are registered with the Controller must be careful not to invoke methods on the Controller while it is being managed by the Player. Calling a control method on a managed Controller directly will produce unpredictable results.

When a Controller is removed from the Player's list of managed Controllers, the Player removes itself from the Controller's listener list.

Transition Events

A managing Player posts TransitionEvents normally as it moves between states, but the managed Controllers affect when the Player changes state. In general, a Player does not post a transition event until all of its managed Controllers have posted the event.

Status Change Events

The managing Player collects the RateChangeEvents, StopTimeChangeEvents, and MediaTimeSetEvents posted by its managed Controllers and posts a single event for the group.

DurationUpdateEvent

A Player posts a DurationUpdateEvent when it determines its duration or its duration changes. A managing Player's duration might change if a managed Controller updates or discovers its duration. In general, if a managed Controller posts a DurationUpdateEvent and the new duration changes the managing Player's duration, the Player posts a DurationUpdateEvent

CachingControlEvent

A managing Player reposts CachingControlEvents received from a Players that it manages, but otherwise ignores the events.

ControllerErrorEvents

A managing Player immediately reposts any ControllerErrorEvent received from a Controller that it is managing. After a ControllerErrorEvent has been received from a managed Controller, a managing Player no longer invokes any methods on the managed Controller; the managed Controller is ignored from that point on.

See Also:

Manager, GainControl, Clock, TransitionEvent, RestartingEvent, DurationUpdateEvent, Component



Fields inherited from interface javax.media.Controller

LATENCY_UNKNOWN, Prefetched, Prefetching, Realized, Realizing, Started, Unrealized

 

Fields inherited from interface javax.media.Clock

RESET

 

Fields inherited from interface javax.media.Duration

DURATION_UNBOUNDED, DURATION_UNKNOWN

 

Method Summary

 void

addController(Controller newController)
          Tells the
Player to assume control of another Controller.

 java.awt.Component

getControlPanelComponent()
          Gets the
Component that provides the default user interface for controlling this Player.

 GainControl

getGainControl()
          Gets the object for controlling this
Player's audio gain.

 java.awt.Component

getVisualComponent()
          Gets the display
Component for this Player.

 void

removeController(Controller oldController)
          Tells the
Player to stop controlling a Controller.

 void

start()
          Starts the
Player as soon as possible.

 

Methods inherited from interface javax.media.MediaHandler

setSource

 

Methods inherited from interface javax.media.Controller

addControllerListener, close, deallocate, getControl, getControls, getStartLatency, getState, getTargetState, prefetch, realize, removeControllerListener

 

Methods inherited from interface javax.media.Clock

getMediaNanoseconds, getMediaTime, getRate, getStopTime, getSyncTime, getTimeBase, mapToTimeBase, setMediaTime, setRate, setStopTime, setTimeBase, stop, syncStart

 

Methods inherited from interface javax.media.Duration

getDuration

 

 

 

 

Teníamos constancia, por la clase teórica de Rueda, de que existía la interfaz Player, que contenía los métodos getVisualComponent() y getControlPaneComponent(), los cuales utilizaremos para esta práctica:

 

getControlPanelComponent

public java.awt.Component getControlPanelComponent()

Gets the Component that provides the default user interface for controlling this Player. If this Player has no default control panel, getControlPanelComponent returns null.

Returns:

The default control panel GUI for this Player.

 

 

 

getVisualComponent

public java.awt.Component getVisualComponent()

Gets the display Component for this Player. The display Component is where visual media is rendered. If this Player has no visual component, getVisualComponent returns null. For example, getVisualComponent might return null if the Player only plays audio.

Returns:

The media display Component for this Player.

 

 

 

Para hacernos la vida más fácil también está la clase Manager. Clase que define métodos static y la puedo usar para apoyar el programa.

 

javax.media
Class Manager

java.lang.Object
  |
  +--javax.media.Manager


public final class Manager

extends java.lang.Object

Manager is the access point for obtaining system dependent resources such as Players, DataSources, Processors, DataSinks, the system TimeBase, the cloneable and merging utility DataSources.

A DataSource is an object used to deliver time-based multimedia data that is specific to a delivery protocol.

A Player is an object used to control and render multimedia data that is specific to the content type of the data.

A Processor is an object similar to a Player which is used to process data and output the processed data.

A DataSink is an object that takes a DataSource as input and renders the output to a specified destination.

A DataSource provides a Player, Processor or DataSink with media data; a Player, Processor or DataSink must have a DataSource. Manager provides access to a protocol and media independent mechanism for constructing DataSources, Players, Processors and DataSinks.

Creating Players and DataSources

Manager will createPlayers from a URL, a MediaLocator or a DataSource. Creating a Player requires the following:

  • Obtain the connected DataSource for the specified protocol
  • Obtain the Player for the content-type specified by the DataSource
  • Attach the DataSource to the Player using the setSource method.

Finding DataSources by Protocol

A MediaLocator defines a protocol for obtaining content. DataSources are identified by the protocol that they support. Manager uses the protocol name to find DataSource classes.

To find a DataSource using a MediaLocator, Manager constructs a list of class names from the protocol package-prefix list and the protocol name obtained from the MediaLocator. For each class name in the constructed list a new DataSource is instantiated, the MediaLocator is attached, and the DataSource is connected. If no errors have occurred, the procces is considered finished and the connected DataSource is used by Manager in any following operations. If there was an error then the next class name in the list is tried. The exact details of the search algorithm is described in the method documentation below.

Finding Players by Content Type

A Player is a MediaHandler. A MediaHandler is a an object that reads data from a DataSource. There are three types of supported MediaHandler: MediaProxy, Player and Processor.

MediaHandlers are identified by the content type that they support. A DataSource identifies the content type of the data it produces with the getContentType method. Manager uses the content type name to find instances of MediaHandler.

To find a MediaHandler using a content type name, Manager constructs a list of class names from the content package-prefix list and the content type name. For each class name in the constructed list a new MediaHandler is instantiated, and the DataSource is attached to the MediaHandler using MediaHandler.setSource.

If the MediaHandler is a Player and the setSource was successful the process is finished and the Player is returned. If the setSource failed, another name in the list is tried.

If the MediaHandler is a MediaProxy then a new DataSource is obtained from the MediaProxy, a new list is created for the content type the DataSource supports and the whole thing is tried again.

If a valid Player is not found then the whole procedure is repeated with “unknown” substituted for the content-type name. The “unknown” content type is supported by generic Players that are capable of handling a large variety of media types, often in a platform dependent way.

The detailed creation algorithm is specified in the methods below.

Creating a Realized Player

Versions of createRealizedPlayer calls are provided as an acceleration to create a Player. The returned player is in the Realized state. In addition to NoPlayerException and IOException, CannotRealizeException can be thrown if the Manager cannot realize the Player.

Creating Processors

Processors are created in the same way as Players as outlined above. Manager also provides an additional way to create a Processor via the createRealizedProcessor call. A ProcessorModel is used to fully identify the input and output requirements of a Processor. The createRealizedProcessor call takes a ProcessorModel as input and create a Processor that adheres to the given ProcessorModel. The returned Processor is in the Realized state. The method is a blocking call.

If the Manager fails to find a Processor that fits the ProcessorModel, a NoProcessorException is thrown. If there is a problem creating and realizing a Processor, it will throw an IOException or CannotRealizeException depending on the circumstances.

Creating DataSinks

DataSinks are created from an input DataSource MediaLocator. The MediaLocator identifies the protocol and content of the DataSink to be used. The search for the particular DataSink class to be created is similar to the process of creating a DataSource. The detail search and creation algorithm is described in the method documentation below.

Player and Processor Threads

Players and Processors process media data asynchronously from the main program flow. This implies that a Player or Processor must often manage one or more threads. The threads managed by the Player or Processor are not in the thread group of the application that calls createPlayer or createProcessor.

System Time Base

All Players need a TimeBase. Many use a system-wide TimeBase, often based on a time-of-day clock. Manager provides access to the system TimeBase through getSystemTimeBase.

Cloning and Merging DataSources

DataSources can be cloned or merged. If a DataSource is cloned, more than one MediaHandler can use it as input. Merging more than one DataSources will generate one DataSource which contains all the SourceStreams of the constituent DataSources

The Manager provides two methods: createCloneableDataSource and createMergingDataSource for such purpose.

Manager Hints

Using the setHint method, the preference for how the Manager creates the objects can be specified. However, a particular implementation of the Manager can choose to ignore the requested hints.

Since:

1.0 , new methods added in 2.0

See Also:

MAX_SECURITY, CACHING, LIGHTWEIGHT_RENDERER,

, URL, MediaLocator, PackageManager, DataSource, URLDataSource, MediaHandler, Player, Processor, MediaProxy, TimeBase



Field Summary

static int

CACHING
          Boolean hint to turn on/off the use of playback caching.

static int

LIGHTWEIGHT_RENDERER
          Boolean hint to turn on/off the use of light weight rendering.

static int

MAX_SECURITY
          Boolean hint to turn on/off maximum security.

static int

PLUGIN_PLAYER
          Boolean hint to request the
Manager to create Players that support PlugIns.

static java.lang.String

UNKNOWN_CONTENT_NAME
           

 

Method Summary

static DataSource

createCloneableDataSource(DataSource source)
          Creates a cloneable
DataSource.

static DataSink

createDataSink(DataSource datasource, MediaLocator destLocator)
          Create a
DataSink for the specified input Datasource and destination Medialocator.

static DataSource

createDataSource(MediaLocator sourceLocator)
          Create a
DataSource for the specified media.

static DataSource

createDataSource(java.net.URL sourceURL)
          Create a
DataSource for the specified media.

static DataSource

createMergingDataSource(DataSource[] sources)
          Creates a merged
DataSource from an array of sources.

static Player

createPlayer(DataSource source)
          Create a
Player for the DataSource.

static Player

createPlayer(MediaLocator sourceLocator)
          Create a
Player for the specified media.

static Player

createPlayer(java.net.URL sourceURL)
          Create a
Player for the specified media.

static Processor

createProcessor(DataSource source)
          Create a
Processor for the DataSource.

static Processor

createProcessor(MediaLocator sourceLocator)
          Create a
Processor for the specified media.

static Processor

createProcessor(java.net.URL sourceURL)
          Create a
Processor for the specified media.

static Player

createRealizedPlayer(DataSource source)
          Create a Realized
Player for the specified source.

static Player

createRealizedPlayer(MediaLocator ml)
          Create a Realized
Player for the specified media.

static Player

createRealizedPlayer(java.net.URL sourceURL)
          Create a Realized
Player for the specified media.

static Processor

createRealizedProcessor(ProcessorModel model)
          Create a Realized
Processor for the specified ProcessorModel.

static java.lang.String

getCacheDirectory()
          Retrieve the directory that’s used for playback caching.

static java.util.Vector

getDataSourceList(java.lang.String protocolName)
          Build a list of
DataSource class names from the protocol prefix-list and a protocol name.

static java.util.Vector

getHandlerClassList(java.lang.String contentName)
          Build a list of Player
Handler classes from the content-prefix-list and a content name.

static java.lang.Object

getHint(int hint)
          Retrieve the value of a hint set.

static java.util.Vector

getProcessorClassList(java.lang.String contentName)
          Build a list of Processor
Handler classes from the content-prefix-list and a content name.

static TimeBase

getSystemTimeBase()
          Get the time-base object for the system.

static java.lang.String

getVersion()
          Returns the version string for this revision of JMF.

static void

setHint(int hint, java.lang.Object value)
          Specify a hint for the
Manager to use.

 

Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

 

 

 

 

Como no se puede hacer Player p = new Player(…); ¡¡ERROR!! ya que Player es una interfaz, por lo que nos ayudamos de la clase Manager para crear un objeto Player. Un método que contiene Manager es el createPlayer, al que se le puede pasar por parámetro un DataSource, un MediaLocator o una URL (un fichero local se puede escribir como URL), porque necesita un reproductor de algo.

 

createPlayer

public static Player createPlayer(MediaLocator sourceLocator)
                           throws java.io.IOException,
                                  NoPlayerException

Create a Player for the specified media.

The algorithm for creating a Player from a MediaLocator is:

1.      Get the protocol from the MediaLocator.

2.      Get a list of DataSource classes that support the protocol, using the protocol package-prefix-list.

3.      For each source class in the list:

1.      Instantiate a new DataSource,

2.      Call the connect method to connect the source.

3.      Get the media content-type-name (using getContentType) from the source.

4.      Get a list of MediaHandler classes that support the media-content-type-name, using the content package-prefix-list.

5.      For each MediaHandler class in the list:

1.      Instantiate a new MediaHandler.

2.      Attach the source to the MediaHandler by calling MediaHandler.setSource.

3.      If there are no failures, determine the type of the MediaHandler; otherwise try the next MediaHandler in the list.

4.      If the MediaHandler is a Player, return the new Player.

5.      If the MediaHandler is a MediaProxy, obtain a new DataSource from the MediaProxy, obtain the list of MediaHandlers that support the new DataSource, and continue searching the new list.

6.      If no MediaHandler is found for this source, try the next source in the list.

4.      If no Player is found after trying all of the sources, reuse the source list.
This time, for each source class in the list:

1.      Instantiate the source.

2.      Call the connect method to connect to the source.

3.      Use the content package-prefix-list to create a list of MediaHandler classes that support the “unknown” content-type-name.

4.      For each MediaHandler class in the list, search for a Player as in the previous search.

1.      If no Player is found after trying all of the sources, a NoPlayerException is thrown.

Parameters:

sourceLocator – A MediaLocator that describes the media content.

Returns:

A Player for the media described by the source.

Throws:

NoPlayerException – Thrown if no Player can be found.

java.io.IOException – Thrown if there was a problem connecting with the source.



createPlayer

public static Player createPlayer(DataSource source)
                           throws java.io.IOException,
                                  NoPlayerException

Create a Player for the DataSource.

The algorithm for creating a Player from a DataSource is:

1.      Get the media content-type-name from the source by calling getContentType.

2.      Use the content package-prefix-list to get a list of Player classes that support the media content-type name.

3.      For each Player class in the list:

1.      Instantiate a new Player.

2.      Attach the source to the Player by calling setSource on the Player.

3.      If there are no failures, return the new Player; otherwise, try the next Player in the list.

4.      If no Player is found for this source:

1.      Use the content package-prefix-list to create a list of Player classes that support the “unknown” content-type-name.

2.      For each Player class in the list:

1.      Instantiate a new Player.

2.      Attach the source to the Player by calling setSource on the Player.

3.      If there are no failures, return the new Player; otherwise, try the next Player in the list.

5.      If no Player can be created, a NoPlayerException is thrown.

Parameters:

DataSource – The DataSource that describes the media content.

Returns:

A new Player.

Throws:

NoPlayerException – Thrown if a Player can’t be created.

java.io.IOException – Thrown if there was a problem connecting with the source.

 

createPlayer

public static Player createPlayer(java.net.URL sourceURL)
                           throws java.io.IOException,
                                  NoPlayerException

Create a Player for the specified media. This creates a MediaLocator from the URL and then calls createPlayer.

Parameters:

sourceURL – The URL that describes the media data.

Returns:

A new Player.

Throws:

NoPlayerException – Thrown if no Player can be found.

java.io.IOException – Thrown if there was a problem connecting with the source.

 

 

 

Una URL se compone de protocolo://destino/recurso, en resumen, compañeros tenemos que escribir file://(la ruta completa). No es válido poner “video.mpg” ya que no sigue la sintaxis.

Uno de nuestro errores fue olvidarnos de Manager y de su createPlayer, de tal forma que dijimos implementamos Player y a saco. Pero era muy engorroso, pesado y nos daba bastantes errores al compilar. Hasta que le dijimos: “Profe, ayúdanos, esto no nos sale y nos estamos haciendo la picha un lío”. Son de estas frases típicas made in Spain, que no las piensas y las sueltas sin mas, a lo que él contestó sin ningún enfado (cosa que agradecemos): “Procura no mezclar las palabras profe y picha en la misma frase.”. Ahora lo recordamos y nos reímos, pero pensándolo fríamente…QUE HABRÁ PENSADO EL PROFE!!! Desde este honrado blog, las más sinceras disculpas.

Después de todo este berenjenal, nos ayudó a recordar, percatándonos de que la manera más fácil era escribir Player p = Manager.createPlayer(…);

 

En clase se nos recordó lo explicado en la teoría sobre que un Player tiene varios estados: unrealized, realized, prefetched y started. Realized es el estado en el que se encuentra un player cuando es creado por primera vez y no tiene ningún conocimiento acerca de la fuente de datos de entrada. Por esta razón, tardará un tiempo en arrancar desconocido para nosotros. Por lo que, antes de hacer el getVisualComponent, hay que colocar p.realized(), porque no podemos reservar un tamaño para el video si no sé su tamaño. p.realized() calcula varias cosas. Realized salta al estado “me he dado cuenta” y no puedo llamar al getVisualComponent() antes de pasar a realized. Para saber cuando ocurre llamo a un escuchador de eventos.

Al player le creamos un controllerListener y se lo añadimos al panel.

 

javax.media
Interface ControllerListener

All Known Implementing Classes:

ControllerAdapter



public interface ControllerListener

ControllerListener is an interface for handling asynchronous events generated by Controllers.

Java Beans Support

If implementations of this interface are going to be used with Java Beans they need to also implement either java.util.EventListener or sunw.util.EventListener.

See Also:

Controller



Method Summary

 void

controllerUpdate(ControllerEvent event)
          This method is called when an event is generated by a
Controller that this listener is registered with.

 

Method Detail

controllerUpdate

public void controllerUpdate(ControllerEvent event)

This method is called when an event is generated by a Controller that this listener is registered with.

Parameters:

event – The event generated.

 

 

 

ControllerListener sólo tiene un método, que hay que redefinir en nuestra clase. Éste se lanza cuando ocurre un evento. Es un método para todos los eventos, entonces, dentro del método, hay que distinguir entre los diferentes eventos que nos pueden aparecer. Cuando ocurra un evento llegará un objeto que hereda de MediaEvent.

 

javax.media
Class MediaEvent

java.lang.Object
  |
  +--java.util.EventObject
        |
        +--javax.media.MediaEvent

Direct Known Subclasses:

ControllerEvent, DataSinkEvent, GainChangeEvent, RTPEvent



public class MediaEvent

extends java.util.EventObject

MediaEvent is the base interface for media events.

This is similar to the JMF 1.0 MediaEvent interface, except it’s a class.

Java Beans support

In order to support the Java Beans event model an implementation of MediaEvent is required to sub-class java.util.EventObject. If an implementation is designed to support the 1.0.2 JDK then it may alternatively sub-class sunw.util.EventObject to provide the support appropriate support.

See Also:

Serialized Form



Fields inherited from class java.util.EventObject

source

 

Constructor Summary

MediaEvent(java.lang.Object source)
           

 

 

Methods inherited from class java.util.EventObject

getSource, toString

 

Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

 

Constructor Detail

MediaEvent

public MediaEvent(java.lang.Object source)

 

 

 

 

Podemos hacer un instanceOf de tal forma que si llega un evento, ya se puede actuar, y sacamos el getVisualComponent(). El evento que de verdad nos interesa es RealizeCompleteEvent.

 

javax.media
Class RealizeCompleteEvent

java.lang.Object
  |
  +--java.util.EventObject
        |
        +--javax.media.MediaEvent
              |
              +--javax.media.ControllerEvent
                    |
                    +--javax.media.TransitionEvent
                          |
                          +--javax.media.RealizeCompleteEvent


public class RealizeCompleteEvent

extends TransitionEvent

A RealizeCompleteEvent is posted when a Controller finishes Realizing. This occurs when a Controller moves from the Realizing state to the Realized state, or as an acknowledgement that the realize method was called and the Controller is already Realized.

See Also:

Controller, ControllerListener, Serialized Form



Fields inherited from class java.util.EventObject

source

 

Constructor Summary

RealizeCompleteEvent(Controller from, int previous, int current, int target)
           

 

 

Methods inherited from class javax.media.TransitionEvent

getCurrentState, getPreviousState, getTargetState, toString

 

Methods inherited from class javax.media.ControllerEvent

getSource, getSourceController

 

Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

 

Constructor Detail

RealizeCompleteEvent

public RealizeCompleteEvent(Controller from,
                            int previous,
                            int current,
                            int target)

 

 

 

 

Otra forma de hacerlo es con hilos. Se puede colocar entre el método realized() y el getVisualComponent(), un Thread.sleep(..) a un tiempo, el que se quiera. Este es el camino erróneo, porque con el tiempo que se coloque en el sleep, si cojo tiempo de más, desperdicio tiempo de espera, y si cojo de menos, nos sale el tiro por la culata. Además de que hilos da mucho problemas.

Esta es una mala solución. En lugar de esperar un tiempo arbitrario, lo mejor es programar con el modo de controlar los eventos, el escuchador,… y toda esa parrafada.

 

¡¡CUIDADO!! Advertencia, el formato de video que se puede usar en JMF depende de la versión del JMF instalado. Si se intenta usar uno que no está instalado, saltará una popi excepción, UnableToHandleFormatException, o algo parecido.

 

Teóricamente sabíamos lo que había que hacer, pero después estabas frente al ordenador como si tuvieses un toro delante. Después de intentar implementar la interfaz Player, usamos a Manager. Llegados a este punto, nos perdimos. No sabíamos como seguir. Miramos en el API, le dimos muchas vueltas,… nada sirvió.

No paraban de saltarnos errores. Al principio tonterías de que faltaba importar paquetes. Hasta que llegó un momento que ni comprendimos los errores que salían. Intentamos seguir las instrucciones que se nos explicaron durante la clase, pero no sacábamos nada en claro, tan solo errores.

 

Hay que tener especial cuidado con el control de excepciones. A nosotros nos salieron el famosísimo IOException y MediaException, los cuales eliminamos rápidamente con un try y catch.

 

javax.media
Class MediaException

java.lang.Object
  |
  +--java.lang.Throwable
        |
        +--java.lang.Exception
              |
              +--javax.media.MediaException

Direct Known Subclasses:

BadHeaderException, CannotRealizeException, ClockStoppedException, IncompatibleSourceException, IncompatibleTimeBaseException, NoDataSinkException, NoDataSourceException, NoPlayerException, ResourceUnavailableException, UnsupportedFormatException, UnsupportedPlugInException



public class MediaException

extends java.lang.Exception

A MediaException indicates an unexpected error condition in a JMF method.

See Also:

Serialized Form



Constructor Summary

MediaException()
           

 

MediaException(java.lang.String reason)
           

 

 

Methods inherited from class java.lang.Throwable

fillInStackTrace, getLocalizedMessage, getMessage, printStackTrace, printStackTrace, printStackTrace, toString

 

Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

 

 

 

 

No logramos programar la clase.

Cuando terminó la hora, una compañera nos ayudó muuuuuuuuuuuuuuuuucho. Ella nos explicó que debíamos hacer para resolverlo. Lo resolvió como decía el profe, como nosotros intentamos, pero hay veces que te atascas y no sale ni para atrás. Aun así, nos pareció una práctica muy rara más que complicada. Es que es como siempre, una vez que la ves hecho lo entiendes, pero sino, no sabes. Esperamos que con lo que aprendimos en el aula y con la ayuda de nuestra compi ahora seamos capaces de resolver los JMF.

 

PUES AHORA TOCA DESPEDIRSE…L

Hacer el blog ha sido de una gran ayuda. Nos dábamos cuenta, a la hora de intentar explicar las cosas, qué no sabíamos y qué debíamos estudiar más. Además del pique que nos traíamos para ver quien de la clase colgaba primero la práctica jaja, hubo gente que la colgó a la media hora de empezar la clase, sin ni si quiera acabar jaja.

Leer los blogs de los compañeros también ayuda bastante pero eso de dejarles comentarios, se nos olvidaba siempre la verdad.

 

El último post que colguemos será, seguramente para dar nuestras impresiones sobre el juego, y quizá, por qué no, sobre la asignatura. Quién sabe que futuro llegará a tener este blog.

HASTA PRONTO!!! J


Dejar una respuesta

Su respuesta:

Categorías