import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.sarxos.webcam.Webcam;
@WebSocket
public class WebcamWebSocketHandler {
private static final Logger LOG = LoggerFactory.getLogger(WebcamWebSocketHandler.class);
private static final ObjectMapper MAPPER = new ObjectMapper();
private Session session;
private void teardown() {
try {
session.close();
session = null;
} finally {
WebcamCache.unsubscribe(this);
}
}
private void setup(Session session) {
this.session = session;
Map<String, Object> message = new HashMap<String, Object>();
message.put("type", "list");
message.put("webcams", WebcamCache.getWebcamNames());
send(message);
WebcamCache.subscribe(this);
}
@OnWebSocketClose
public void onClose(int status, String reason) {
LOG.info("WebSocket closed, status = {}, reason = {}", status, reason);
teardown();
}
@OnWebSocketError
public void onError(Throwable t) {
LOG.error("WebSocket error", t);
teardown();
}
@OnWebSocketConnect
public void onConnect(Session session) {
LOG.info("WebSocket connect, from = {}", session.getRemoteAddress().getAddress());
setup(session);
}
@OnWebSocketMessage
public void onMessage(String message) {
LOG.info("WebSocket message, text = {}", message);
}
public void newImage(Webcam webcam, BufferedImage image) {
LOG.info("New image from {}", webcam);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ImageIO.write(image, "JPG", baos);
} catch (IOException e) {
LOG.error(e.getMessage(), e);
}
String base64 = null;
try {
base64 = new String(Base64.getEncoder().encode(baos.toByteArray()), "UTF8");
} catch (UnsupportedEncodingException e) {
LOG.error(e.getMessage(), e);
}
Map<String, Object> message = new HashMap<String, Object>();
message.put("type", "image");
message.put("webcam", webcam.getName());
message.put("image", base64);
send(message);
}
private void send(String message) {
if (session.isOpen()) {
try {
session.getRemote().sendStringByFuture(message);
} catch (Exception e) {
LOG.error("Exception when sending string", e);
}
}
}
private void send(Object object) {
try {
send(MAPPER.writeValueAsString(object));
} catch (JsonProcessingException e) {
LOG.error(e.getMessage(), e);
}
}
}