IP-Cam live stream speichern

David84

Mitglied
Hi zusammen.

Ich arbeite seit ca 3 Monaten an meinem Schulprojekt wo man über eine Java Software den Stream der Camera anzeigen und speichern kann. Den Stream kann ich mittlerweile in meiner GUI anzeigen und einzelne Bilder abspeichern. wenn ich aber den kompletten Stream speichern möchte stürzt das komplette Programm ab. In den Ordner wo der Stream gespeichert werden soll wird eine .mpeg Datei erstellt aber beim abspielen ist es wenn da nur so wie ein bild vorhanden wäre.

Könnt ihr mir da bitte weiterhelfen da ich im Internet leider zu diesem Thema keine Informationen gefunden habe.

den Sourcecode vom Button habe ich mit eingefügt vielleicht hat jemand eine Idee.

Gruß David
Java:
btnVideoSave = new JButton("Video speichern");
        btnVideoSave.addActionListener(new ActionListener() {
        	public void actionPerformed(ActionEvent e) {
        		BufferedInputStream stream = null;
                FileOutputStream fos = null;
                Thread thisThread = Thread.currentThread();
                try {
                    Date dt = new Date();
                    SimpleDateFormat dtformat = new SimpleDateFormat("dd.MM.yyyy 'at' HH.mm.ss");// Datumsformat festlegen
                    URL url = new URL("http://" + Daten[0] + ":" + Daten[1]);
                    URLConnection conn = url.openConnection();
                    stream = new BufferedInputStream(conn.getInputStream());
                    
                    fos = new FileOutputStream(Daten[4] + "\\"+ dtformat.format(dt) +".mjpg");
                    
                    // Die ausgelesenen Daten liegen als byte vor, nicht als char
                    byte  buffer[] = new byte[256];
                    int   nbytes ;
                    
                    /*
                     * Hier wird nicht immer nur ein byte gelesen, sondern gleich
                     * maximal 256. Bringt bessere Performance.
                     */
                    while((nbytes=stream.read(buffer, 0, 256)) != 1) { 
                        fos.write(buffer, 0, nbytes);
                    }
                    
                    /*
                     * Buffer leeren, Speicher freigeben
                     */
                    buffer = null;
                } catch(IOException e1) {
                    e1.printStackTrace();
                } finally {
                    /*
                     * Die Streams schließen, egal ob Exception kommt oder nicht
                     */
                    if(fos != null) {
                        try {
                            fos.close();
                        } catch (IOException e1) {
                            e1.printStackTrace();
                        }
                    }
                    
                    if(stream != null) {
                        try {
                            stream.close();
                        } catch (IOException e1) {
                            e1.printStackTrace();
                        }
                    }
                }

        	}
        });
        btnVideoSave.setBounds(670, 327, 89, 23);
        getContentPane().add(btnVideoSave);
 
wie dein programm stürzt ab ? ... ach so ... du meinst es "friert ein" ... na is doch auch ganz klar : du blockierst den EDT

korrekter weise arbeitet man mit events in etwa so

Java:
public void actionPerformed(ActionEvent e)
{
	(new Thread(new Runnable()
	{
		public void run()
		{
			// ... verarbeiten des events
			SwingUtilities.invokeLater(new Runnable()
			{
				public void run()
				{
					// ... ergebnis-meldung durch ändern der GUI
				}
			});
		}
	})).start();
}

du musst deine i/o-ops in einen thread auslagern ... und wenn du dann wieder die gui manipulieren willst dies wieder in den edt einglieder ...

frag noch mal google wie man richtig mit gui's und events umgeht
 
ein s***** wird es auf der gelinkten seite erklärt ... dort ist nichts davon zu finden das man i/o-ops in nem neuen thread auslagern muss .. geschweige denn ein sample ... sondern nur wie man über die event-queue wieder daten in den edt einspeist ...
 
Ja du hast recht das Programm friert ein, so das man nichts mehr machen kann.

Wie baue ich das richtig in so einen Thread ein?

Ich will z.B. mit dem Speichern Button den stream speichern und dann noch einen Stop Button.

Thread bedeutet soviel wie Nebenläufigkeit oder?
Sprich das z.B. zwei Threads parallel laufen.
 
ein s***** wird es auf der gelinkten seite erklärt ... dort ist nichts davon zu finden das man i/o-ops in nem neuen thread auslagern muss .. geschweige denn ein sample ... sondern nur wie man über die event-queue wieder daten in den edt einspeist ...

brems dich mal etwas ein :noe:

Der TO hat ja allen anscheins nach nicht umbedingt viel Ahnung von Threads, also wäre doch eine Allgemeine Erklärung wie man üblicherweise mit GUI und lang andauernder Operationen umgeht sinnvoll, oder nicht? Ein Sample ist im Link nicht, hab ich auch nicht gesagt. Aber es wird gut erklärt wie man lang andauernde Aktionen normalerweise durchführt.

So a classic example is that you need to run a long running operation like downloading a file. So you launch a thread to perform this action then when it is completed you will use invokeLater to update the UI. If you didn't use invokeLater and instead you just updated the ui directly you might have a race condition and undefined behavior could occur.
 
Ich habe jetzt den code etwas angepasst aber bekomme folgende fehlermeldung:
Java:
Exception in thread "Thread-4" java.lang.NullPointerException
	at RaspiSpy.VideoSpeichern.run(VideoSpeichern.java:27)
	at java.lang.Thread.run(Unknown Source)

Der Code sind so aus in der Main:
Java:
        btnVideoSave = new JButton("Video speichern");
        btnVideoSave.addActionListener(new ActionListener() {
        	public void actionPerformed(ActionEvent e) {
        	    VideoSpeichern video = new VideoSpeichern();
        	    VideoSpeichern = new Thread(video);
        	    VideoSpeichern.start();
        		
        	}
        });
        btnVideoSave.setBounds(670, 327, 89, 23);
        getContentPane().add(btnVideoSave);

und das Ist die VideoSpeichern klasse:

Java:
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;

import java.text.SimpleDateFormat;
import java.util.Date;

public class VideoSpeichern implements Runnable {

   	String Daten[];

    
    public void run(){
        //Thread thisThread = Thread.currentThread();
        
 
    	BufferedInputStream stream = null;
        FileOutputStream fos = null;
    	
        try {
        Date dt = new Date();
        SimpleDateFormat dtformat = new SimpleDateFormat("dd.MM.yyyy 'at' HH.mm.ss");// Datumsformat festlegen
        URL url = new URL("http://" + Daten[0] + ":" + Daten[1]);
        URLConnection conn = url.openConnection();
        stream = new BufferedInputStream(conn.getInputStream());
        
        fos = new FileOutputStream(Daten[4] + "\\"+ dtformat.format(dt) +".mpeg");
        
        // Die ausgelesenen Daten liegen als byte vor, nicht als char
        byte  buffer[] = new byte[256];
        int   nbytes ;
        
        /*
         * Hier wird nicht immer nur ein byte gelesen, sondern gleich
         * maximal 256. Bringt bessere Performance.
         */
        while((nbytes=stream.read(buffer, 0, 256)) != 1) { 
            fos.write(buffer, 0, nbytes);
        }
        
        /*
         * Buffer leeren, Speicher freigeben
         */
        buffer = null;
    } catch(IOException e1) {
        e1.printStackTrace();
    } finally {
        /*
         * Die Streams schließen, egal ob Exception kommt oder nicht
         */
        if(fos != null) {
            try {
                fos.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
        
        if(stream != null) {
            try {
                stream.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    }


}}
 
Habe nun das Problem das die Software einfriert gelöst aber wenn ich die Aufnahme starte nimmt das Programm eine video auf das wird auch größer von der MByte desto länger es aufnimmt. Aber bei Abspielen sieht es so aus als ob das Programm nur paar Millisekunden aufnimmt. Hat jemand ne idee wo der fehler liegen könnte?

Java:
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;

import java.text.SimpleDateFormat;
import java.util.Date;

public class VideoSpeichern implements Runnable {

   	String Daten[];
   	
   	public VideoSpeichern(String [] Daten){
   		
   		this.Daten = Daten;
   	}

    
    public void run(){
        //Thread thisThread = Thread.currentThread();
        
 
    	BufferedInputStream stream = null;
        FileOutputStream fos = null;
    	
        try {
            Date dt = new Date();
            SimpleDateFormat dtformat = new SimpleDateFormat("dd.MM.yyyy 'at' HH.mm.ss");// Datumsformat festlegen
            URL url = new URL("http://" + Daten[0] + ":" + Daten[1]);
            URLConnection conn = url.openConnection();
            stream = new BufferedInputStream(conn.getInputStream());
            
            fos = new FileOutputStream(Daten[4] + "\\"+ dtformat.format(dt) +".mpeg");
            
            // Die ausgelesenen Daten liegen als byte vor, nicht als char
            byte  buffer[] = new byte[256];
            int   nbytes ;
            
            /*
             * Hier wird nicht immer nur ein byte gelesen, sondern gleich
             * maximal 256. Bringt bessere Performance.
             */
            while((nbytes=stream.read(buffer, 0, 256)) != 1) { 
                fos.write(buffer, 0, nbytes);
            }
            
            /*
             * Buffer leeren, Speicher freigeben
             */
            buffer = null;
    } catch(IOException e1) {
        e1.printStackTrace();
    } finally {
        /*
         * Die Streams schließen, egal ob Exception kommt oder nicht
         */
        if(fos != null) {
            try {
                fos.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
        
        if(stream != null) {
            try {
                stream.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    }


}}
 
spontan : weil weder format noch start und ende definiert werden ... was aber für ein späteres abspielen eines "abgeschlossenen" video-files nötig ist ...


einfach mal so irgendeinen stream "wegcapturen" geht halt nicht
 

Zurück
Oben