/** * Copyright (c) 2008 - 2015 Smaxe Ltd (www.smaxe.com). * All rights reserved. */ import com.smaxe.uv.media.core.VideoFrame; import com.smaxe.uv.media.java.swing.JVideoScreen; import com.smaxe.uv.media.java.video.VideoFrameFactory; import com.smaxe.uv.na.WebcamFactory; import com.smaxe.uv.na.webcam.IWebcam; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; import java.io.IOException; import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicReference; import javax.swing.AbstractAction; import javax.swing.AbstractListModel; import javax.swing.ComboBoxModel; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.SwingUtilities; import javax.swing.border.EmptyBorder; /** * <code>ExNativeAccessWebcam</code> - {@link IWebcam} usage example. * * @author Andrei Sochirca * @see <a href="http://www.smaxe.com/product.jsf?id=juv-webcam-sdk" target="_blank">JUV Webcam SDK</a> */ @SuppressWarnings({"rawtypes", "unchecked"}) public final class ExNativeAccessWebcam extends Object { /** * Entry point. * * @param args * @throws Exception if an exception occurred */ public static void main(final String[] args) throws Exception { final Executor executor = Executors.newSingleThreadExecutor(); final JFrame frame = new JFrame(); final JComboBox webcamComboBox = new JComboBox(); final AbstractAction webcams = new AbstractAction("Webcams") { private final static long serialVersionUID = 0L; public void actionPerformed(final ActionEvent e) { executor.execute(new Runnable() { public void run() { final List<IWebcam> webcams = WebcamFactory.getWebcams(); SwingUtilities.invokeLater(new Runnable() { public void run() { webcamComboBox.setModel(new WebcamComboModel(webcams)); } }); } }); } }; final JPanel content = new JPanel(new FlowLayout()); content.setBorder(new EmptyBorder(8, 8, 8, 8)); content.setPreferredSize(new Dimension(640, 48)); content.add(new JButton(webcams)); content.add(webcamComboBox); content.add(new JButton(new AbstractAction("Open") { private final static long serialVersionUID = -4792981545160764997L; public void actionPerformed(final ActionEvent e) { final IWebcam webcam = (IWebcam) webcamComboBox.getSelectedItem(); if (webcam == null) return; final AtomicReference<JFrame> frameRef = new AtomicReference<JFrame>(); final JVideoScreen videoScreen = new JVideoScreen(); videoScreen.setAutoScaleOnResize(false); executor.execute(new Runnable() { public void run() { final AtomicReference<VideoFrame> lastFrameRef = new AtomicReference<VideoFrame>(); try { webcam.open(new IWebcam.FrameFormat(320, 240), new IWebcam.IListenerX() { private VideoFrame lastFrame = new VideoFrame(0, 0, null); public void onVideoFrame(final VideoFrame frame) { SwingUtilities.invokeLater(new Runnable() { public void run() { videoScreen.setFrame(frame); if (lastFrame.width != frame.width || lastFrame.height != frame.height) { final JFrame frame = frameRef.get(); if (frame != null) frame.pack(); } lastFrame = frame; lastFrameRef.set(lastFrame); } }); } public void onVideoFrameTimeout(final long timeout) { System.out.println("onVideoFrameTimeout: " + timeout + "ms"); } public void onVideoInfo(final float frameRate, final long frames) { System.out.println("onVideoInfo: frameRate=" + frameRate + ", frames=" + frames); } }); final IWebcam.FrameFormat[] supportedFormats = webcam.getFormats(); if (supportedFormats != null) { System.out.println("Webcam: " + webcam.getName()); System.out.println("Supported formats: "); for (IWebcam.FrameFormat format : supportedFormats) { System.out.println("=> " + format); } } webcam.startCapture(); SwingUtilities.invokeLater(new Runnable() { public void run() { final JFrame frame = new JFrame(); frameRef.set(frame); frame.getContentPane().setLayout(new BorderLayout()); frame.getContentPane().add(videoScreen, BorderLayout.CENTER); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.setResizable(false); frame.setTitle(webcam.getName()); videoScreen.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(final MouseEvent e) { final int clickCount = e.getClickCount(); final Object source = e.getSource(); switch (clickCount) { case 1: { if (SwingUtilities.isRightMouseButton(e)) { JPopupMenu popup = new JPopupMenu(); popup.add(new AbstractAction("Take Snapshot") { private final static long serialVersionUID = 0L; public void actionPerformed(ActionEvent e) { new SnapshotDialog(VideoFrameFactory.clone(lastFrameRef.get())).setVisible(true); } }); popup.addSeparator(); popup.add(new AbstractAction("Mirror") { private final static long serialVersionUID = 0L; public void actionPerformed(ActionEvent e) { videoScreen.mirror(!videoScreen.getMirrorFlag()); } }); popup.add(new AbstractAction("Flip") { private final static long serialVersionUID = 0L; public void actionPerformed(ActionEvent e) { videoScreen.flip(!videoScreen.getFlipFlag()); } }); popup.addSeparator(); for (IWebcam.FrameFormat format : supportedFormats) { popup.add(new SetWebcamFrameFormat(executor, webcam, format)); } if (supportedFormats.length <= 1) { popup.add(new SetWebcamFrameFormat(executor, webcam, new IWebcam.FrameFormat(320, 240))); popup.add(new SetWebcamFrameFormat(executor, webcam, new IWebcam.FrameFormat(640, 480))); } popup.addSeparator(); popup.add(new SetWebcamFrameFormat(executor, webcam, new IWebcam.FrameFormat(512, 512))); popup.show((Component) source, e.getX(), e.getY()); } } break; } } }); frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { webcam.close(); frame.dispose(); } }); frame.pack(); frame.setVisible(true); } }); } catch (Exception ex) { JOptionPane.showMessageDialog(frame, ex.getMessage(), ex.getMessage(), JOptionPane.WARNING_MESSAGE); } } }); } })); frame.getContentPane().setLayout(new BorderLayout()); frame.getContentPane().add(content); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.setTitle("Webcam capture options"); frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.pack(); frame.setVisible(true); webcams.actionPerformed(null); } /** * <code>SetWebcamFrameFormat</code> */ private final static class SetWebcamFrameFormat extends AbstractAction { private final static long serialVersionUID = 9182176560922213390L; // fields private final Executor executor; private final IWebcam webcam; private final IWebcam.FrameFormat format; /** * Constructor. * * @param executor * @param webcam * @param format */ public SetWebcamFrameFormat(final Executor executor, final IWebcam webcam, final IWebcam.FrameFormat format) { super(format.width + "x" + format.height); this.executor = executor; this.webcam = webcam; this.format = format; } // AbstractAction implementation public void actionPerformed(final ActionEvent e) { executor.execute(new Runnable() { public void run() { webcam.setFrameFormat(format); } }); } } /** * <code>SnapshotDialog</code> - snapshot dialog. */ private final static class SnapshotDialog extends JDialog { private final static long serialVersionUID = -3136925779409522531L; /** * Constructor. * * @param videoFrame */ public SnapshotDialog(final VideoFrame videoFrame) { this.setLayout(new BorderLayout()); this.setResizable(false); this.setTitle("Web snapshot"); JVideoScreen videoScreen = new JVideoScreen(); videoScreen.setFrame(videoFrame); videoScreen.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(final MouseEvent e) { final int clickCount = e.getClickCount(); final Object source = e.getSource(); switch (clickCount) { case 1: { if (SwingUtilities.isRightMouseButton(e)) { JPopupMenu popup = new JPopupMenu(); popup.add(new AbstractAction("Save As..") { private final static long serialVersionUID = 0L; public void actionPerformed(ActionEvent e) { JFileChooser fileChooser = new JFileChooser(); fileChooser.setCurrentDirectory(new File(".")); final int rv = fileChooser.showSaveDialog(getParent()); if (rv != JFileChooser.APPROVE_OPTION) return; final File file = fileChooser.getSelectedFile(); new Thread(new Runnable() { public void run() { try { VideoFrameFactory.saveAsJpg(file, videoFrame); } catch (IOException e) { e.printStackTrace(); } } }).start(); } }); popup.show((Component) source, e.getX(), e.getY()); } } break; } } }); this.add(videoScreen, BorderLayout.CENTER); this.pack(); } } /** * <code>WebcamComboModel</code> - webcam combo model. */ private final static class WebcamComboModel extends AbstractListModel implements ComboBoxModel { private final static long serialVersionUID = -8627944517955777531L; // fields private final List<IWebcam> devices; // state private Object selected = null; /** * Constructor. * * @param devices */ public WebcamComboModel(final List<IWebcam> devices) { this.devices = devices; } // MutableComboBoxModel implementation public void setSelectedItem(final Object item) { this.selected = item; } public Object getSelectedItem() { return selected; } public Object getElementAt(int index) { return devices.get(index); } public int getSize() { return devices.size(); } } /** * Constructor. */ private ExNativeAccessWebcam() { } }