---
title: The capture button
description: The touch surface on the Meta Ray-Ban's right temple can pause or stop your camera stream at any moment — a firmware-enforced privacy gesture your app must respect. What your app observes, how to handle it, and how to test it in the simulator.
type: guide
platform: android
vendor: meta
related:
  - /docs/guides/photo-capture
  - /docs/guides/video-capture
  - /docs/concepts/transport-vs-app
  - /docs/reference/errors
---

The right temple of Meta's smart glasses carries a capacitive touch surface — the **capture button**. It isn't a button your app owns: it's the *wearer's* control over the camera, enforced by firmware below anything the SDK (or Meta's DAT itself) can override. Every camera-using app inherits its behavior, so this page is worth ten minutes before you ship one.

## What the gestures do

Two gestures, hardware-verified:

| Gesture | Effect on your camera stream |
|---|---|
| **Tap** (single touch) | Pause ⇄ resume. Non-destructive — the connection holds. |
| **Tap-and-hold** | Stop. The whole device session ends; the connection drops and the SDK auto-recovers over a few seconds. |

The privacy LED on the glasses tracks the same state: lit while the camera is live, dark the moment it's paused or stopped — so bystanders always see the truth, whatever the app wants.

## Why it works this way

This is a **privacy mechanism, not an API gap**. Meta's model is that the person wearing the camera — not the app — has the final say over whether it's capturing. That's why:

- **There is no app-callable pause or resume.** DAT exposes the state (`StreamState.PAUSED`) but no way to change it. We probed the internal resume path on real hardware: the glasses **refuse** an app-initiated resume of a wearer's pause — the firmware ends the session rather than let software un-pause the camera.
- **Fighting it makes things worse.** Tearing down and reopening the stream to force a resume drops the whole connection, and doing so shortly after a pause can wedge the glasses for ~20 seconds. Don't.
- The gesture always wins. Your app's job is to *observe and respond gracefully*, and the SDK is built around exactly that.

## What your app observes

The SDK turns the gesture into typed, actionable signals — the same ones in the simulator and on hardware, because it's the same shared gate:

**While paused (tap):**
- `capturePhoto()` / `captureVideo()` return `CaptureError.StreamPaused`, whose message already tells the user what to do: *"The camera is paused. Tap the right temple of your glasses to resume the camera, then try again."*
- Starting `videoFrames` throws `CameraStreamPausedException`. A pause **mid-stream** is not an error — frame delivery halts (your last frame stays on screen) and resumes on the next tap.
- An **in-flight recording stays alive but captures no footage** — end it and the clip contains everything except the paused window, spliced seamlessly. `duration_ms` reflects footage, not wall clock.
- [Assistant](/docs/concepts/assistant) tools using `orToolError` automatically speak the tap-the-temple message to the user.

**After a stop (hold):**
- The stream is gone and **no wearer gesture brings it back for your app** — a tap with no live stream goes to Meta's own capture and your app never sees it.
- Your app re-arms the stream with its **next camera use**: the next frame-grab photo, recording, or `videoFrames` subscription starts a fresh stream (on hardware this rides the SDK's automatic session recovery, ~3–5 s after the hold).
- An in-flight recording ends with the footage captured so far.

The canonical handling pattern is two lines of intent: surface the message, let the wearer tap, retry. Snippets live in [photo capture](/docs/guides/photo-capture#handling-failures) and [video capture](/docs/guides/video-capture#if-the-camera-is-paused-when-you-start).

## Test it without glasses

The [browser simulator](/docs/concepts/transport-vs-app) reproduces the whole model, because the paused gate is the same code on both substrates:

- The **Capture button panel** (right rail) shows the glasses with a marker on the right temple — tap it to pause/resume, press-and-hold to stop. The **capture LED** in the Glasses View header mirrors the privacy light.
- Every transition lands in the event log under the camera chip (`camera_stream_opened` / `_paused` / `_resumed` / `_closed`), and a capture denied while paused logs `capture_denied` under errors with the same actionable message.
- Agents drive it headless with the `injectHardwareButton` MCP tool — pause the stream mid-test and assert your app's handling end-to-end.

One surfaced substrate delta: on real glasses a hold also drops the connection for a few seconds while the SDK recovers; the simulator closes the stream without the blip.

## Related

- [Capture a photo](/docs/guides/photo-capture) — `CaptureError.StreamPaused` handling with the full `when` arm.
- [Capture video](/docs/guides/video-capture) — mid-recording pause semantics and the footage-splice behavior.
- [Transport vs app simulation](/docs/concepts/transport-vs-app) — why the simulator's error is byte-for-byte the hardware error.
- [Error reference](/docs/reference/errors#capture-errors) — every `CaptureError` variant.
