Gravar vídeo com WebCam

9 respostas
G

Já procurei em vários tópicos mas não estou conseguindo achar uma resposta.

Meu atual formulário GUI mostra a imagem da webcam e é possível tirar fotos e salva-las no computador. Porém eu queria que quando o usuário apertasse ‘Gravar’ começasse a gravar e o botoão mudasse para ‘Parar’. Quando ele clicar de novo a gravação para e salva o arquivo.

As outras coisas eu sei fazer, como os Botões e o JFileChooser, mas eu só queria saber COMO GRAVAR?
OBS: Para tirar fotos uso o JFM.

Abraços, Gustavo Borba.

9 Respostas

quebrado

Sera que isto ajuda…
http://www.humatic.de/htools/dsj.htm
t+

G

E em JFM, não haveria um jeito?

discorpio

Boa noite a todos.

Depois de voce intalar o Java Media Framework (JMF), baixe-o no link abaixo, voce então pode usar o código logo a seguir:

http://java.sun.com/javase/technologies/desktop/media/jmf/2.1.1/download.html.

import java.awt.Image;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.media.Buffer;
import javax.media.CaptureDeviceInfo;
import javax.media.CaptureDeviceManager;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.Player;
import javax.media.control.FrameGrabbingControl;
import javax.media.format.VideoFormat;
import javax.media.util.BufferToImage;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRootPane;

public class WebCamCapture extends JFrame implements ActionListener {

    private static final long serialVersionUID = 1L;
    private Player player;
    private CaptureDeviceInfo di;
    private MediaLocator ml;
    private JPanel painelbotoes;
    private JButton start = null;
    private JButton capture = null;
    public JButton clearimage = null;
    public JButton confirm = null;
    public Buffer buf = null;
    public Image img = null;
    // public VideoFormat vf = null;
    public BufferToImage btoi = null;
    public Component webcam = null;

    public static void main(String args[]){
        JFrame wcam = new WebCamCapture();
        wcam.setTitle("Captura de Imagem");
    }

    public WebCamCapture(){
        setUndecorated(true);
        getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());
        painelbotoes = new JPanel();
        painelbotoes.setLayout(new GridLayout(1,4));
        start = new JButton("Iniciar");
        start.addActionListener(this);
        capture = new JButton("Capture");
        capture.addActionListener(this);
        capture.setEnabled(false);
        clearimage = new JButton("Limpar");
        clearimage.addActionListener(this);
        clearimage.setEnabled(false);
        confirm = new JButton("Gravar");
        confirm.addActionListener(this);
        confirm.setEnabled(false);
        painelbotoes.add(start);
        painelbotoes.add(capture);
        painelbotoes.add(clearimage);
        painelbotoes.add(confirm);
        add(painelbotoes, BorderLayout.NORTH);
        di = CaptureDeviceManager.getDevice("vfw//0");
        ml = new MediaLocator("vfw://0");
        pack();
        this.setSize(400,400);
        this.setLocationRelativeTo(this);
        this.setVisible(true);
    }

    public void playerClose(){
        player.close();
        player.deallocate();
        player = null;
    }

    public void actionPerformed(ActionEvent e){
        if (e.getSource()==start){
            try {
                player = Manager.createRealizedPlayer(ml);
                webcam = player.getVisualComponent();
                if (webcam!=null) add(webcam, BorderLayout.CENTER);
                player.start();
                validate();
            } catch(Exception ex){
                JOptionPane.showMessageDialog(null,"Não foi possível conectar ao dispositivo de captura\n"+ex.getMessage());
                ex.printStackTrace();
            }
            start.setEnabled(false);
            capture.setEnabled(true);
        } else if (e.getSource()==capture){
            FrameGrabbingControl fgc=(FrameGrabbingControl)player.getControl("javax.media.control.FrameGrabbingControl");
            buf = fgc.grabFrame();
            btoi = new BufferToImage((VideoFormat)buf.getFormat());
            img = btoi.createImage(buf);
            playerClose();
            capture.setEnabled(false);
            clearimage.setEnabled(true);
            confirm.setEnabled(true);
        } else if (e.getSource()==clearimage){
            remove(webcam);
            webcam = null;
            clearimage.setEnabled(false);
            confirm.setEnabled(false);
            start.setEnabled(true);
        } else if (e.getSource()==confirm){
            gravaImg(img);
            System.exit(0);
        }
    }

    public void gravaImg(Image imagem){
        File arquivo = new File("C:/Temp/Teste.jpg");
        try {
            if (!arquivo.exists()){
              FileOutputStream fo = new FileOutputStream(arquivo);
            }
            ImageIO.write((RenderedImage)imagem, "JPG", arquivo);
        } catch(IOException ex){
            JOptionPane.showMessageDialog(null, "Não foi possível encontrar o caminho especificado");
            ex.printStackTrace();
        }
    }

}

Execute e vê se é o que voce queria.

J
GustavoBorba:
E em JFM, não haveria um jeito?
A jmf usa o vídeo for windows(vfw), que está para ser excluído das próximas versões do windows(7 em diante). A dsj usa directshow e pinta o vídeo em cima do direct3d, com a vmr9. Além da dsj ser bem mais simples de se usar.

A aplicação abaixo realiza uma simples captura para um arquivo de vídeo.

/**
dsj demo code.
You may use, modify and redistribute this code under the terms laid out in the header of the DSJDemo application.
copyright 2005-7
N.Peters
humatic GmbH
Berlin, Germany
**/

import de.humatic.dsj.*;


public class SimpleCapture implements java.beans.PropertyChangeListener {

	private DSCapture graph;

	public SimpleCapture() {}

	public void createGraph() {

		javax.swing.JFrame f = new javax.swing.JFrame("dsj SimpleCapture");

		DSFilterInfo[][] dsi = DSCapture.queryDevices();

		graph = new DSCapture(DSFiltergraph.RENDER_NATIVE, dsi[0][2], false, DSFilterInfo.doNotRender(), this);

		f.add(java.awt.BorderLayout.CENTER, graph.asComponent());

		f.add(java.awt.BorderLayout.SOUTH, new SwingMovieController(graph));

		final javax.swing.JButton toFile = new javax.swing.JButton("set capture file");

		toFile.addActionListener(new java.awt.event.ActionListener() {

			public void actionPerformed(java.awt.event.ActionEvent e) {

				if (graph.getState() == DSCapture.PREVIEW) {

					graph.setCaptureFile("captureTest.asf", DSFilterInfo.doNotRender(), DSFilterInfo.doNotRender(), true);

					toFile.setText("set preview");

					graph.record();

				} else {

					graph.setPreview();

					toFile.setText("set capture file");

				}

			}

		});

		f.add(java.awt.BorderLayout.NORTH, toFile);

		f.pack();

		f.setVisible(true);

		javax.swing.JFrame jf = new javax.swing.JFrame("Device control");

		jf.setLayout(new java.awt.GridLayout(0,1));

		if (((DSCapture)graph).getActiveVideoDevice() != null && ((DSCapture)graph).getActiveVideoDevice().getControls() != null) {

			for (int i = CaptureDeviceControls.BRIGHTNESS; i < CaptureDeviceControls.FOCUS; i++) try { jf.add(((DSCapture)graph).getActiveVideoDevice().getControls().getController(i, 0, true)); }catch (Exception ex){}

		}

		if (((DSCapture)graph).getActiveAudioDevice() != null) for (int i = CaptureDeviceControls.MASTER_VOL; i < CaptureDeviceControls.TREBLE; i++) try { jf.add(((DSCapture)graph).getActiveAudioDevice().getControls().getController(i, 0, true)); }catch (Exception ex){}

		if (jf.getContentPane().getComponentCount() == 0) return;

		jf.pack();

		jf.setVisible(true);

		/**
		Don't do this at home. This demo relies on dsj closing and disposing off filtergraphs when the JVM exits. This is
		OK for a "open graph, do something & exit" style demo, but real world applications should take care of calling
		dispose() on filtergraphs they're done with themselves.
		**/

		f.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

	}

	public void propertyChange(java.beans.PropertyChangeEvent pe) {

		System.out.println("received event or callback from "+pe.getPropagationId());

	}

	public static void main(String[] args){

		new SimpleCapture().createGraph();

	}


}
G

Olá, discorpio.

Esse código eu já tenho. Eu gostaria é de gravar um VÍDEO.

Abraços, Gustavo Borba.

J
GustavoBorba:
Olá, discorpio.

Esse código eu já tenho. Eu gostaria é de gravar um VÍDEO.

Abraços, Gustavo Borba.

/**
dsj demo code.
You may use, modify and redistribute this code under the terms laid out in the header of the DSJDemo application.
copyright 2005-7
N.Peters
humatic GmbH
Berlin, Germany
**/

import de.humatic.dsj.*;


public class SimpleCapture implements java.beans.PropertyChangeListener {

	private DSCapture graph;

	public SimpleCapture() {}

	public void createGraph() {

		javax.swing.JFrame f = new javax.swing.JFrame("dsj SimpleCapture");

		DSFilterInfo[][] dsi = DSCapture.queryDevices();

		graph = new DSCapture(DSFiltergraph.RENDER_NATIVE, dsi[0][2], false, DSFilterInfo.doNotRender(), this);

		f.add(java.awt.BorderLayout.CENTER, graph.asComponent());

		f.add(java.awt.BorderLayout.SOUTH, new SwingMovieController(graph));

		final javax.swing.JButton toFile = new javax.swing.JButton("set capture file");

		toFile.addActionListener(new java.awt.event.ActionListener() {

			public void actionPerformed(java.awt.event.ActionEvent e) {

				if (graph.getState() == DSCapture.PREVIEW) {

					graph.setCaptureFile("captureTest.asf", DSFilterInfo.doNotRender(), DSFilterInfo.doNotRender(), true);

					toFile.setText("set preview");

					graph.record();

				} else {

					graph.setPreview();

					toFile.setText("set capture file");

				}

			}

		});

		f.add(java.awt.BorderLayout.NORTH, toFile);

		f.pack();

		f.setVisible(true);

		javax.swing.JFrame jf = new javax.swing.JFrame("Device control");

		jf.setLayout(new java.awt.GridLayout(0,1));

		if (((DSCapture)graph).getActiveVideoDevice() != null && ((DSCapture)graph).getActiveVideoDevice().getControls() != null) {

			for (int i = CaptureDeviceControls.BRIGHTNESS; i < CaptureDeviceControls.FOCUS; i++) try { jf.add(((DSCapture)graph).getActiveVideoDevice().getControls().getController(i, 0, true)); }catch (Exception ex){}

		}

		if (((DSCapture)graph).getActiveAudioDevice() != null) for (int i = CaptureDeviceControls.MASTER_VOL; i < CaptureDeviceControls.TREBLE; i++) try { jf.add(((DSCapture)graph).getActiveAudioDevice().getControls().getController(i, 0, true)); }catch (Exception ex){}

		if (jf.getContentPane().getComponentCount() == 0) return;

		jf.pack();

		jf.setVisible(true);

		/**
		Don't do this at home. This demo relies on dsj closing and disposing off filtergraphs when the JVM exits. This is
		OK for a "open graph, do something & exit" style demo, but real world applications should take care of calling
		dispose() on filtergraphs they're done with themselves.
		**/

		f.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

	}

	public void propertyChange(java.beans.PropertyChangeEvent pe) {

		System.out.println("received event or callback from "+pe.getPropagationId());

	}

	public static void main(String[] args){

		new SimpleCapture().createGraph();

	}


}
G

Ocorre esse erro:

<blockquote>Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException: 2

at app.createGraph(app.java:15)

at app.main(app.java:89)

Java Result: 1

</blockquote>
J

GustavoBorba:
Ocorre esse erro:

<blockquote>Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException: 2

at app.createGraph(app.java:15)

at app.main(app.java:89)

Java Result: 1

</blockquote></blockquote>

Porque sua máquina deve ter apenas 1 dispositivo de captura.

graph = new DSCapture(DSFiltergraph.RENDER_NATIVE, dsi[0][2], false, DSFilterInfo.doNotRender(), this);

pode usar assim

graph = new DSCapture(DSFiltergraph.RENDER_NATIVE, dsi[0][0], false, DSFilterInfo.doNotRender(), this);

Se você receber o erro novamente, coloque um breakepoint na linha, e veja em qual índice do vetor dsi está o dispositivo de vídeo.

Metaleiro

[color=darkblue]Tem o Source no final :[/color]

Record Movies with Java Media Framework (JMF)

Criado 1 de junho de 2010
Ultima resposta 4 de jun. de 2010
Respostas 9
Participantes 5