public void playVideo(MP4VideoDemuxer demuxer) {
    try {
      long sleepTimeMillisPerFrame = (long) (1000.0 / FRAME_RATE);
      long previousTimeMillis = System.currentTimeMillis();

      demuxer.seekToFrame(0);
      YUVPicture picture;
      while (true) {
        picture = demuxer.getNextFrame();

        if (picture == null) {
          if (LOOP_FOREVER) {
            demuxer.seekToFrame(0);
            return;
          } else {
            break;
          }
        }

        long currentTimeMillis = System.currentTimeMillis();

        doTheNextFrame(picture);

        long timeDelta = currentTimeMillis - previousTimeMillis;
        long timeToSleep = sleepTimeMillisPerFrame - timeDelta;
        if (timeToSleep < 1) timeToSleep = 1;
        if (timeToSleep > sleepTimeMillisPerFrame) timeToSleep = sleepTimeMillisPerFrame;

        ThreadTools.sleep(timeToSleep);
        previousTimeMillis = currentTimeMillis;
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  public void findEntryBoxAndEnterValue(String name, double value) {
    JPanelFixture entryBoxArrayPanel = focusedWindow.panel("EntryBoxArrayPanel");
    JPanelFixture enumEntryBox = entryBoxArrayPanel.panel(name + "_YoEntryBox");
    JTextComponentFixture textBox = enumEntryBox.textBox();

    // For some reason deleting, and then entering doesn't seem to work. It only deletes part of the
    // text!?
    // Instead here we have to call setText.
    // textBox.deleteText();
    // textBox.enterText(Double.toString(value) + "\n");

    textBox.setText(Double.toString(value));
    textBox.enterText("\n");
    ThreadTools.sleep(500);
  }
  public SimulationGUITestFixture(final SimulationConstructionSet scs) {
    FailOnThreadViolationRepaintManager.install();

    this.scs = scs;

    JFrame frame =
        GuiActionRunner.execute(
            new GuiQuery<JFrame>() {
              protected JFrame executeInEDT() throws SimulationExceededMaximumTimeException {
                JFrame jFrame = scs.getJFrame();

                return jFrame;
              }
            });
    focusedWindow = new FrameFixture(frame);

    ThreadTools.sleep(1000);
    focusedWindow.focus();

    mainSCSWindow = focusedWindow;
  }
  public void connect() {
    //      try
    //      {
    //
    //      }
    //      catch (IOException e)
    //      {
    //         throw new RuntimeException(e);
    //      }

    boolean isConnected = false;
    System.out.println("[GazeboOutputWriter] Connecting to " + address);
    while (!isConnected) {
      try {
        channel = SocketChannel.open();
        channel.configureBlocking(true);
        channel.socket().setKeepAlive(true);
        channel.socket().setReuseAddress(true);
        channel.socket().setSoLinger(false, 0);
        channel.socket().setTcpNoDelay(true);

        channel.connect(address);
        isConnected = true;
        sendInitialState();
      } catch (IOException e) {
        System.out.println("Connect failed.");
        try {
          channel.close();
        } catch (IOException e1) {
          e1.printStackTrace();
        }
        ThreadTools.sleep(3000);
        isConnected = false;
      }
    }

    System.out.println("[GazeboOutputWriter] Connected");
    System.out.println("num of joints = " + joints.size());
  }