Skip to content
CrossFly is 100% open sourceFollow us on GitHub
CrossFlyCrossFly
Get started

This page was machine-translated from Portuguese and may contain errors. The Portuguese version is canonical.

How to record a video with audio and a time limit

Purpose. Record a video with the device camera, optionally with audio, limiting the duration and choosing the quality, and get the path of the .mp4 file.

APIs used

  • Camera.captureMode (Preview) — capture mode: PHOTO, MUTED_VIDEO (video without sound), AUDIO_VIDEO (video + audio).
  • Camera.videoTimeLimit (int) — recording limit in seconds; 0 = no limit.
  • Camera.videoQuality (AVQuality) — HIGH, MEDIUM (default of Camera), LOW. Each value sets fps, video/audio rate, and stereo.
  • Camera.shot() → String — starts the recording UI and returns the path of the .mp4 (or null).
  • PhotoPicker(Preview type) — UI used when cameraType == PICKER; it has the public fields videoTimeLimit and videoQuality that shot() already fills in from the Camera.

Note. In PhotoPicker, when recording video, the file is saved to /sdcard/<timestamp>.mp4. videoTimeLimit makes the picker’s time label count down. In AUDIO_VIDEO the recording includes audio (GdxRecorder.startVideoWithAudio), in MUTED_VIDEO it doesn’t. On iOS with video mode, shot() uses the OS native camera passing videoTimeLimit/videoQuality.

Complete example (copy, paste, and run)

package com.exemplo;

import dev.crossfly.ui.*;                   // Window, Component, Button, Label, UIConstants
import dev.crossfly.ui.layout.*;            // VerticalLayout
import dev.crossfly.device.*;               // Camera, Camera.AVQuality

/** Runnable main screen. Point the launcher (classname) and run: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      Label resultado = new Label("");
      add(LAY_AUTO, resultado);

      Button acao = new Button("Gravar vídeo");
      acao.onAction(c ->
      {
         new Thread(() ->
         {
            Camera cam = new Camera();
            cam.cameraType     = UIConstants.CameraType.PICKER;     // CrossFly recording UI
            cam.captureMode    = UIConstants.Preview.AUDIO_VIDEO;   // video WITH audio (use MUTED_VIDEO for no sound)
            cam.videoQuality   = Camera.AVQuality.HIGH;             // HIGH | MEDIUM | LOW
            cam.videoTimeLimit = 30;                                // 30s; 0 = no limit

            String mp4 = cam.shot();                                // path of the .mp4, or null if cancelled

            Component.onUI(() ->                                    // return outside the paint thread
               resultado.setText(mp4 != null ? "Vídeo: " + mp4 : "Cancelado"));
         }).start();
      });
      add(LAY_AUTO, acao);
   }
}

The snippet below shows only the core. To run it, place it in the MainWindow skeleton above.

Minimal snippet

// verified at source: Camera.java (captureMode/videoTimeLimit/videoQuality, shot()); PhotoPicker.java (startRecording, stopRecording)
import dev.crossfly.device.*;              // Camera, Camera.AVQuality
import dev.crossfly.ui.*;                  // Component, UIConstants.CameraType/Preview

new Thread(() -> {
   Camera cam = new Camera();
   cam.cameraType    = UIConstants.CameraType.PICKER;     // CrossFly recording UI
   cam.captureMode   = UIConstants.Preview.AUDIO_VIDEO;   // video WITH audio (use MUTED_VIDEO for no sound)
   cam.videoQuality  = Camera.AVQuality.HIGH;             // HIGH | MEDIUM | LOW
   cam.videoTimeLimit = 30;                               // 30s; 0 = no limit

   String mp4 = cam.shot();                               // path of the .mp4, or null if cancelled

   Component.onUI(() -> {                                 // return outside the paint thread
      if (mp4 != null)
         usarVideo(mp4);
   });
}).start();

Go deeper

Was this page helpful?