# Como gravar um vídeo com áudio e limite de tempo

> Gravar vídeo (com ou sem áudio), definir qualidade e limite de duração, e obter o caminho do MP4.

Source: https://crossfly.dev/pt/docs/cookbook/device/gravar-video — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Como gravar um vídeo com áudio e limite de tempo

**Propósito.** Gravar um vídeo pela câmera do dispositivo, opcionalmente **com áudio**, limitando a
duração e escolhendo a qualidade, e receber o **caminho do arquivo `.mp4`**.

## APIs usadas
- `Camera.captureMode` (`Preview`) — modo de captura: `PHOTO`, `MUTED_VIDEO` (vídeo sem som), `AUDIO_VIDEO` (vídeo + áudio).
- `Camera.videoTimeLimit` (`int`) — limite de gravação em **segundos**; `0` = sem limite.
- `Camera.videoQuality` (`AVQuality`) — `HIGH`, `MEDIUM` (default do `Camera`), `LOW`. Cada valor define fps, taxa de vídeo/áudio e estéreo.
- `Camera.shot()` → `String` — inicia a UI de gravação e retorna o caminho do `.mp4` (ou `null`).
- `PhotoPicker(Preview type)` — UI usada quando `cameraType == PICKER`; possui os campos públicos `videoTimeLimit` e `videoQuality` que `shot()` já preenche a partir do `Camera`.

> **Nota.** No `PhotoPicker`, ao gravar vídeo, o arquivo é salvo em `/sdcard/<timestamp>.mp4`.
> O `videoTimeLimit` faz o rótulo de tempo do picker **contar de forma regressiva**. Em `AUDIO_VIDEO`
> a gravação inclui áudio (`GdxRecorder.startVideoWithAudio`), em `MUTED_VIDEO` não.
> No iOS com modo de vídeo, `shot()` usa a câmera nativa do SO passando `videoTimeLimit`/`videoQuality`.

## Exemplo completo (copiar, colar e rodar)

```java
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

/** Tela principal executável. Aponte o launcher (classname) e rode: 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;     // UI de gravação do CrossFly
            cam.captureMode    = UIConstants.Preview.AUDIO_VIDEO;   // vídeo COM áudio (use MUTED_VIDEO p/ sem som)
            cam.videoQuality   = Camera.AVQuality.HIGH;             // HIGH | MEDIUM | LOW
            cam.videoTimeLimit = 30;                                // 30s; 0 = sem limite

            String mp4 = cam.shot();                                // caminho do .mp4, ou null se cancelado

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

> O trecho abaixo mostra **só o miolo**. Para rodar, coloque-o no esqueleto `MainWindow` acima.

## Trecho mínimo

```java
// verificado na fonte: 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;     // UI de gravação do CrossFly
   cam.captureMode   = UIConstants.Preview.AUDIO_VIDEO;   // vídeo COM áudio (use MUTED_VIDEO p/ sem som)
   cam.videoQuality  = Camera.AVQuality.HIGH;             // HIGH | MEDIUM | LOW
   cam.videoTimeLimit = 30;                               // 30s; 0 = sem limite

   String mp4 = cam.shot();                               // caminho do .mp4, ou null se cancelado

   Component.onUI(() -> {                                 // retorno fora da paint thread
      if (mp4 != null)
         usarVideo(mp4);
   });
}).start();
```

## Aprofunde-se
- Guia da câmera: [Câmera do dispositivo](/docs/data-and-services/device-camera) · Widget: [PhotoPicker](/docs/ui/widgets/photopicker)
- Receita irmã: [tirar-foto.md](/docs/cookbook/device/tirar-foto)
