package org.myrobotlab.service;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import org.bytedeco.javacv.IPCameraFrameGrabber;
import org.myrobotlab.framework.Service;
import org.myrobotlab.framework.ServiceType;
import org.myrobotlab.image.SerializableImage;
import org.myrobotlab.logging.Level;
import org.myrobotlab.logging.LoggerFactory;
import org.myrobotlab.logging.Logging;
import org.myrobotlab.logging.LoggingFactory;
import org.slf4j.Logger;
/**
* IPCamera - a service to allow streaming of video from an IP based camera.
*
* Android related -
* http://stackoverflow.com/questions/8301543/android-bitmap-to-bufferedimage
* Bitmap to BufferedImage - conversion once Bitmap class is serialized
*/
public class IpCamera extends Service {
public class VideoProcess implements Runnable {
@Override
public void run() {
try {
grabber.start();
capturing = true;
while (capturing) {
BufferedImage bi = grabber.grabBufferedImage();
log.debug("grabbed");
if (bi != null) {
log.debug("publishDisplay");
invoke("publishDisplay", new Object[] { getName(), bi });
}
}
} catch (Exception e) {
logException(e);
}
}
}
private static final long serialVersionUID = 1L;
transient private IPCameraFrameGrabber grabber = null;
transient private Thread videoProcess = null;
public String controlURL;
private boolean capturing = false;
private boolean enableControls = true;
public final static Logger log = LoggerFactory.getLogger(IpCamera.class.getCanonicalName());
public final static int FOSCAM_MOVE_UP = 0;
public final static int FOSCAM_MOVE_STOP_UP = 1;
public final static int FOSCAM_MOVE_DOWN = 2;
public final static int FOSCAM_MOVE_STOP_DOWN = 3;
public final static int FOSCAM_MOVE_LEFT = 4;
public final static int FOSCAM_MOVE_STOP_LEFT = 5;
public final static int FOSCAM_MOVE_RIGHT = 6;
public final static int FOSCAM_MOVE_STOP_RIGHT = 7;
public final static int FOSCAM_MOVE_CENTER = 25;
public final static int FOSCAM_MOVE_VERTICLE_PATROL = 26;
public final static int FOSCAM_MOVE_STOP_VERTICLE_PATROL = 27;
public final static int FOSCAM_MOVE_HORIZONTAL_PATROL = 28;
public final static int FOSCAM_MOVE_STOP_HORIZONTAL_PATROL = 29;
public final static int FOSCAM_MOVE_IO_OUTPUT_HIGH = 94;
public final static int FOSCAM_MOVE_IO_OUTPUT_LOW = 95;
public final static int FOSCAM_ALARM_MOTION_ARMED_DISABLED = 0;
public final static int FOSCAM_ALARM_MOTION_ARMED_ENABLED = 1;
public final static int FOSCAM_ALARM_MOTION_SENSITIVITY_HIGH = 0;
public final static int FOSCAM_ALARM_MOTION_SENSITIVITY_MEDIUM = 1;
public final static int FOSCAM_ALARM_MOTION_SENSITIVITY_LOW = 2;
public final static int FOSCAM_ALARM_MOTION_SENSITIVITY_ULTRALOW = 3;
public final static int FOSCAM_ALARM_INPUT_ARMED_DISABLED = 0;
public final static int FOSCAM_ALARM_INPUT_ARMED_ENABLED = 1;
public final static int FOSCAM_ALARM_MAIL_DISABLED = 0;
public final static int FOSCAM_ALARM_MAIL_ENABLED = 1;
public static void main(String[] args) {
LoggingFactory.init(Level.INFO);
try {
IpCamera foscam = new IpCamera("foscam");
foscam.startService();
foscam.startService();
GUIService gui = new GUIService("gui");
gui.startService();
} catch (Exception e) {
Logging.logError(e);
}
}
public final static SerializableImage publishFrame(String source, BufferedImage img) {
SerializableImage si = new SerializableImage(img, source);
return si;
}
public IpCamera(String n) {
super(n);
}
/**
* method to determine connectivity of a valid host, user & password to a
* foscam camera.
*
* @return
*/
/*
* public String getStatus() { StringBuffer ret = new StringBuffer(); try {
*
* URL url = new URL("http://" + host + "/get_status.cgi?user=" + user +
* "&pwd=" + password); log.debug("getStatus " + url); URLConnection con =
* url.openConnection(); BufferedReader in = new BufferedReader(new
* InputStreamReader(con.getInputStream())); String inputLine;
*
* // TODO - parse for good info
*
* while ((inputLine = in.readLine()) != null) { ret.append(inputLine); }
* in.close();
*
* log.debug(String.format("%d",ret.indexOf("var id")));
*
* if (ret.indexOf("var id") != -1) { ret = new StringBuffer("connected"); }
* else { } } catch (Exception e) { ret.append(e.getMessage());
* logException(e); } return ret.toString(); }
*/
public void capture() {
if (videoProcess != null) {
capturing = false;
videoProcess = null;
}
videoProcess = new Thread(new VideoProcess(), getName() + "_videoProcess");
videoProcess.start();
}
// "http://" + host + "/videostream.cgi?user=" + user + "&pwd=" + password
public boolean connectVideoStream(String url) throws MalformedURLException {
grabber = new IPCameraFrameGrabber(url);
// invoke("getStatus");
capture();
return true;
}
/*
* public String setAlarm(int armed, int sensitivity, int inputArmed, int
* ioLinkage, int mail, int uploadInterval) { StringBuffer ret = new
* StringBuffer(); try {
*
* URL url = new URL("http://" + host + "/set_alarm.cgi?motion_armed=" + armed
* + "user=" + user + "&pwd=" + password); URLConnection con =
* url.openConnection(); BufferedReader in = new BufferedReader(new
* InputStreamReader(con.getInputStream())); String inputLine;
*
* while ((inputLine = in.readLine()) != null) { ret.append(inputLine); }
* in.close(); } catch (Exception e) { logException(e); } return
* ret.toString(); }
*/
public String move(Integer param) {
if (!enableControls) {
return null;
}
log.info("move " + param);
StringBuffer ret = new StringBuffer();
try {
// TODO - re-use connection optimization
// URL url = new URL("http://" + host +
// "/decoder_control.cgi?command=" + param + "&user=" + user +
// "&pwd=" + password);
URL url = new URL(controlURL + param);
URLConnection con = url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
ret.append(inputLine);
}
in.close();
} catch (Exception e) {
logException(e);
// connectVideoStream(host, user, password);
}
return ret.toString();
}
public SerializableImage publishDisplay(String source, BufferedImage img) {
return new SerializableImage(img, source);
}
public void setControlURL(String url) {
controlURL = url;
}
public Boolean setEnableControls(Boolean v) {
enableControls = v;
return v;
}
public void stopCapture() {
capturing = false;
if (videoProcess != null) {
capturing = false;
videoProcess = null;
}
}
/**
* This static method returns all the details of the class without it having
* to be constructed. It has description, categories, dependencies, and peer
* definitions.
*
* @return ServiceType - returns all the data
*
*/
static public ServiceType getMetaData() {
ServiceType meta = new ServiceType(IpCamera.class.getCanonicalName());
meta.addDescription("control and video stream capture for generic ip camera");
meta.addCategory("video");
// FIXME - should be webcam dependency not opencv !
// meta.addDependency("org.bytedeco.javacpp","1.1");
meta.addDependency("org.bytedeco.javacv", "1.1");
return meta;
}
}