-1

如何同时管理多个 GoPro 摄像机?我想同时串流三个 GoPro 摄像机的三个视频,并将视频记录在硬盘上。

我用 Java 为一个 GoPro 编写了一个工具,它可以正常工作。

请帮帮我!

这是代码:

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");
}

}

4

1 回答 1

1

恕我直言,这是一个物理问题:标准 wifi 卡无法连接到多个 wifi 网络。

如果您运行的是 Windows,这里有一个似乎允许它的 Microsoft 实用程序( http://research.microsoft.com/en-us/downloads/994abd5f-53d1-4dba-a9d8-8ba1dcccead7/ )。

微软研究院虚拟 WiFi

虚拟 WiFi 可帮助用户使用一张 WiFi 卡连接到多个 IEEE 802.11 网络。VI 的工作原理是公开多个虚拟适配器,每个需要连接的无线网络一个。虚拟 WiFi 使用网络跳跃方案在所需的无线网络之间切换无线网卡。

一旦您可以一次连接所有相机,请尝试按照 jjurm 在评论中的建议逐个相机执行一个线程。请记住,根据所需流的分辨率(全高清 24fps 未压缩 = 1920 * 1080 * 24 ~ 50 Mbs <=> 802.11g Wifi 理论速度),您会受到带宽的限制。

希望能帮助到你

于 2015-04-10T08:40:29.383 回答