Java Media Framework + jipCam + Camera IP

6 respostas
C

:smiley:

Saudações,

Fiz um aplicativo utilizando JMF que se conecta a uma camera USB e exibe sua imagem, podendo tirar ‘fotografias’ da imagem e/ou gravar o vídeo. Agora estou estudando a integração do JMF com uma Camera IP, para tanto estou estudando o jipCam http://jipcam.sourceforge.net/ que é um framework que auxilia exatamente neste tipo de comunicação: conectar uma camera ip em um aplicativo jmf. Porém, estou com dificuldades para encontrar documentação, ou código de exemplo, nem se quer um Hello World encontrei… Em fim, algo que facilite minha vida. Alguém já trabalhou, ou estudou algo a respeito?

6 Respostas

C

aqui o primeiro código de minha jornada de aprendizado. retirado do livro de Deitel:

Ele executa um arquivo ou um local (dispositivo.. no caso de uma webcam na porta 3: "vfw://3" )

//Pacotes do núcleo de Java
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.media.ControllerAdapter;
import javax.media.EndOfMediaEvent;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.NoPlayerException;
import javax.media.Player;
import javax.media.PrefetchCompleteEvent;
import javax.media.RealizeCompleteEvent;
import javax.media.Time;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class SimplePlayer extends JFrame {
	/**
	 * Default Serial Version
	 */
	private static final long serialVersionUID = 1L;

	// declara um objeto Player para reproduzir clipes de mídia
	private Player player;

	/*
	 * objetos Component para a exibição do vídeo e para manter os controles
	 */
	// componente para conteúdo visual que exibe a parte de vídeo de um clipe de
	// mídia (se o clipe de mídia for um vídeo).
	private Component visualMedia;

	// componente de controle da mídia. permite reproduzir, fazer pausa e parar
	// o clipe de mídia
	private Component mediaControl;

	// contêiner principal
	private Container container;

	/*
	 * endereços dos clipes como referências File e URL
	 */
	// arquivo de mídia
	private File mediaFile;

	// referência. pode ser uma webcam, um endereço de rede ou internet
	private URL fileURL;

	// construtor para SimplePlayer
	public SimplePlayer() {
		super("cassioso player");

		container = getContentPane();
		// painel que contém botões
		JPanel buttonPanel = new JPanel();
		container.add(buttonPanel, BorderLayout.NORTH);

		// abrindo um arquivo a partir do botão de diretório
		JButton openFile = new JButton("Open File");
		buttonPanel.add(openFile);
		// registra um ActionListener para eventos de openFile
		openFile.addActionListener(
		// classe interna anônima para tratar eventos de openFile
				new ActionListener() {
					// abre e cria "player" para o arquivo
					public void actionPerformed(ActionEvent event) {
						/*
						 * pede ao usuário que selecione um arquivo de mídia do
						 * computador local.
						 */
						mediaFile = getFile();
						if (mediaFile != null) {
							// tenta obter uma representação como URL do nome e
							// endereço do arquivo selecionado.
							try {
								fileURL = mediaFile.toURL();
							}
							// caminho para o arquivo não pode ser encontrado
							catch (MalformedURLException badURL) {
								badURL.printStackTrace();
								showErrorMessage("Bad URL");
							}
							// Método de SimplePlayer para criar um Player para
							// a mídia selecionada pelo usuário
							makePlayer(fileURL.toString());
						}
					} // fim do método actionPerformed
				} // fim do método ActionListener
				); // fim da chamada para o método addActionListener

		// botão de abertura do URL
		JButton openURL = new JButton("Open Locator");
		buttonPanel.add(openURL);
		// registra um ActionListener para eventos de openURL
		openURL.addActionListener(
		// classe interna anônima para tratar de eventos de openURL
				new ActionListener() {
					// abre e cria um "player" para o localizador de mídia
					public void actionPerformed(ActionEvent event) {
						/*
						 * pede ao usuário que digite um string que especifica o
						 * endereço da mídia
						 */
						String addressName = getMediaLocation();
						if (addressName != null)
							// Método de SimplePlayer para criar um Player para
							// a mídia que está no endereço especificado
							makePlayer(addressName);
					}
				} // fim do método ActionListener
				); // fim da chamada para o método addActionListener

		/*
		 * O JMF fornece geradores de vídeo peso-leve que são compatíveis com os
		 * componentes peso-leve do Swing. A linha a baixo especifica que o
		 * Player deve desenhar seus componentes GUI (graphical user interface)
		 * e sua parte de vídeo (se existir uma) usando geradores peso-leve, de
		 * modo que o reprodutor de mídia terá aparência semelhante à de outros
		 * componentes GUI com componentes Swing
		 */
		Manager.setHint(Manager.LIGHTWEIGHT_RENDERER, Boolean.TRUE);
	} // fim do construtor SimplePlayer

	// método utilitário para mensagens de erro "pop-up"

	public void showErrorMessage(String error) {
		JOptionPane.showMessageDialog(this, error, "Error",
				JOptionPane.ERROR_MESSAGE);
	}

	// obtém arquivo do computador
	public File getFile() {
		JFileChooser fileChooser = new JFileChooser();
		fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
		int result = fileChooser.showOpenDialog(this);
		if (result == JFileChooser.CANCEL_OPTION)
			return null;
		else
			return fileChooser.getSelectedFile();
	}

	// obtém endereço da mídia digitado pelo usuário
	public String getMediaLocation() {
		String input = JOptionPane.showInputDialog(this, "Enter URL");
		// se o usuário pressionar OK sem digitar dados
		if (input != null && input.length() == 0)
			return null;
		return input;
	}

	/*
	 * cria player com o endereço da mídia. O argumento String indica o endereço
	 * da mídia.
	 */
	public void makePlayer(String mediaLocation) {
		// método para remover da frame o componente visual e os controles da
		// GUI do Player anterior, antes de criar um novo Player
		if (player != null)
			removePlayerComponents();
		/*
		 * O clipe de mídia precisa ser processado antes de ser reproduzido.
		 * Para processar um clipe de mídia, o programa precisa acessar uma
		 * fonte de mídia...
		 */
		// O método makePlayer exige um ponteiro para a fonte da qual a mídia é
		// recuperada, o que é feito instanciando-se um novo MediaLocator para o
		// valor dado pelo argumento String
		MediaLocator mediaLocator = new MediaLocator(mediaLocation);
		// Verifica a validade da fonte de mídia
		if (mediaLocator == null) {
			showErrorMessage("Error opening file");
			return;
		}
		// cria um player a partir de MediaLocator
		try {
			/*
			 * ... criar um Controller para aquela fonte ...
			 */
			// createPlayer abre a fonte de mídia especificada e determina o
			// Player apropriado para a fonte de mídia
			player = Manager.createPlayer(mediaLocator);

			// inSource = Manager.createDataSource(mediaLocator);

			/*
			 * Os ControllerListeners esperam os ControllerEvents que os Players
			 * geram, para monitorar o progresso de um Player no processo de
			 * tratamento da mídia.
			 */
			player.addControllerListener(new PlayerEventHandler());

			/*
			 * ... e enviar a mídia para a saída
			 * 
			 * para finalizar o método makePlayer invoca o método realize de
			 * Player no estado Realizing para indicar que ele está se
			 * conectando à sua fonte de mídia e interagindo com ela. Quando um
			 * Player completa a realização, ele gera um Realize-CompleteEvent ?
			 * um tipo de ControllerEvent que ocorre quando o Player completa
			 * sua transição para o estado Realized. Este estado indica que o
			 * Player completou todos os preparativos necessários para começar a
			 * processar a mídia. O PlayerEventHandler invoca o método
			 * realizeComplete quando o Player gera um RealizeCompleteEvent
			 */
			player.realize();
		}
		// caso não exista nenhum player ou o formato não é suportado
		catch (NoPlayerException noPlayerException) {
			noPlayerException.printStackTrace();
		}
		// erro na leitura do arquivo
		catch (IOException ioException) {
			ioException.printStackTrace();
		}
	} // fim do método makePlayer

	/**
	 * Devolve o player para os recursos do sistema e restaura a mídia e os
	 * controles
	 */
	public void removePlayerComponents() {
		// remove componente de vídeo anterior, se existe um
		if (visualMedia != null)
			container.remove(visualMedia);

		// remove controle de mídia anterior, se existe um
		if (mediaControl != null)
			container.remove(mediaControl);

		// método para parar toda a atividade do Player e liberar recursos do
		// sistema mantidos pelo Player anterior.
		player.close();
	}

	// obtém controles visuais para mídia e player
	public void getMediaComponents() {
		// obtém o componente visual do clipe de vídeo e devolve null para
		// arquivos de áudio, porque não há componente visual
		// a exibir.
		visualMedia = player.getVisualComponent();

		// adiciona componente visual, se estiver presente
		if (visualMedia != null)
			container.add(visualMedia, BorderLayout.CENTER);

		// obtém a GUI de controle do player
		mediaControl = player.getControlPanelComponent();

		// adiciona componente de controles, se estiver presente
		if (mediaControl != null)
			container.add(mediaControl, BorderLayout.SOUTH);
	} // fim do método getMediaComponents

	/*
	 * A classe ControllerAdapter facilita a implementação de ControllerListener
	 * para as classes que precisam tratar de apenas alguns tipos de
	 * ControllerEvent.
	 */
	private class PlayerEventHandler extends ControllerAdapter {

		// carrega antecipadamente a mídia assim que o player é realizado.
		public void realizeComplete(RealizeCompleteEvent realizeDoneEvent) {
			/*
			 * Quando o Player carrega antecipadamente um clipe de mídia, o
			 * Player obtém controle exclusivo sobre certos recursos do sistema
			 * necessários para reproduzir o clipe. O Player também começa a
			 * colocar dados da mídia no buffer para reduzir o atraso antes da
			 * reprodução do clipe de mídia.
			 * 
			 * enquanto isto, o estado do player é definido como Prefetching.
			 */
			player.prefetch();
			/*
			 * Quando termina de carregar o estado do player mudfa para
			 * Prefetched e fica pronto para reproduzir a mídia. É gerado então
			 * um PrefetchCompleteEvent, automaticamente o player invoca o
			 * método prefetchComplete de PlayerEventHandler
			 */
		}

		// player pode começar a mostrar a mídia após a carga antecipada
		public void prefetchComplete(PrefetchCompleteEvent prefetchDoneEvent) {
			/*
			 * obtém os controles da GUI e o componente visual da mídia (se a
			 * mídia for um clipe de vídeo) e os anexa ao painel de conteúdo da
			 * janela do aplicativo
			 */
			getMediaComponents();

			// assegura um leiaute válido para a frame
			validate();

			// começa a reproduzir a mídia
			/*
			 * Se o Player não fez a carga antecipada nem realizou a mídia,
			 * invocar o método start faz a carga antecipada e realiza a mídia.
			 */
			player.start();
			/*
			 * Quando o clipe de mídia terminar, o Player gera um
			 * ControllerEvent do tipo EndOfMediaEvent.
			 */
		} // fim do método prefetchComplete

		// se fim da mídia, restaura para o início e pára de reproduzir
		/*
		 * Trata o evento EndOfMediaEvent e restaura o clipe de mídia para sua
		 * posição inicial invocando o método setMediaTime de Player com um novo
		 * Time (pacote javax.media) com valor zero.
		 */
		public void endOfMedia(EndOfMediaEvent mediaEndEvent) {
			// ajusta a posição da mídia para uma posição específica de tempo
			player.setMediaTime(new Time(0));

			// termina o processamento e faz o estado do Player = Stopped
			player.stop();
			// Obs.: Invocar o método start para um Player Stopped que não tenha
			// sido fechado retoma a reprodução da mídia.

		}// fim do método endOfMedia

	} // fim da classe interna PlayerEventHandler

	// executa o aplicativo
	public static void main(String args[]) {
		SimplePlayer testPlayer = new SimplePlayer();
		testPlayer.setSize(300, 300);
		testPlayer.setLocation(300, 300);
		testPlayer.setDefaultCloseOperation(EXIT_ON_CLOSE);
		testPlayer.setVisible(true);
	}

} // fim da classe SimplePlayer
C

Saudações,

Um código simples que deveria funcionar com o jipcam, mas da um erro de dependencia com o log4j:

[color=red]Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Category
at ipcam.PlayerManager.main([/color][color=blue]PlayerManager.java:115[/color][color=red])[/color]

package ipcam;

import java.awt.Component;

import javax.media.ConfigureCompleteEvent;
import javax.media.ControllerEvent;
import javax.media.ControllerListener;
import javax.media.EndOfMediaEvent;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.Player;
import javax.media.PrefetchCompleteEvent;
import javax.media.Processor;
import javax.media.RealizeCompleteEvent;
import javax.media.ResourceUnavailableEvent;
import javax.media.SizeChangeEvent;
import javax.media.protocol.DataSource;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * @author cassio
 * @since December 2007
 */
public class PlayerManager extends JFrame implements ControllerListener {

	private static final long serialVersionUID = 1L;

	private Player p;

	private Object waitSync = new Object();

	boolean stateTransitionOK = true;

	public void play(DataSource ds) {

		try {
			p = Manager.createPlayer(ds);
		} catch (Exception e) {
			System.err.println("Failure to create the player: " + e);
		}

		/*
		 * turn on the listeners and realize the player
		 */
		p.addControllerListener(this);
		p.prefetch();
		if (!waitForState(Processor.Prefetched)) {
			System.err.println("Failure to realize the player: ");
		}

		JPanel painel = new JPanel();
		Component cc; // control component
		Component vc; // visual component
		if ((vc = p.getVisualComponent()) != null)
			painel.add(vc);
		if ((cc = p.getControlPanelComponent()) != null)
			add(cc);

		this.setContentPane(painel);
		
		p.start();
		this.setVisible(true);
	}

	public void addNotify() {
		super.addNotify();
		pack();
	}

	private boolean waitForState(int state) {
		synchronized (waitSync) {
			try {
				while (p.getState() < state && stateTransitionOK)
					waitSync.wait();
			} catch (Exception e) {
			}
		}
		return stateTransitionOK;
	}

	/**
	 * Controller Listener implementation
	 */
	public void controllerUpdate(ControllerEvent evt) {
		if (evt instanceof ConfigureCompleteEvent
				|| evt instanceof RealizeCompleteEvent
				|| evt instanceof PrefetchCompleteEvent) {
			synchronized (waitSync) {
				stateTransitionOK = true;
				waitSync.notifyAll();
			}
		} else if (evt instanceof ResourceUnavailableEvent) {
			synchronized (waitSync) {
				stateTransitionOK = false;
				waitSync.notifyAll();
			}
		} else if (evt instanceof EndOfMediaEvent) {
			p.close();
		} else if (evt instanceof SizeChangeEvent) {
		}
	}

	/**
	 * Main program
	 */
	public static void main(String[] args) {
		MediaLocator ml = new MediaLocator("http://192.168.0.100:80");
		net.sf.jipcam.axis.media.protocol.http.DataSource ds = null;
		try {
			// DataSource configuration
			ds = new net.sf.jipcam.axis.media.protocol.http.DataSource();
			ds.setLocator(ml);
			// i'm not using password
			ds.setUsername(null);
			ds.setPassword(null);
		} catch (Exception e) {
			System.err.println("Imposspível criar dataSuource para: " + ml);
			e.printStackTrace();
		}

		PlayerManager p = new PlayerManager();
		p.play(ds);
	}
}
C

Consegui resolver o problema do log4j. Aparentemente foi apenas uma questão de configuração de diretório… Coloquei a lib do log4j à cima dos diretórios do projeto: coloquei na pasta JAVA_HOME/jre/lib/ext. Porém me surgiu um outro erro, agora relacionado mais diretamente com o que estou tentando fazer:

[color=red]Failure to create the player: javax.media.NoPlayerException: Cannot find a Player for: net.sf.jipcam.axis.media.protocol.http.DataSource@b8c8e6
Exception in thread “main” java.lang.NullPointerException
at ipcam.PlayerManager.play(PlayerManager.java:50)
at ipcam.PlayerManager.main(PlayerManager.java:128)[/color]

Este erro ocorreu por que meu Manager.CreatePlayer(ds) não funcionou:

try {
			p = Manager.createPlayer(ds);
		} catch (NoPlayerException e) {
			// a exceção é capturada aqui!!!
			System.err.println("Failure to create the player: " + e);
		} catch (IOException e) {
			System.err.println("Failure to acces the DataSource: " + e);
		}

pesquisar agora…

R

Kra, conseguiu resolver esse problema???

C

não, infelizmente não consegui trabalhar com o jipcam.

C

cassioso, entao vc ta trabalhando so com JMF para cominicar com camera ip…

vc tem algum exemplo para o jmf com camera ip…

Criado 22 de novembro de 2007
Ultima resposta 21 de fev. de 2008
Respostas 6
Participantes 3