package webcam; // Klasse gehˆrt zum Paket webcam
//Import der benˆtigten Pakete
import java.io.*;
import java.net.*;
import java.awt.*;
import javax.swing.*;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageDecoder;
//Die Klasse wird erweiter durch JPanel und ist abgeleitet von Runnable
public class MJPG extends JPanel implements Runnable
{
// Definition der Attribute
public boolean useMJPGStream = true;
public boolean connected = false;
private boolean initCompleted = false;
public String jpgURL;
public String mjpgURL;
private String username;
private String password;
private String base64authorization = null;
private Image image = null;
public Dimension imageSize = null;
DataInputStream dis;
HttpURLConnection huc = null;
public MJPG (String Daten[]) // Konstruktor
{
// ‹bergebene Daten werden den Variablen zugewiflen
mjpgURL = "http://" + Daten[0] + "/videostream.cgi";
jpgURL = "http://" + Daten[0] + "/videostream.cgi";
username = Daten[4];
password = Daten[1];
// Benutze Benutzer und Passwort nur wenn sie gegeben sind
if(username == null || password == null) // Wenn eine der Variablen leer ist
{
System.out.println("Kein Benutzer angegeben!"); // Gibt eine Meldung auf der Konsole aus
}
else
{
// Ruft eine Methode auf und speichert deren R¸ckgabewert in eine Variable
base64authorization = this.encodeUsernameAndPasswordInBase64(username, password);
}
}
// Verschl¸sselt Benutzer und Passwort
private String encodeUsernameAndPasswordInBase64(String usern, String psswd)
{
String s = usern + ":" + psswd; // Benutzername und Passwort in eine Variable schreiben
String encs = new sun.misc.BASE64Encoder().encode(s.getBytes()); // Verschl¸sselung des Strings
return "Basic " + encs; // Wert zur¸ckgeben
}
// Verbindung zur Kamera aufbauen
public void connect()
{
try // Versuche
{
URL u = new URL(useMJPGStream?mjpgURL:jpgURL); // Ein neues URL objekt wird erstellt
// Es wird eine URL Verbindung mit speziellen HTTP Methoden erzeugt
huc = (HttpURLConnection) u.openConnection();
// Wenn die Verschl¸sselung stattgefunden hat
if(base64authorization != null) // Wenn die Variable ungleich null ist
{
huc.setDoInput(true); // Benutze die URLConnection als Eingabe benutzt
// Benutzer und Passwort benutzen
huc.setRequestProperty("Authorization",base64authorization);
huc.connect(); // Die Verbindung wird geˆffnet
}
InputStream is = huc.getInputStream(); // Es wird von der geˆffneten Verbindung gelesen
connected = true; // Wert der Variable setzen
BufferedInputStream bis = new BufferedInputStream(is); // Ein Lesepuffer wird verwendet
// Stellt Routinen zur Verf¸gung, mit denen Werte der Standarddatentypen aus
// einem Stream gelesen werden kˆnnen
dis = new DataInputStream(bis);
if (!initCompleted) // Wenn Variable false ist
{
initDisplay(); // Methode aufrufen
}
}
// Bei einem Fehler wird nochmals probiert eine Verbindung herzustellen
catch(IOException e) // Wird ausgef¸hrt wenn ein Fehler stattgefunden hat
{
try // Versuche
{
huc.disconnect(); // HTTPURLConnection trennen
Thread.sleep(60); // Thread schlafen lassen
}
catch(InterruptedException ie) // Beim einem Fehler
{
huc.disconnect(); // // HTTPURLConnection trennen
connect(); // Methode aufrufen
}
connect(); // Methode aufrufen
}
catch(Exception e) // Bei einem Fehler
{
}
}
// Anzeige einstellen
public void initDisplay()
{
if (useMJPGStream) // Wenn der MJPG Stream verwendet wird
{
readMJPGStream(); // Methode aufrufen
}
else // Wenn der JPG Bilder verwendet werden
{
readJPG(); // Methode aufrufen
disconnect(); // Methode aufrufen
}
imageSize = new Dimension(image.getWidth(this), image.getHeight(this)); // Bildgrˆfle wird ermittelt
setPreferredSize(imageSize); // Grˆfle des JPanel wird gesetzt
initCompleted = true; // Variable wird auf true gesetzt
}
// DataInputStream trennen
public void disconnect()
{
try // Versuche
{
if(connected) // Wenn Verbindung zur Kamera vorhanden
{
dis.close(); // DataInputStream wird geschlossen
connected = false; // Variable wird auf false gesetzt
}
}
catch(Exception e) // Bei einem Fehler
{
}
}
// Bild auf JPanel zeichnen
public void paint(Graphics g)
{
if (image != null) // Wenn Bild in Variable gespeichert
{
g.drawImage(image, 0, 0, this); // Bild auf das Panel setzen
}
}
// Methode um st‰ndig den Stream zu lesen
public void readStream()
{
try // Versuche
{
if (useMJPGStream) // Wenn MJPG Stream verwendet wird
{
while(true) // Endlosschleife
{
readMJPGStream(); // Methode aufrufen
repaint(); // Bild neu zeichnen
}
}
else // Wenn JPG Bilder verwendet werden
{
while(true) // Endlosschleife
{
connect(); // Methode aufrufen
readJPG(); // Methode aufrufen
repaint(); // Methode aufrufen
disconnect(); // Methode aufrufen
}
}
}
catch(Exception e) // Bei einem Fehler
{
}
}
// Bild aus dem Stream lesen
public void readMJPGStream()
{
readLine(4,dis); // Verwirft die ersten 4 Linien ab
readJPG(); // Methode aufrufen
readLine(1,dis); // Verwirft die letzte Linie
}
// Liest das eingebettete Bild
public void readJPG()
{
try // Versuche
{
JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(dis); // JPEG Dekoder erstellen
image = decoder.decodeAsBufferedImage(); // Bild als BufferedImage in Variable speichern
}
catch(Exception e) // Bei einem Fehler wird folgender Code ausgef¸hrt
{
e.printStackTrace(); // Fehler auf Konsole ausgeben
disconnect(); // Methode aufrufen
}
}
// Liest die Linien heraus
public void readLine(int n, DataInputStream dis)
{
for (int i=0; i<n; i++) // Wird so oft ausgef¸hrt so viele Linien man heraus schneiden will
{
readLine(dis); // Methode aufrufen
}
}
// Zeilen lesen
public void readLine(DataInputStream dis)
{
try // Versuche
{
boolean end = false; // Deklaration
String lineEnd = "\n"; // Zeichen f¸r das Ende der Linie
byte[] lineEndBytes = lineEnd.getBytes(); // String in Bytes umwandeln
byte[] byteBuf = new byte[lineEndBytes.length]; // L‰nge von lineEndBytes
while(!end) // Solange end = false
{
dis.read(byteBuf,0,lineEndBytes.length); // Ausschnitt aus dem Stream lesen
String t = new String(byteBuf); // Gelesenes in String schreiben
if(t.equals(lineEnd)) // Wenn Zeilenende erreicht
{
end = true; // Variable aus true setzen
}
}
}
catch(Exception e) // Wird bei einem Fehler ausgef¸hrt
{
e.printStackTrace(); // Fehler auf Konsole ausgeben
}
}
// Hauptmethode wird beim Starten des Threads ausgef¸hrt
public void run()
{
connect(); // Methode aufrufen
readStream(); // Methode aufrufen
}
// Getter Methode f¸r die Screenshot-Funktion
public Image getImage()
{
return image; // Variable image zur¸ckgeben
}
}