/** * Copyright (c) 2006 - 2012 Smaxe Ltd (www.smaxe.com). * All rights reserved. */ import com.smaxe.uv.media.core.VideoFrame; import com.smaxe.uv.media.java.fx.JfxVideoScreen; import com.smaxe.uv.na.WebcamFactory; import com.smaxe.uv.na.webcam.IWebcam; import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicReference; import javafx.application.Application; import javafx.application.Platform; import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Insets; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.ChoiceBox; import javafx.scene.control.ContextMenu; import javafx.scene.control.MenuItem; import javafx.scene.control.SeparatorMenuItem; import javafx.scene.input.MouseButton; import javafx.scene.input.MouseEvent; import javafx.scene.layout.BorderPane; import javafx.stage.Stage; import javafx.stage.WindowEvent; /** * <code>ExJfxNativeAccessWebcam</code> - {@link IWebcam} usage example in JavaFx environment. * * @author Andrei Sochirca * @see <a href="http://www.smaxe.com/product.jsf?id=juv-webcam-sdk" target="_blank">JUV Webcam SDK</a> */ public final class ExJfxNativeAccessWebcam extends Application { /** * Entry point. * * @param args * @throws Exception if an exception occurred */ public static void main(final String[] args) throws Exception { launch(args); } /** * <code>EnumerateWebcamsEventHandler</code> - 'Enumerqtes Webcams' event handler. */ private final class EnumerateWebcamsEventHandler extends Object implements EventHandler<ActionEvent> { public void handle(final ActionEvent event) { executor.execute(new Runnable() { public void run() { final List<IWebcam> webcams = WebcamFactory.getWebcams(); Platform.runLater(new Runnable() { public void run() { webcamChoiceBox.getItems().setAll(webcams); } }); } }); } }; /** * <code>SetWebcamFrameFormatEventHandler</code> - 'Open Webcam' event handler. */ private final class SetWebcamFrameFormatEventHandler extends Object implements EventHandler<ActionEvent> { // fields private final Executor executor; private final IWebcam webcam; private final IWebcam.FrameFormat format; /** * Constructor. * * @param executor * @param webcam * @param format */ public SetWebcamFrameFormatEventHandler(final Executor executor, final IWebcam webcam, final IWebcam.FrameFormat format) { this.executor = executor; this.webcam = webcam; this.format = format; } // EventHandler implementation public void handle(final ActionEvent event) { executor.execute(new Runnable() { public void run() { webcam.setFrameFormat(format); } }); } } /** * <code>OpenWebcamEventHandler</code> - 'Open Webcam' event handler. */ private final class OpenWebcamEventHandler extends Object implements EventHandler<ActionEvent> { public void handle(final ActionEvent event) { final IWebcam webcam = webcamChoiceBox.getSelectionModel().getSelectedItem(); if (webcam == null) return; final AtomicReference<Stage> stageRef = new AtomicReference<Stage>(); final JfxVideoScreen videoScreen = new JfxVideoScreen(); 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) { Platform.runLater(new Runnable() { public void run() { videoScreen.setFrame(frame); if (lastFrame.width != frame.width || lastFrame.height != frame.height) { final Stage stage = stageRef.get(); if (stage != null) { stage.sizeToScene(); } } 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(); Platform.runLater(new Runnable() { public void run() { final Stage stage = new Stage(); stage.setResizable(false); stage.setScene(new Scene(new BorderPane(videoScreen))); stage.setTitle(webcam.getName()); stageRef.set(stage); videoScreen.setOnMouseClicked(new EventHandler<MouseEvent>() { public void handle(final MouseEvent event) { if (event.getClickCount() != 1) return; if (event.getButton() != MouseButton.SECONDARY) return; ContextMenu popup = new ContextMenu(); MenuItem takeSnapshot = new MenuItem("Take Snapshot"); takeSnapshot.setOnAction(new EventHandler<ActionEvent>() { public void handle(final ActionEvent e) { } }); MenuItem mirror = new MenuItem("Mirror"); mirror.setOnAction(new EventHandler<ActionEvent>() { public void handle(final ActionEvent e) { videoScreen.mirror(!videoScreen.getMirrorFlag()); } }); MenuItem flip = new MenuItem("Flip"); flip.setOnAction(new EventHandler<ActionEvent>() { public void handle(final ActionEvent e) { videoScreen.flip(!videoScreen.getFlipFlag()); } }); ObservableList<MenuItem> items = popup.getItems(); items.add(takeSnapshot); items.add(new SeparatorMenuItem()); items.add(mirror); items.add(flip); items.add(new SeparatorMenuItem()); for (IWebcam.FrameFormat format : supportedFormats) { MenuItem mi = new MenuItem("" + format.width + "x" + format.height); mi.setOnAction(new SetWebcamFrameFormatEventHandler(executor, webcam, format)); items.add(mi); } popup.setAutoHide(true); popup.setHideOnEscape(true); popup.show(videoScreen, event.getScreenX(), event.getScreenY()); } }); stage.setOnCloseRequest(new EventHandler<WindowEvent>() { public void handle(final WindowEvent event) { webcam.close(); } }); stage.show(); } }); } catch (Exception ex) { ex.printStackTrace(); } } }); } }; // fields private ExecutorService executor = null; // ui private ChoiceBox<IWebcam> webcamChoiceBox; // Application implementation /** * Constructor. */ public ExJfxNativeAccessWebcam() { } @Override public void init() throws Exception { super.init(); executor = Executors.newSingleThreadExecutor(); } @Override public void start(Stage stage) throws Exception { Scene scene = new Scene(createComponents()); stage.setResizable(false); stage.setScene(scene); stage.setTitle("Webcam capture options"); new EnumerateWebcamsEventHandler().handle(null); stage.sizeToScene(); stage.show(); } @Override public void stop() throws Exception { executor.shutdown(); super.stop(); } // inner use methods /** * Creates and places components(class fields) in the container. * * @return components container */ private Parent createComponents() { webcamChoiceBox = new ChoiceBox<IWebcam>(); webcamChoiceBox.setFocusTraversable(false); webcamChoiceBox.setPrefWidth(240); BorderPane layout = new BorderPane(); Button webcamsButton = new Button("Webcams"); Button openButton = new Button("Open"); webcamsButton.setFocusTraversable(false); webcamsButton.setOnAction(new EnumerateWebcamsEventHandler()); openButton.setFocusTraversable(false); openButton.setOnAction(new OpenWebcamEventHandler()); BorderPane.setMargin(webcamsButton, new Insets(8, 8, 8, 8)); BorderPane.setMargin(openButton, new Insets(8, 8, 8, 8)); layout.setLeft(webcamsButton); layout.setCenter(webcamChoiceBox); layout.setRight(openButton); return layout; } }