Raspivid dans une fenetre Java

Vous avez réalisé ou vous voulez réaliser un truc impensable avec votre Raspberry Pi ? Cet endroit est pour vous...

Modérateur : Francois

Répondre
francois_dode
Messages : 4
Enregistré le : jeu. 29 oct. 2015 15:40

Raspivid dans une fenetre Java

Message par francois_dode » jeu. 29 oct. 2015 15:48

Bonjour a tous,

J'aimerais pouvoir envoyer la vidéo de la fonction raspivid dans une fenêtre java. Lorsqu’on utilise "raspivid -o -" cela redirige la video vers la sortie standard (stdout).
Mon idée serais de redirigé cette sortie vers une JFrame ou JPanel.
J'ai déjà essayer plusieurs méthode comme jvlc ou JavaFX mais rien ne fonctionne.
J'ai également vu qu'on pouvait se servir de omxplayer mais je ne vois pas comment rediriger la sortie de omxplayer dans une fenêtre java.
Merci pour votre future aide.

francois_dode
Messages : 4
Enregistré le : jeu. 29 oct. 2015 15:40

Re: Raspivid dans une fenetre Java

Message par francois_dode » jeu. 5 nov. 2015 13:52

Up

Avatar du membre
vague nerd
Modérateur
Messages : 1473
Enregistré le : mar. 14 oct. 2014 11:42
Localisation : France !

Re: Raspivid dans une fenetre Java

Message par vague nerd » mer. 11 nov. 2015 17:58

+1
Cordialement,

Vague Nerd

francois_dode
Messages : 4
Enregistré le : jeu. 29 oct. 2015 15:40

Re: Raspivid dans une fenetre Java

Message par francois_dode » mar. 17 nov. 2015 12:20

Après plusieurs recherche j'ai trouvé la solution !! :)
J'arrive a obtenir le vidéo sous la forme d'un JLabel que je peux ajouter a un JPanel.

Il faut tout d'abord installer v4l4j sur le Raspberry en suivant les instructions ici : https://code.google.com/p/v4l4j/wiki/Ge ... artedOnRPi

Les différents programme sont compilé sur le Raspberry via ssh a partir de NetBeans sur un PC.
Bien penser a importer la librairie v4l4j.jar dans le projet NetBeans.

Voila la classe principale :

Code : Tout sélectionner

import java.awt.BorderLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

/**
 *
 * @author Utilisateur1
 */
public class NewClass extends WindowAdapter{

    private JFrame frame;
    private SimpleViewer test;


    public static void main(String args[]) {

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new NewClass();
            }
        });
    }

    public NewClass() {
        frame = new JFrame(); 
        test = new SimpleViewer();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.addWindowListener(this);
        frame.setVisible(true);
        frame.setSize(640, 480);
        
        frame.setLayout(new BorderLayout());
       
        frame.getContentPane().add(test.getLabel(), BorderLayout.CENTER);
         //frame.add(label);
 

    }
    
           /**
         * Catch window closing event so we can free up resources before exiting
         * @param e
         */
        public void windowClosing(WindowEvent e) {
                test.cleanupCapture();

                // close window
                frame.removeAll();
        }
}
Et la classe permettant de récuperer le flux video et de le mettre dans un JLabel :

Code : Tout sélectionner

import javax.swing.JLabel;

import au.edu.jcu.v4l4j.FrameGrabber;
import au.edu.jcu.v4l4j.CaptureCallback;

import au.edu.jcu.v4l4j.VideoDevice;
import au.edu.jcu.v4l4j.VideoFrame;
import au.edu.jcu.v4l4j.exceptions.StateException;
import au.edu.jcu.v4l4j.exceptions.V4L4JException;

/**
 * This class demonstrates how to perform a simple push-mode capture. It starts
 * the capture and display the video stream in a JLabel
 *
 * @author gilles
 *
 */
public class SimpleViewer implements CaptureCallback {

    private static int width = 640, height = 480, std = 0, channel = 0;
    private static String device = "/dev/video0";

    private VideoDevice videoDevice;
    private FrameGrabber frameGrabber;

    private JLabel label;

    /**
     * Builds a WebcamViewer object
     *
     * @throws V4L4JException if any parameter if invalid
     */
    public SimpleViewer() {

        // Initialise video device and frame grabber
        try {
            initFrameGrabber();
        } catch (V4L4JException e1) {
            System.err.println("Error setting up capture");
            e1.printStackTrace();

            // cleanup and exit
            cleanupCapture();
            return;
        }

        // create and initialise UI
        initGUI();

        // start capture
        try {
            frameGrabber.startCapture();
        } catch (V4L4JException e) {
            System.err.println("Error starting the capture");
            e.printStackTrace();
        }
    }

    /**
     * Initialises the FrameGrabber object
     *
     * @throws V4L4JException if any parameter if invalid
     */
    private void initFrameGrabber() throws V4L4JException {
        videoDevice = new VideoDevice(device);
        frameGrabber = videoDevice.getJPEGFrameGrabber(width, height, channel, std, 80);
        frameGrabber.setCaptureCallback(this);
        width = frameGrabber.getWidth();
        height = frameGrabber.getHeight();
        System.out.println("Starting capture at " + width + "x" + height);
    }

    /**
     * Creates the UI components and initialises them
     */
    private void initGUI() {

        label = new JLabel();

    }

    /**
     * this method stops the capture and releases the frame grabber and video
     * device
     */
    protected void cleanupCapture() {
        try {
            frameGrabber.stopCapture();
        } catch (StateException ex) {
                        // the frame grabber may be already stopped, so we just ignore
            // any exception and simply continue.
        }

        // release the frame grabber and video device
        videoDevice.releaseFrameGrabber();
        videoDevice.release();
    }

    @Override
    public void exceptionReceived(V4L4JException e) {
                // This method is called by v4l4j if an exception
        // occurs while waiting for a new frame to be ready.
        // The exception is available through e.getCause()
        e.printStackTrace();
    }

    @Override
    public void nextFrame(VideoFrame frame) {
                // This method is called when a new frame is ready.
        // Don't forget to recycle it when done dealing with the frame.

        // draw the new frame onto the JLabel
        label.getGraphics().drawImage(frame.getBufferedImage(), 0, 0, width, height, null);

        // recycle the frame
        frame.recycle();
    }

    public JLabel getLabel() {
        return label;
    }

    public static int getWidth() {
        return width;
    }

    public static int getHeight() {
        return height;
    }

}
une fois le programme compilé par NetBeans, il créer un fichier jar sur le Raspberry (par défaut /home/pi/NetBeansProjects/<nom du projet>/dist).
une fois dans le répertoire exécuter la commande

Code : Tout sélectionner

java -Djava.library.path=/usr/lib/jni -jar <nom du fichier>.jar 

Avatar du membre
vague nerd
Modérateur
Messages : 1473
Enregistré le : mar. 14 oct. 2014 11:42
Localisation : France !

Re: Raspivid dans une fenetre Java

Message par vague nerd » ven. 20 nov. 2015 19:15

Super, merci du partage, j'ai hâte d'essayer.
Y a t il des soucis de latence ?
Cdt.
Cordialement,

Vague Nerd

francois_dode
Messages : 4
Enregistré le : jeu. 29 oct. 2015 15:40

Re: Raspivid dans une fenetre Java

Message par francois_dode » lun. 30 nov. 2015 09:09

Non aucun de soucis de latence quand l'application est directement lancé sur le raspberry.
En ssh par contre il y a de très fortes latences.

Répondre

Retourner vers « Utilisateurs avancés »