-1

How I can manage multiple GoPro cameras at the same time? I want to stream three videos of three GoPro cameras at the same time and record the videos on the hard disk.

I have written a tool in Java for one GoPro and it works correctly.

Help me please!

This is the code:

public class GoProStreamer extends JFrame {

private static final String CAMERA_IP = "10.5.5.9";
private static int PORT = 8080;
private static DatagramSocket mOutgoingUdpSocket;
private Process streamingProcess;
private Process writeVideoProcess;
private KeepAliveThread mKeepAliveThread;

private JPanel contentPane;

public GoProStreamer() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(800, 10, 525, 300);

    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    contentPane.setLayout(new BorderLayout(0, 0));
    setContentPane(contentPane);

    JButton btnStop = new JButton("Stop stream");
    JButton btnStart = new JButton("Start stream");
    JButton btnRec = new JButton("Rec");
    JButton btnStopRec = new JButton("Stop Rec");
    //      JButton btnZoomIn = new JButton("Zoom In sincrono");
    //      JButton btnZoomOut = new JButton("Zoom out sincrono");
    //      JButton btnZoomIn1 = new JButton("Zoom In Camera 1");
    //      JButton btnZoomOut1 = new JButton("Zoom out Camera 1");
    //      JButton btnZoomIn2 = new JButton("Zoom in Camera 2");
    //      JButton btnZoomOut2 = new JButton("Zoom out Camera 2");
    //      JButton btnZoomIn3 = new JButton("Zoom in camera 3");
    //      JButton btnZoomOut3 = new JButton("Zoom out Camera 3");

    btnStop.setEnabled(false);
    btnRec.setEnabled(false);
    btnStopRec.setEnabled(false);
    //      btnZoomIn.setEnabled(false);
    //      btnZoomOut.setEnabled(false);
    //      btnZoomIn1.setEnabled(false);
    //      btnZoomOut1.setEnabled(false);
    //      btnZoomIn2.setEnabled(false);
    //      btnZoomOut2.setEnabled(false);
    //      btnZoomIn3.setEnabled(false);
    //      btnZoomOut3.setEnabled(false);

    JPanel panel = new JPanel();
    //      JPanel panel2 = new JPanel();
    //      JPanel panel3 = new JPanel();
    //      JPanel panel4 = new JPanel();

    panel.add(btnStart);
    panel.add(btnStop);
    panel.add(btnRec);
    panel.add(btnStopRec);
    //      panel2.add(btnZoomIn1);
    //      panel3.add(btnZoomOut1);
    //      panel2.add(btnZoomIn2);
    //      panel3.add(btnZoomOut2);
    //      panel2.add(btnZoomIn3);
    //      panel3.add(btnZoomOut3);
    //      panel4.add(btnZoomIn);
    //      panel4.add(btnZoomOut);

    contentPane.add(panel, BorderLayout.SOUTH);
    //  contentPane.add(panel2, BorderLayout.NORTH);
    //  contentPane.add(panel3, BorderLayout.CENTER);

    btnStart.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            startStreamService();
            keepAlive();
            startStreaming();

            btnStart.setEnabled(false);
            btnStop.setEnabled(true);
            btnRec.setEnabled(true);
            btnStopRec.setEnabled(false);
            //              btnZoomIn.setEnabled(true);
            //              btnZoomOut.setEnabled(true);
            //              btnZoomIn1.setEnabled(true);
            //              btnZoomOut1.setEnabled(true);
            //              btnZoomIn2.setEnabled(true);
            //              btnZoomOut2.setEnabled(true);
            //              btnZoomIn3.setEnabled(true);
            //              btnZoomOut3.setEnabled(true);
        }
    });

    btnStop.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            stopStreaming();
            stopKeepalive();

            btnStart.setEnabled(true);
            btnStop.setEnabled(false);
            btnRec.setEnabled(false);
            btnStopRec.setEnabled(false);
        }
    });

    btnRec.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            startRec();

            btnStart.setEnabled(false);
            btnStop.setEnabled(false);
            btnRec.setEnabled(false);
            btnStopRec.setEnabled(true);
        }
    });

    btnStopRec.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            stopRec();

            btnStart.setEnabled(false);
            btnStop.setEnabled(true);
            btnRec.setEnabled(true);
            btnStopRec.setEnabled(false);
        }
    });
}

private void startStreamService() {
    HttpURLConnection localConnection = null;
    try {
        String str = "http://" + CAMERA_IP + "/gp/gpExec?p1=gpStreamA9&c1=restart";
        localConnection = (HttpURLConnection) new URL(str).openConnection();
        localConnection.addRequestProperty("Cache-Control", "no-cache");
        localConnection.setConnectTimeout(5000);
        localConnection.setReadTimeout(5000);
        int i = localConnection.getResponseCode();
        if (i >= 400) {
            throw new IOException("sendGET HTTP error " + i);
        }
    }
    catch (Exception e) {

    }
    if (localConnection != null) {
        localConnection.disconnect();
    }
}

@SuppressWarnings("static-access")
private void sendUdpCommand(int paramInt) throws SocketException, IOException {
    Locale localLocale = Locale.US;
    Object[] arrayOfObject = new Object[4];
    arrayOfObject[0] = Integer.valueOf(0);
    arrayOfObject[1] = Integer.valueOf(0);
    arrayOfObject[2] = Integer.valueOf(paramInt);
    arrayOfObject[3] = Double.valueOf(0.0D);
    byte[] arrayOfByte = String.format(localLocale, "_GPHD_:%d:%d:%d:%1f\n", arrayOfObject).getBytes();
    String str = CAMERA_IP;
    int i = PORT;
    DatagramPacket localDatagramPacket = new DatagramPacket(arrayOfByte, arrayOfByte.length, new InetSocketAddress(str, i));
    this.mOutgoingUdpSocket.send(localDatagramPacket);
}

private void startStreaming() {
    Thread threadStream = new Thread() {
        @Override
        public void run() {
            try {
                streamingProcess = Runtime.getRuntime().exec("ffmpeg-20150318-git-0f16dfd-win64-static\\bin\\ffplay -i http://10.5.5.9:8080/live/amba.m3u8");
                InputStream errorStream = streamingProcess.getErrorStream();
                byte[] data = new byte[1024];
                int length = 0;
                while ((length = errorStream.read(data, 0, data.length)) > 0) {
                    System.out.println(new String(data, 0, length));
                    System.out.println(System.currentTimeMillis());
                }

            } catch (IOException e) {

            }
        }
    };
    threadStream.start();
}

private void startRec() {
    Thread threadRec = new Thread() {
        @Override
        public void run() {
            try {
                writeVideoProcess = Runtime.getRuntime().exec("ffmpeg-20150318-git-0f16dfd-win64-static\\bin\\ffmpeg -re -i http://10.5.5.9:8080/live/amba.m3u8 -c copy -an Video_GoPro_" + Math.random() + ".avi");
                InputStream errorRec = writeVideoProcess.getErrorStream();
                byte[] dataRec = new byte[1024];
                int lengthRec = 0;
                while ((lengthRec = errorRec.read(dataRec, 0, dataRec.length)) > 0) {
                    System.out.println(new String(dataRec, 0, lengthRec));
                    System.out.println(System.currentTimeMillis());
                }
            } catch (IOException e) {

            }
        }
    };
    threadRec.start();
}

private void keepAlive() {
    mKeepAliveThread = new KeepAliveThread();
    mKeepAliveThread.start();
}

class KeepAliveThread extends Thread {
    public void run() {
        try {
            Thread.currentThread().setName("gopro");
            if (mOutgoingUdpSocket == null) {
                mOutgoingUdpSocket = new DatagramSocket();
            }
            while ((!Thread.currentThread().isInterrupted()) && (mOutgoingUdpSocket != null)) {
                sendUdpCommand(2);
                Thread.sleep(2500L);
            }
        }
        catch (SocketException e) {

        }
        catch (InterruptedException e) {

        }
        catch (Exception e) {

        }
    }
}

private void stopStreaming() {
    if (streamingProcess != null) {
        streamingProcess.destroy();
        streamingProcess = null;
    }
    stopKeepalive();
    mOutgoingUdpSocket.disconnect();
    mOutgoingUdpSocket.close();
}

private void stopRec() {
    writeVideoProcess.destroy();
    writeVideoProcess = null;
}

private void stopKeepalive() {
    if (mKeepAliveThread != null) {
        mKeepAliveThread.interrupt();
        try {
            mKeepAliveThread.join(10L);
            mKeepAliveThread = null;
        }
        catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

public static void main(String[] args) {
    GoProStreamer streamer = new GoProStreamer();
    streamer.setVisible(true);
    streamer.setTitle("Pannello di controllo");
}

}

Alessio
  • 23
  • 9
  • 1
    Do you have any code for this? Even if you share the code for your 1 GoPro, that would be helpful. – Juan Carlos Farah Apr 09 '15 at 14:44
  • It depends on your implementation, but I assume you can create new thread for each camera, easily even in java. – jjurm Apr 09 '15 at 19:33
  • I have add the code. I can't create 3 different thread, because i can connect to one gopro for time, via wi-fi. I can't connect to the 3 different wi-fi at the same time!!! – Alessio Apr 10 '15 at 08:20

1 Answers1

1

IMHO, it is a physical problem : a standard wifi card can't connect to multiple wifi networks.

if you're running Windows, here is a Microsoft utilty ( http://research.microsoft.com/en-us/downloads/994abd5f-53d1-4dba-a9d8-8ba1dcccead7/ ) that seems to allow it.

Microsoft Research Virtual WiFi

Virtual WiFi helps a user connect to multiple IEEE 802.11 networks with one WiFi card. VIt works by exposing multiple virtual adapters, one for each wireless network to which connectivity is desired. Virtual WiFi uses a network hopping scheme to switch the wireless card across the desired wireless networks.

As soon as you can connect all cameras at one time, try to do one thread by camera as suggested by jjurm in comments. Keep in mind that you are limited by your bandwith according to the resolution of the stream wanted (Full HD 24fps uncompressed = 1920 * 1080 * 24 ~ 50 Mbs <=> 802.11g Wifi theoric speed ).

Hope it helps

Community
  • 1
  • 1
A. Ocannaille
  • 306
  • 4
  • 14
  • ok, but each camera has the same IP address. If i connect the PC to the 3 cameras, how do i create the different thread? – Alessio Apr 10 '15 at 08:59
  • 1
    This is indeed a problem. To my mind, it is a network problem and not a software problem. The same IP means the same network and this will cause conflicts. Try changing your GoPro IP. It seems possible on GoPro Hero Black [IP Address Changer for GoPro Hero 3+ Black cameras](http://www.cam-do.com/SOBM/IPChanger.html) – A. Ocannaille Apr 10 '15 at 09:23
  • ok thanks. but i don't know how to connect 3 gopro by Microsoft Research Virtual WiFi. can you help me? – Alessio Apr 10 '15 at 09:28
  • I must admit that I never tried Microsoft Research Virtual WiFi. I cannot here at my work, but i can try At home. But i'm not sure to have enough wifi devices to test this properly. – A. Ocannaille Apr 10 '15 at 09:44