package org.geogebra.web.web.gui.dialog.image; import org.geogebra.common.GeoGebraConstants.Versions; import org.geogebra.common.main.Localization; import org.geogebra.web.html5.Browser; import org.geogebra.web.html5.main.AppW; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.dom.client.Element; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.VerticalPanel; /** * Panel for HTML5 webcam input */ public class WebCamInputPanel extends VerticalPanel { private SimplePanel inputWidget; private Element video; private JavaScriptObject stream; private int canvasWidth = 640, canvasHeight = 480;// overwritten by real // dimensions private AppW app; private static final int MAX_CANVAS_WIDTH = 640; /** * @param app * application */ public WebCamInputPanel(AppW app) { this.app = app; initGUI(); } private void initGUI() { inputWidget = new SimplePanel(); resetVideo(); add(inputWidget); } private native Element populate(Element el, String message, String errorMessage) /*-{ el.style.position = "relative"; var ihtml = "<span style='position:absolute;width:213px;height:160px;text-align:center;'><br><br>" + message + "</span>\n"; ihtml += "<video width='213' height='160' autoplay><br><br>" + errorMessage + "</video>"; el.innerHTML = ihtml; var video = el.lastChild; $wnd.navigator.getMedia = ($wnd.navigator.getUserMedia || $wnd.navigator.webkitGetUserMedia || $wnd.navigator.mozGetUserMedia || $wnd.navigator.msGetUserMedia); $wnd.URL = $wnd.URL || $wnd.webkitURL || $wnd.msURL || $wnd.mozURL || $wnd.oURL || null; var that = this; if ($wnd.navigator.getMedia) { try { $wnd.navigator .getMedia( { video : true }, function(bs) { if ($wnd.URL && $wnd.URL.createObjectURL) { video.src = $wnd.URL .createObjectURL(bs); el.firstChild.style.display = "none"; } else { video.src = bs; el.firstChild.style.display = "none"; } that.@org.geogebra.web.web.gui.dialog.image.WebCamInputPanel::stream = bs; }, function(err) { @org.geogebra.common.util.debug.Log::debug(Ljava/lang/String;)("Error from WebCam: "+err); }); return video; } catch (e) { el.firstChild.innerHTML = "<br><br>" + errorMessage; return null; } } else { el.firstChild.innerHTML = "<br><br>" + errorMessage; } return null; }-*/; private native String shotcapture(Element video1) /*-{ var canvas = $doc.createElement("canvas"); canvas.width = Math .max(video1.videoWidth || 0, @org.geogebra.web.web.gui.dialog.image.WebCamInputPanel::MAX_CANVAS_WIDTH); canvas.height = video1.videoHeight ? Math.round(canvas.width * video1.videoHeight / video1.videoWidth) : 0.75 * @org.geogebra.web.web.gui.dialog.image.WebCamInputPanel::MAX_CANVAS_WIDTH; var ctx = canvas.getContext('2d'); ctx.drawImage(video1, 0, 0); this.@org.geogebra.web.web.gui.dialog.image.WebCamInputPanel::stopVideo()(); this.@org.geogebra.web.web.gui.dialog.image.WebCamInputPanel::canvasWidth = canvas.width; this.@org.geogebra.web.web.gui.dialog.image.WebCamInputPanel::canvasHeight = canvas.height; return canvas.toDataURL('image/png'); }-*/; /** * Stop recording */ public native void stopVideo() /*-{ var stream = this.@org.geogebra.web.web.gui.dialog.image.WebCamInputPanel::stream; if (stream == null) { return; } if (stream.stop) { stream.stop(); } else { stream.getVideoTracks()[0].stop(); } stream = null; }-*/; /** * @return screenshot as data URL (png) */ public String getImageDataURL() { if (video == null) { return null; } return shotcapture(video); } /** * Starts recording */ public void startVideo() { stopVideo(); inputWidget.getElement().removeAllChildren(); resetVideo(); } private void resetVideo() { Localization loc = app.getLocalization(); String message; if (app.getVersion() == Versions.WEB_FOR_DESKTOP) { message = ""; } else if (Browser.isFirefox()) { message = loc.getMenu("Webcam.Firefox"); }else if(Browser.isEdge()){ message = loc.getMenu("Webcam.Edge"); }else{ message = loc.getMenu("Webcam.Chrome"); } video = populate(inputWidget.getElement(), message, loc.getMenu("Webcam.Problem")); } /** * @return screenshot width */ public int getCanvasWidth() { return canvasWidth; } /** * @return screenshot height */ public int getCanvasHeight() { return canvasHeight; } }