Clase “Receptor”:
	
Esta clase se utiliza para ser heredada por otra clase que implemente una recepción RTP ya que implementa los métodos necesarios y que son independientes de las particularidades de cada receptor (origen, destino, tipo de datos).

Constantes de la clase:
	protected static final int BUFFERLEN = 100;
		- almacena el valor del tamaño del buffer de recepción en milisegundos.

Variables miembro:
protected Target destino;
- Guarda la configuración de puertos del programa, dependiendo del tipo de recepción, se utilizará unos puertos u otros.
protected RTPManager rtpManager;
- Guarda el manejador RTP que permite la comunicación.
private PlayerWindow playerWindow;
- Guarda la ventana de reproducción que se utilizará para reproducir lo que se reciba.
private Object dataSync;
- Objeto utilizado para llevar a cabo la sincronización.
private boolean dataReceived;
- Indica si se han recibido datos.

Constructor de la clase:
	Inicializa las variables miembro de la clase.
public Receptor(Target destino)
{
	//inicializamos las variables
	System.out.println(Misc.ind() + "Inicializando variables");
	this.destino = destino;
	playerWindow = null;
	dataSync = new Object();
	dataReceived = false;
}

Métodos de la clase:
close():
	Cierra el reproductor y libera los recursos asociados a este:
protected void close()
{
	System.out.println(Misc.ind() + "Cerrando ventana de reproduccion");
	//cerramos la ventana de reproduccion
	try { playerWindow.close(); }
	catch (Exception e) {}
	//cerramos todos el destino del manejador RTP
	System.out.println(Misc.ind() + "Cerrando sesion de recepcion");
	rtpManager.removeTargets("Cerrando sesion de recepcion");
	//eliminamos el manejador RTP
	rtpManager.dispose();
	rtpManager = null;
}

controllerUpdate():
	Este método se ejecuta cada vez que se actualiza el controlador e inicializa la ventana de ejecución y la hace visible:
public synchronized void controllerUpdate(ControllerEvent ce)
{
	//creamos un reproductor
	Player p = (Player)ce.getSourceController();
	if (p == null)
		return;
	//si el evento está completamente generado
	if (ce instanceof RealizeCompleteEvent)
	{
		//inicializamos la ventana de reproduccion
		PlayerWindow pw = playerWindow;
		if (pw == null)
		{
			System.err.println(Misc.ind() + "Error interno");
			System.exit(-1);
		}
		pw.initialize();
		//visualizamos la ventana de reproduccion
		pw.setVisible(true);
		//iniciamos el reproductor
		p.start();
	}
	//si hay un evento de error del controlador
	if (ce instanceof ControllerErrorEvent)
	{
		//eliminamos el ControllerListener
		p.removeControllerListener(this);
		//cerramos la ventana de reproduccion
		PlayerWindow pw = playerWindow;
		if (pw != null)
		{
			pw.close();
			playerWindow = null;
		}
			System.err.println(Misc.ind() + "Error Interno de recepcion: " + ce);
	}
}

update():
	Hay 3 métodos update(), el primero se ejecuta al producirse un evento remoto mostrando la información en el log del programa:
public void update(RemoteEvent event)
{
	//si se trata de un informe de entrega
	if (event instanceof ReceiverReportEvent)
	{
		//cogemos el informe
		ReceiverReport rr = ((ReceiverReportEvent) event).getReport();
		//creamos un buffer
		StringBuffer sb = new StringBuffer();
		//le vamos dando formato al buffer
		sb.append("Recepcion");
		//si hay informe
		if(rr != null)
		{
			//obtenemos el participante
			Participant participant = rr.getParticipant();
			//añadimos información al buffer
			if( participant != null)
			{
				sb.append(" desde " + participant.getCNAME());
				sb.append(" ssrc = " + rr.getSSRC());
			}
			else
			{
				sb.append(" ssrc = " + rr.getSSRC());
			}
		}
	}
	//si se trata de un informe de envio
	else if(event instanceof SenderReportEvent)
	{
		//cogemos el informe
		SenderReport sr = ((SenderReportEvent) event).getReport();
		//creamos un buffer
		StringBuffer sb = new StringBuffer();
		//le vamos dando formato al buffer
		sb.append("Emision");
		//si hay informe
		if( sr != null)
		{
			//obtenemos el participante
			Participant participant= sr.getParticipant();
			//añadimos información al buffer
			if( participant != null)
			{
				sb.append( " desde " + participant.getCNAME());
				sb.append( " ssrc = " + sr.getSSRC());
			}
			else
			{
				sb.append( " ssrc = " + sr.getSSRC());
			}
		}
	}
	//si no es nada de lo anterior
	else
	{
		System.out.println("Evento remoto: " + event);
	}
}

	El segundo se ejecuta al iniciar sesión un nuevo participante:
public synchronized void update(SessionEvent evt)
{
	//si hay un participante nuevo
	if (evt instanceof NewParticipantEvent)
	{
		//creamos el participante nuevo
		Participant p = ((NewParticipantEvent)evt).getParticipant();
		System.err.println(Misc.ind() + "  - Un nuevo participante se ha unido: " + p.getCNAME());
	}
}

	El tercero se ejecuta al recibir una secuencia nueva mostrando la información en el log:
public synchronized void update(ReceiveStreamEvent evt)
{
	//obtenemos el origen de la cadena
	RTPManager rtpManager = (RTPManager)evt.getSource();
	//obtenemos el participante
	Participant participant = evt.getParticipant();
	//obtenemos la secuencia
	ReceiveStream stream = evt.getReceiveStream();
	//si la secuencia es un "Payload" nos salimos
	if (evt instanceof RemotePayloadChangeEvent)
	{
		System.err.println(Misc.ind() + "  - Recivido un evento RTP no soportado.");
		System.exit(0);
	}
	//si es una nueva cadena recibida
	else if (evt instanceof NewReceiveStreamEvent)
	{
		try
		{
			//obtenemos la secuencia
			stream = ((NewReceiveStreamEvent)evt).getReceiveStream();
			//obtenemos la fuente
			DataSource ds = stream.getDataSource();
			//segun sea una secuencia de control o no, escribimos en el log una cosa u otra
			RTPControl ctl = (RTPControl)ds.getControl("javax.media.rtp.RTPControl");
			if (ctl != null)
				System.err.println(Misc.ind() + "  - Recibida nueva secuencia RTP: " + ctl.getFormat());
			else
				System.err.println(Misc.ind() + "  - Recibida nueva secuencia RTP");
			//si hay participante o no, escribimos una cosa u otra
			if (participant == null)
				System.err.println(Misc.ind() + "  - El emisor no pudo ser identificado");
			else
				System.err.println(Misc.ind() + "  - La secuencia proviene de: " + participant.getCNAME());
			//creamos un reproductor a partir de la fuente de datos
			Player p = javax.media.Manager.createPlayer(ds);
			if (p == null)
				return;
			//inicializamos el reproductor
			p.addControllerListener(this);
			p.realize();
			//generamos una ventana de reproducción
			PlayerWindow pw = new PlayerWindow(p, stream);
			playerWindow = pw;

			//Notificamos que se ha recibido una nueva secuencia
			synchronized(dataSync)
			{
				dataReceived = true;
				dataSync.notifyAll();
			}
		}
		//capturamos la excepcion
		catch (Exception e)
		{
			System.err.println(Misc.ind() + "Excepcion NewReceiveStreamEvent " + e.getMessage());
			return;
		}
	}
	//si es parte de una cadena anterior
	else if (evt instanceof StreamMappedEvent)
	{
		//si hay una secuencia y con una fuente de datos
		if (stream != null && stream.getDataSource() != null)
		{
			//usamos la fuente de datos fuente de datos
			DataSource ds = stream.getDataSource();
			//Obtenemos el formato
			RTPControl ctl = (RTPControl)ds.getControl("javax.media.rtp.RTPControl");
			System.err.println(Misc.ind() + "  - La secuencia anteriormente no identificada ");
			//escribimos el formato
			if (ctl != null)
				System.err.println(Misc.ind() + "  - " + ctl.getFormat());
			System.err.println(Misc.ind() + "  - ha sido identificada como de: " + participant.getCNAME());
			//creamos un manejador de sesion RTP
			RTPSessionMgr rtpMgr = (RTPSessionMgr)evt.getSessionManager();
			//obtenemos una sesion de direccion
			SessionAddress addr = rtpMgr.getRemoteSessionAddress();
		}
	}
	//si es una despedida
	else if (evt instanceof ByeEvent)
	{
		//crea,ps im buffer
		StringBuffer sb = new StringBuffer();
		//aplicamos un formato
		sb.append("ADIOS");
		//generamos una razón
		String reason = ((ByeEvent)evt).getReason();
		//añadimos al buffer información adicional
		sb.append(" desde " + participant.getCNAME());
		sb.append(" ssrc = " + stream.getSSRC());
		sb.append(" razon = '" + reason + "'");

		if (playerWindow != null)
		{
			playerWindow.close();
			playerWindow = null;
		}
	}
}