@vidtreo/recorder-vue 1.6.12 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +292 -23
  2. package/dist/components/MobileRecordingPrompt.vue.d.ts +8 -0
  3. package/dist/components/MobileRecordingPromptToggle.vue.d.ts +12 -0
  4. package/dist/components/MobileWebRecorderUIContent.vue.d.ts +7 -0
  5. package/dist/components/NativeCameraUIContent.vue.d.ts +7 -0
  6. package/dist/components/StandardRecorder.vue.d.ts +5 -10
  7. package/dist/components/StandardRecorderContent.vue.d.ts +24 -0
  8. package/dist/components/VidtreoRecorder.vue.d.ts +5 -10
  9. package/dist/components/ui/AudioBar.vue.d.ts +40 -0
  10. package/dist/components/ui/DeviceSelector.vue.d.ts +2 -2
  11. package/dist/components/ui/PermissionFlowSteps.vue.d.ts +1 -1
  12. package/dist/components/ui/PermissionRecoveryGuide.vue.d.ts +1 -1
  13. package/dist/components/ui/PreviewContent.vue.d.ts +6 -4
  14. package/dist/components/ui/RecordingControlsButtons.vue.d.ts +5 -4
  15. package/dist/components/ui/SettingsPanel.vue.d.ts +5 -2
  16. package/dist/components/ui/TranscodingProgress.vue.d.ts +1 -0
  17. package/dist/components/ui/UploadErrorOverlay.vue.d.ts +13 -0
  18. package/dist/components/ui/UploadProgress.vue.d.ts +1 -0
  19. package/dist/components/ui/UploadProgressOverlay.vue.d.ts +7 -0
  20. package/dist/composables/use-credential-error.d.ts +9 -0
  21. package/dist/composables/use-native-camera.d.ts +4 -1
  22. package/dist/composables/use-permission-flow.d.ts +2 -1
  23. package/dist/composables/use-recorder-translations.d.ts +2 -0
  24. package/dist/composables/use-vidtreo-recorder.d.ts +6 -0
  25. package/dist/i18n/translations.d.ts +48 -1
  26. package/dist/index.d.ts +2 -1
  27. package/dist/index.js +1 -1
  28. package/dist/recorder-vue.css +1 -1
  29. package/dist/types/index.d.ts +26 -15
  30. package/dist/utils/audio-only.d.ts +3 -0
  31. package/dist/utils/button-visibility.d.ts +1 -0
  32. package/dist/utils/device-error-overlay-mapper.d.ts +30 -1
  33. package/dist/utils/env-utils.d.ts +2 -1
  34. package/dist/utils/mobile-recording-prompt.d.ts +14 -0
  35. package/dist/utils/progress-overlay.d.ts +31 -0
  36. package/dist/utils/upload-error-message.d.ts +13 -0
  37. package/dist/utils/upload-label.d.ts +11 -0
  38. package/package.json +3 -2
  39. package/dist/services/upload-service-wrapper.d.ts +0 -12
package/README.md CHANGED
@@ -19,7 +19,7 @@ npm install @vidtreo/recorder-vue @vidtreo/recorder
19
19
  ```
20
20
 
21
21
  **Peer dependencies**:
22
- - `@vidtreo/recorder >=1.6.0`
22
+ - `@vidtreo/recorder >=1.9.0`
23
23
  - `vue >=3.0.0`
24
24
 
25
25
  Don't forget the stylesheet — either import it once in your entry, or rely on the built-in CSS injection (added to `<head>` automatically when the package loads).
@@ -66,20 +66,21 @@ const apiKey = import.meta.env.VITE_VIDTREO_API_KEY as string;
66
66
 
67
67
  ## Component API
68
68
 
69
- The component accepts a single `recorder-props` object so the discriminated union (`demo: true` vs `apiKey`) stays type-safe at the call site. Events use the standard Vue `@event-name` listener syntax.
69
+ The component accepts a single `recorder-props` object so the discriminated union (`demo: true` vs `apiKey` vs `getAccessToken`) stays type-safe at the call site. Events use the standard Vue `@event-name` listener syntax.
70
70
 
71
71
  ### Props (`recorder-props`)
72
72
 
73
73
  | Prop | Type | Required | Default | Description |
74
74
  |------|------|----------|---------|-------------|
75
- | `apiKey` | `string` | Yes* | – | API key for authentication. *Optional when `demo: true`. |
75
+ | `apiKey` | `string` | Yes* | – | API key for authentication. *Optional when `demo: true` or when `getAccessToken` is used. |
76
+ | `getAccessToken` | `() => Promise<string>` | No* | – | Returns a short-lived desktop access token minted by your server. Use instead of `apiKey` (exactly one of the two). Called again whenever a fresh token is needed, including when a queued upload resumes after a reload. |
76
77
  | `demo` | `boolean` | No | `false` | Demo mode. Skips upload and lets you download the local recording. |
77
78
  | `backendUrl` | `string` | No | `https://core.vidtreo.com` | Backend API URL. |
78
79
  | `countdownDuration` | `number` | No | – | Pre-recording countdown (milliseconds). |
79
80
  | `minTimeRecord` | `number` | No | – | Minimum recording time in ms before Stop is allowed. Must not be greater than `maxRecordingTime` when both are positive. |
80
81
  | `maxRecordingTime` | `number` | No | – | Maximum recording time in milliseconds. |
81
82
  | `userMetadata` | `Record<string, unknown>` | No | – | Custom metadata attached to uploads. |
82
- | `recordingPrompt` | `RecordingPrompt` | No | – | Prompt shown during recording. Use `countdown: { show, placement: "above-countdown" }` to float it over the countdown. |
83
+ | `recordingPrompt` | `RecordingPrompt` | No | – | Prompt shown during recording. Use `countdown: { show, placement: "above-countdown" }` to float it over the countdown. A `label` field is still accepted for backward compatibility but is not displayed. |
83
84
  | `enableSourceSwitching` | `boolean` | No | `true` | Toggle between camera and screen. |
84
85
  | `enableMute` | `boolean` | No | `true` | Show the mute/unmute button. |
85
86
  | `enablePause` | `boolean` | No | `true` | Show pause/resume buttons. |
@@ -88,6 +89,7 @@ The component accepts a single `recorder-props` object so the discriminated unio
88
89
  | `tabVisibilityOverlayText` | `string` | No | localized default | Custom message for the tab-visibility overlay. |
89
90
  | `mobileMode` | `"embed" \| "overlay" \| "native"` | No | `"overlay"` | Mobile experience. `"embed"` = same as desktop, `"overlay"` = fullscreen modal, `"native"` = device's native camera (file input). |
90
91
  | `nativeCamera` | `boolean` | No | – | **Deprecated** — use `mobileMode: "native"` instead. |
92
+ | `audioOnly` | `boolean` | No | `false` | Record audio only with the microphone (no camera). Requires audio recording enabled for the environment in the backend. See [Audio-only recording](#audio-only-recording). |
91
93
  | `maxFileSize` | `number` | No | – | Maximum file size in MB (native camera mode). |
92
94
  | `lang` | `string` | No | `"en"` | Language code (`"en"` or `"es"`). |
93
95
  | `texts` | `PartialTranslations` | No | – | Per-key text overrides. |
@@ -98,18 +100,22 @@ The component accepts a single `recorder-props` object so the discriminated unio
98
100
  |-------|---------|------------|
99
101
  | `recording-start` | – | Recording begins (after the countdown finishes). |
100
102
  | `recording-stop` | – | Recording ends and processing starts. |
101
- | `upload-progress` | `progress: number` (0..1) | Each chunk is uploaded. |
102
- | `upload-complete` | `{ recordingId: string; uploadUrl: string }` | Upload finishes. |
103
- | `upload-error` | `error: Error` | Upload fails. |
104
- | `transcoding-progress` | `progress: number` (0..1) | Native-camera transcoding progress. |
105
- | `error` | `error: Error` | Any unhandled error. |
103
+ | `upload-progress` | `progress: number` (0..1), `phase: UploadProgressPhase \| null` | Upload progress in every flow (desktop, mobile and native camera, including resumed uploads). `phase` is `"preparing"`, `"transferring"`, `"finalizing"`, `"completed"`, or `null` when the upload starts (progress `0`). |
104
+ | `upload-complete` | `RecordingUploadResult` | Upload finishes. Same payload for the desktop/overlay recorder and native camera mode. See [Upload completion payload](#upload-completion-payload). |
105
+ | `upload-error` | `error: Error` | Upload fails. Use `getUploadErrorCode(error)` to read the [error code](#upload-errors). |
106
+ | `transcoding-progress` | `progress: number` (0..1) | Transcoding progress after a recording stops (desktop and mobile) and native camera processing. |
107
+ | `error` | `error: Error` | Any unhandled error, including the [credential conflict](#temporary-access-tokens) configuration error. |
106
108
 
107
109
  ### Example with listeners
108
110
 
109
111
  ```vue
110
112
  <script setup lang="ts">
111
113
  import { VidtreoRecorder } from "@vidtreo/recorder-vue";
112
- import type { VidtreoRecorderProps } from "@vidtreo/recorder-vue";
114
+ import type {
115
+ RecordingUploadResult,
116
+ UploadProgressPhase,
117
+ VidtreoRecorderProps,
118
+ } from "@vidtreo/recorder-vue";
113
119
 
114
120
  const recorderProps: VidtreoRecorderProps = {
115
121
  apiKey: "your-api-key",
@@ -118,13 +124,13 @@ const recorderProps: VidtreoRecorderProps = {
118
124
  lang: "en",
119
125
  };
120
126
 
121
- function onComplete(result: { recordingId: string; uploadUrl: string }) {
127
+ function onComplete(result: RecordingUploadResult) {
122
128
  console.log("Recording uploaded:", result.recordingId);
123
129
  console.log("View at:", result.uploadUrl);
124
130
  }
125
131
 
126
- function onProgress(progress: number) {
127
- console.log(`Upload: ${Math.round(progress * 100)}%`);
132
+ function onProgress(progress: number, phase: UploadProgressPhase | null) {
133
+ console.log(`Upload: ${Math.round(progress * 100)}% (${phase ?? "starting"})`);
128
134
  }
129
135
 
130
136
  function onError(error: Error) {
@@ -142,6 +148,117 @@ function onError(error: Error) {
142
148
  </template>
143
149
  ```
144
150
 
151
+ ### Temporary access tokens
152
+
153
+ ```vue
154
+ <script setup lang="ts">
155
+ import { VidtreoRecorder } from "@vidtreo/recorder-vue";
156
+
157
+ async function getAccessToken(): Promise<string> {
158
+ const response = await fetch("/api/vidtreo-token");
159
+ const { token } = await response.json();
160
+ return token;
161
+ }
162
+ </script>
163
+
164
+ <template>
165
+ <VidtreoRecorder :recorder-props="{ getAccessToken }" />
166
+ </template>
167
+ ```
168
+
169
+ The token is never stored. If an upload is interrupted, the component calls `getAccessToken` again when the upload resumes.
170
+
171
+ Pass either `apiKey` or `getAccessToken`, not both. The props type rejects both at compile time; at runtime (plain JavaScript) the component renders a configuration error with the message `Provide either apiKey or getAccessToken, not both` and emits `error` once with an error whose `code` is `CONFIG_ERROR_CREDENTIAL_CONFLICT` (`"config.credential-conflict"`). Passing neither (outside demo mode, and without `VIDTREO_API_KEY` in the environment) renders the `errorApiKeyRequired` configuration error and emits `error` once instead of throwing. The same applies when `StandardRecorder`, `MobileWebRecorderUI` or `NativeCameraUI` are used directly. Demo mode ignores credentials. `CONFIG_ERROR_CREDENTIAL_CONFLICT` and `isCredentialConflictError` are re-exported from `@vidtreo/recorder`:
172
+
173
+ ```ts
174
+ import { isCredentialConflictError } from "@vidtreo/recorder-vue";
175
+
176
+ function onError(error: Error) {
177
+ if (isCredentialConflictError(error)) {
178
+ reportMisconfiguration();
179
+ }
180
+ }
181
+ ```
182
+
183
+ ### Progress overlays
184
+
185
+ After you stop a recording the preview shows a progress overlay until the upload finishes:
186
+
187
+ | Stage | Label key | Progress |
188
+ |-------|-----------|----------|
189
+ | Finalizing the recording (before transcoding reports progress) | `finishing` | 0% |
190
+ | Transcoding | `finishing` | transcoding progress |
191
+ | Uploading | `uploading`, `finalizing` when the backend is finalizing, `retryingUpload` while a retry is pending | upload progress |
192
+
193
+ The same overlays show in the mobile overlay recorder. In native camera mode a resumed upload without a preview shows a standalone progress bar with the same labels.
194
+
195
+ ### Upload completion payload
196
+
197
+ `upload-complete` receives a `RecordingUploadResult`: every field of the backend upload result plus the backward-compatible `recordingId` and `uploadUrl`.
198
+
199
+ ```ts
200
+ import type { RecordingUploadResult } from "@vidtreo/recorder-vue";
201
+
202
+ type RecordingUploadResult = {
203
+ recordingId: string; // same value as id
204
+ uploadUrl: string; // "" when the backend has no URL yet
205
+ id: string;
206
+ publicId: string;
207
+ filename: string;
208
+ fileSize: number;
209
+ mimeType: string;
210
+ duration: number | null;
211
+ status: string;
212
+ createdAt: string;
213
+ transferStatus: "pending" | "transferring" | "transferred" | "failed" | null;
214
+ transferError: string | null;
215
+ transferredAt: string | null;
216
+ r2DeleteAfter: string | null;
217
+ r2DeletedAt: string | null;
218
+ mediaType?: "audio"; // set for audio-only recordings
219
+ audioId?: string; // same value as id, set for audio-only recordings
220
+ };
221
+ ```
222
+
223
+ For audio-only recordings (`audioOnly: true`) the payload also has `mediaType: "audio"` and `audioId`.
224
+
225
+ ### Upload errors
226
+
227
+ When an upload fails with a known cause, the component shows a dialog (`role="alertdialog"`) after recording and processing finish, and `upload-error` receives an error with a code:
228
+
229
+ ```vue
230
+ <script setup lang="ts">
231
+ import {
232
+ getUploadErrorCode,
233
+ UPLOAD_ERROR_INSUFFICIENT_CREDITS,
234
+ VidtreoRecorder,
235
+ } from "@vidtreo/recorder-vue";
236
+
237
+ function onUploadError(error: Error) {
238
+ if (getUploadErrorCode(error) === UPLOAD_ERROR_INSUFFICIENT_CREDITS) {
239
+ notifyAdmin();
240
+ }
241
+ }
242
+ </script>
243
+
244
+ <template>
245
+ <VidtreoRecorder
246
+ :recorder-props="{ apiKey: 'your-api-key' }"
247
+ @upload-error="onUploadError"
248
+ />
249
+ </template>
250
+ ```
251
+
252
+ | Code | Meaning |
253
+ |------|---------|
254
+ | `upload.insufficient-credits` | The account has no credits left (HTTP 402). The upload is not retried. |
255
+
256
+ `getUploadErrorCode` returns `null` for other errors. Network errors are retried automatically before they are reported; while a retry is in progress the progress bar shows the `retryingUpload` label.
257
+
258
+ ### Upload resume
259
+
260
+ Uploads are queued in IndexedDB before they are sent, in every mode (desktop, mobile overlay, mobile embed, and native camera). If the page is reloaded or the connection drops, the next mounted `VidtreoRecorder` resumes the upload with the same idempotency key and sends only the parts that are missing. Progress shows again while it resumes (in native camera mode as a standalone progress bar, since there is no preview), and `upload-complete` fires with the full payload when it finishes. Mount the component with the same credentials (`apiKey` or `getAccessToken`) so the upload can resume. If IndexedDB is unavailable, uploads go directly to the backend without persistence.
261
+
145
262
  ## Composable API
146
263
 
147
264
  When the default component doesn't fit your UI, drop down to the `useVidtreoRecorder` composable and assemble your own.
@@ -193,6 +310,7 @@ const { state, actions, audioLevel, controller } = useVidtreoRecorder({
193
310
  stream: MediaStream | null;
194
311
  isMuted: boolean;
195
312
  isPaused: boolean;
313
+ isFinalizingRecording: boolean; // true from stop until the recording blob is ready
196
314
  isAudioReady: boolean;
197
315
  hasAudioFailed: boolean;
198
316
  error: string | null;
@@ -200,6 +318,10 @@ const { state, actions, audioLevel, controller } = useVidtreoRecorder({
200
318
  countdown: number | null;
201
319
  timer: string; // "00:12" format
202
320
  uploadProgress: number | null; // 0..1 or null
321
+ uploadPhase: UploadProgressPhase | null; // "preparing" | "transferring" | "finalizing" | "completed"
322
+ uploadRetryAttempt: number | null;
323
+ uploadErrorCode: UploadErrorCode | null; // "upload.insufficient-credits"
324
+ transcodingProgress: number | null; // 0..1 while transcoding, otherwise null
203
325
  transitionMessage: string | null;
204
326
  isInitialized: boolean;
205
327
  recordedBlob: Blob | null; // populated in demo mode
@@ -218,17 +340,18 @@ const { state, actions, audioLevel, controller } = useVidtreoRecorder({
218
340
 
219
341
  | Action | Signature | What it does |
220
342
  |--------|-----------|--------------|
221
- | `startRecording` | `(sourceType?: "camera" \| "screen") => Promise<void>` | Begin recording (after countdown if configured). |
222
- | `stopRecording` | `() => Promise<RecordingStopResult>` | Stop and trigger upload. |
343
+ | `startRecording` | `(sourceType?: "camera" \| "screen" \| "audio") => Promise<void>` | Begin recording (after countdown if configured). Defaults to `"audio"` when `audioOnly` is set, otherwise `"camera"`. |
344
+ | `stopRecording` | `() => Promise<RecordingStopResult>` | Stop and trigger upload. The result has `blob` and `mediaType` (`"audio"` or `"video"`). |
223
345
  | `pauseRecording` | `() => void` | Pause an active recording. |
224
346
  | `resumeRecording` | `() => void` | Resume from pause. |
225
347
  | `toggleMute` | `() => void` | Toggle the audio mute state. |
226
348
  | `switchSource` | `(sourceType: "camera" \| "screen") => Promise<void>` | Swap between camera and screen during preview/recording. |
227
349
  | `changeCamera` | `(deviceId: string) => Promise<void>` | Switch to a different camera. |
228
350
  | `changeMic` | `(deviceId: string) => Promise<void>` | Switch to a different microphone. |
229
- | `startPreview` | `(sourceType?: "camera" \| "screen") => Promise<void>` | Open the stream without recording. |
351
+ | `startPreview` | `(sourceType?: "camera" \| "screen" \| "audio") => Promise<void>` | Open the stream without recording. `"audio"` opens a microphone-only stream. |
230
352
  | `stopPreview` | `() => void` | Tear the preview stream down. |
231
353
  | `downloadVideo` | `() => void` | Download the last `recordedBlob` (demo mode). |
354
+ | `clearUploadError` | `() => void` | Clear `uploadErrorCode` after the user dismisses the upload error. |
232
355
  | `cleanup` | `() => void` | Release all resources. Useful before unmounting. |
233
356
 
234
357
  ### Specialized composables
@@ -236,7 +359,7 @@ const { state, actions, audioLevel, controller } = useVidtreoRecorder({
236
359
  | Composable | Purpose |
237
360
  |------------|---------|
238
361
  | `useMobileWebRecorder(config)` | Wraps `useVidtreoRecorder` and adds `isModalOpen`, `openModal`, `closeModal`, `canCloseModal` for the mobile overlay experience. |
239
- | `useNativeCamera(config)` | File-input + transcoding flow used when `mobileMode: "native"`. Returns `{ state, actions }` with `handleFileSelect`, `processAndUpload`, `downloadVideo`, `reset`. |
362
+ | `useNativeCamera(config)` | File-input + transcoding flow used when `mobileMode: "native"`. Returns `{ state, actions }` with `handleFileSelect`, `processAndUpload`, `downloadVideo`, `reset`. Resumes queued native uploads on mount (except in demo mode); `state` includes `uploadPhase`, `uploadRetryAttempt` and `uploadErrorCode`. |
240
363
  | `usePermissionFlow(options)` | Drives the camera/mic permission overlay. Returns `{ isActive, isComplete, currentStep, steps, recoveryData, requestPermission, retryPermission }` — useful if you want to build a fully custom permission UI. |
241
364
  | `useRecorderTranslations(translations)` | Splits a `TranslationKeys` object into `preview`, `buttons`, and `settings` subsets as `ComputedRef`s. Accepts `MaybeRefOrGetter<TranslationKeys>` so it stays reactive when the language changes. |
242
365
 
@@ -333,10 +456,76 @@ const language = ref<"en" | "es">("en");
333
456
 
334
457
  ### Translation keys
335
458
 
336
- | Key | English | Spanish |
337
- |-----|---------|---------|
459
+ Every key is identical (name and default copy) across `@vidtreo/recorder-react`, `@vidtreo/recorder-vue` and `@vidtreo/recorder-wc`.
460
+
461
+ | Key | English Default | Spanish Default |
462
+ |-----|----------------|-----------------|
338
463
  | `initializingCamera` | Initializing camera... | Inicializando cámara... |
339
464
  | `grantPermissions` | Grant camera and microphone permissions when prompted | Otorga permisos de cámara y micrófono cuando se solicite |
465
+ | `browserUnsupported` | This browser is not supported | Este navegador no es compatible |
466
+ | `browserUnsupportedDynamic` | `{browser} ({version}) is not supported, please use <a href="https://www.google.com/chrome/" target="_blank" rel="noopener noreferrer">Chrome</a>` | `{browser} ({version}) no es compatible, por favor usa <a href="https://www.google.com/chrome/" target="_blank" rel="noopener noreferrer">Chrome</a>` |
467
+ | `browserUnsupportedSafari` | `Safari (latest stable) is supported. If you experience issues, please use <a href="https://www.google.com/chrome/" target="_blank" rel="noopener noreferrer">Chrome</a>` | `Safari (última versión estable) es compatible. Si experimentas problemas, por favor usa <a href="https://www.google.com/chrome/" target="_blank" rel="noopener noreferrer">Chrome</a>` |
468
+ | `browserUnsupportedFirefox` | `Firefox is not supported, please use <a href="https://www.google.com/chrome/" target="_blank" rel="noopener noreferrer">Chrome</a>` | `Firefox no es compatible, por favor use <a href="https://www.google.com/chrome/" target="_blank" rel="noopener noreferrer">Chrome</a>` |
469
+ | `retryCamera` | Retry Camera | Reintentar Cámara |
470
+ | `cameraInUse` | Your camera is being used by another application. Close other apps using the camera (Zoom, Teams, Discord) and try again. | Tu cámara está siendo usada por otra aplicación. Cierra otras apps que usen la cámara (Zoom, Teams, Discord) e intenta de nuevo. |
471
+ | `cameraNotFound` | No camera detected. Connect a camera or check your device settings. | No se detectó ninguna cámara. Conecta una cámara o revisa la configuración de tu dispositivo. |
472
+ | `cameraPermissionDenied` | Camera access was denied. Allow camera access in your browser settings and try again. | Se denegó el acceso a la cámara. Permite el acceso a la cámara en la configuración de tu navegador e intenta de nuevo. |
473
+ | `cameraTimeout` | The camera took too long to start. Close other apps using the camera and try again. | La cámara tardó demasiado en iniciar. Cierra otras apps que usen la cámara e intenta de nuevo. |
474
+ | `failedToStartCamera` | Failed to start camera | Error al iniciar la cámara |
475
+ | `audioInUse` | Your microphone is being used by another application. Close other apps using the microphone (Zoom, Teams, Discord) and try again. | Tu micrófono está siendo usado por otra aplicación. Cierra otras apps que usen el micrófono (Zoom, Teams, Discord) e intenta de nuevo. |
476
+ | `audioNotFound` | No microphone detected. Connect a microphone or check your device settings. | No se detectó ningún micrófono. Conecta un micrófono o revisa la configuración de tu dispositivo. |
477
+ | `audioPermissionDenied` | Microphone access was denied. Allow microphone access in your browser settings and try again. | Se denegó el acceso al micrófono. Permite el acceso al micrófono en la configuración de tu navegador e intenta de nuevo. |
478
+ | `audioTimeout` | The microphone took too long to start. Close other apps using the microphone and try again. | El micrófono tardó demasiado en iniciar. Cierra otras apps que usen el micrófono e intenta de nuevo. |
479
+ | `failedToStartAudio` | Failed to start microphone | Error al iniciar el micrófono |
480
+ | `audioErrorTitle` | Microphone unavailable | Micrófono no disponible |
481
+ | `audioErrorMessage` | We couldn't access your microphone. It may be in use by another app like Zoom, Teams, or Discord. Please close it and try again. | No pudimos acceder a tu micrófono. Puede estar en uso por otra app como Zoom, Teams o Discord. Ciérrala e inténtalo de nuevo. |
482
+ | `audioErrorRetry` | Try again | Intentar de nuevo |
483
+ | `audioMissingTitle` | Recording has no audio | La grabación no tiene audio |
484
+ | `audioMissingMessage` | We couldn't capture audio in this recording. Your microphone may have been disconnected or blocked by the browser. Check your microphone and record again. | No pudimos capturar audio en esta grabación. Es posible que el micrófono se haya desconectado o que el navegador lo haya bloqueado. Verifica tu micrófono y vuelve a grabar. |
485
+ | `audioSilentTitle` | Recording is silent | La grabación quedó en silencio |
486
+ | `audioSilentMessage` | We didn't detect any sound during the recording. Make sure your microphone is working and not muted by your operating system, then record again. | No detectamos sonido durante la grabación. Verifica que tu micrófono esté funcionando y no esté silenciado por el sistema, luego vuelve a grabar. |
487
+ | `audioProcessingErrorTitle` | Audio processing error | Error al procesar el audio |
488
+ | `audioProcessingErrorMessage` | We couldn't process the audio in this recording. Please record again. | No pudimos procesar el audio de esta grabación. Por favor vuelve a grabar. |
489
+ | `audioMissingRetry` | Record again | Grabar de nuevo |
490
+ | `audioWarningNoSignalTitle` | No microphone signal | Sin señal del micrófono |
491
+ | `audioWarningNoSignalMessage` | We're not detecting any sound. Check that your microphone is active. | No estamos detectando sonido. Verifica que tu micrófono esté activo. |
492
+ | `audioWarningLowSignalTitle` | Audio is very quiet | Audio muy bajo |
493
+ | `audioWarningLowSignalMessage` | Move closer to the microphone or turn up the input volume. | Acércate al micrófono o sube el volumen de entrada. |
494
+ | `audioWarningSpeakingMutedTitle` | You're speaking while muted | Estás hablando muteado |
495
+ | `audioWarningSpeakingMutedMessage` | Unmute your microphone if you want your voice in the recording. | Activa el micrófono si quieres que tu voz se escuche en la grabación. |
496
+ | `audioWarningTrackEndedTitle` | Microphone disconnected | Micrófono desconectado |
497
+ | `audioWarningTrackEndedMessage` | The microphone was disconnected. Reconnect it before continuing. | Se desconectó el micrófono. Reconéctalo antes de continuar. |
498
+ | `audioWarningNoChunksTitle` | No microphone input | Sin entrada del micrófono |
499
+ | `audioWarningNoChunksMessage` | We're not receiving audio from the microphone. Check browser permissions. | No estamos recibiendo audio del micrófono. Revisa los permisos del navegador. |
500
+ | `audioWarningTrackMutedTitle` | Microphone muted by browser | Micrófono silenciado por el navegador |
501
+ | `audioWarningTrackMutedMessage` | The browser muted your microphone. Check site settings. | El navegador silenció tu micrófono. Revisa la configuración del sitio. |
502
+ | `audioWarningDismiss` | Dismiss | Cerrar |
503
+ | `cameraErrorTitle` | Camera unavailable | Cámara no disponible |
504
+ | `cameraErrorMessage` | We couldn't access your camera. It may be in use by another app. Please close it and try again. | No pudimos acceder a tu cámara. Puede estar en uso por otra app. Ciérrala e inténtalo de nuevo. |
505
+ | `browserErrorTitle` | Browser not supported | Navegador no compatible |
506
+ | `browserErrorMessage` | Your browser doesn't support video recording. Please use the latest version of Chrome for the best experience. | Tu navegador no es compatible con la grabación de video. Por favor usa la última versión de Chrome. |
507
+ | `recordingCodecUnsupportedTitle` | Recording format not supported | Formato de grabación no compatible |
508
+ | `recordingCodecUnsupportedMessage` | This device can't use the selected video format. Close other apps, update Chrome if possible, and record again. | Este dispositivo no puede usar el formato de video seleccionado. Cierra otras apps, actualiza Chrome si es posible y vuelve a grabar. |
509
+ | `recordingMediaEmptyTitle` | No video was produced | No se generó ningún video |
510
+ | `recordingMediaEmptyMessage` | The browser didn't produce a usable video. Check your camera and record again. | El navegador no produjo un video utilizable. Verifica la cámara y vuelve a grabar. |
511
+ | `recordingMediaErrorTitle` | Recording could not be finished | No se pudo finalizar la grabación |
512
+ | `recordingMediaErrorMessage` | The browser reported an error before the video was ready to upload. Record again. | El navegador informó un error antes de preparar el video para subirlo. Vuelve a grabar. |
513
+ | `recordingServerTranscodeFallbackTitle` | Video processing failed | No se pudo procesar el video |
514
+ | `recordingServerTranscodeFallbackMessage` | We couldn't prepare this video for upload on your device. Record again. | No pudimos preparar este video para subirlo en tu dispositivo. Vuelve a grabar. |
515
+ | `recordingTrackEndedTitle` | Camera stopped during recording | La cámara se detuvo durante la grabación |
516
+ | `recordingTrackEndedMessage` | The camera feed ended before the recording finished. Check that the camera is still connected and record again. | La señal de la cámara terminó antes de finalizar la grabación. Verifica que la cámara siga conectada y vuelve a grabar. |
517
+ | `recordingFinalizeTimeoutTitle` | Recording took too long to finish | La grabación tardó demasiado en finalizar |
518
+ | `recordingFinalizeTimeoutMessage` | This device may be low on memory or processing power. Close other apps or browser tabs, then record again. | Es posible que este dispositivo tenga poca memoria o potencia de procesamiento. Cierra otras apps o pestañas del navegador y vuelve a grabar. |
519
+ | `recordingStateRaceTitle` | Recording did not start correctly | La grabación no inició correctamente |
520
+ | `recordingStateRaceMessage` | The recording could not be finalized because it did not start cleanly. Please refresh the page and record again. | No se pudo finalizar la grabación porque no inició correctamente. Actualiza la página y vuelve a grabar. |
521
+ | `recordingNoFramesTitle` | No video was captured | No se capturó video |
522
+ | `recordingNoFramesMessage` | We couldn't receive video frames from the camera. Check your camera connection and record again. | No pudimos recibir fotogramas de video de la cámara. Verifica la conexión de la cámara y vuelve a grabar. |
523
+ | `recordingUnsupportedTitle` | Recording not available | Grabación no disponible |
524
+ | `recordingUnsupportedMessage` | This device or browser can't record video reliably right now. Check your connection, update Chrome if possible, or use another device. | Este dispositivo o navegador no puede grabar video de forma estable ahora. Revisa tu conexión, actualiza Chrome si es posible o usa otro dispositivo. |
525
+ | `recordingPipelineRetry` | Record again | Grabar de nuevo |
526
+ | `genericErrorTitle` | Something went wrong | Algo salió mal |
527
+ | `genericErrorMessage` | An unexpected error occurred. Please try again. | Ocurrió un error inesperado. Por favor inténtalo de nuevo. |
528
+ | `errorRetry` | Try again | Intentar de nuevo |
340
529
  | `switchingDevice` | Switching device... | Cambiando dispositivo... |
341
530
  | `recordingStartsIn` | Recording starts in... | La grabación comienza en... |
342
531
  | `switchingSource` | Switching source... | Cambiando fuente... |
@@ -344,7 +533,6 @@ const language = ref<"en" | "es">("en");
344
533
  | `settings` | Settings | Configuración |
345
534
  | `record` | Record | Grabar |
346
535
  | `stop` | Stop | Detener |
347
- | `minimumRecordingTimeNotReached` | You have not met the minimum recording time yet | Aun no cumples el tiempo minimo de grabacion |
348
536
  | `pause` | Pause | Pausar |
349
537
  | `resume` | Resume | Reanudar |
350
538
  | `mute` | Mute | Silenciar |
@@ -352,9 +540,68 @@ const language = ref<"en" | "es">("en");
352
540
  | `switchSource` | Switch Source | Cambiar Fuente |
353
541
  | `camera` | Camera | Cámara |
354
542
  | `microphone` | Microphone | Micrófono |
543
+ | `microphoneConnecting` | Connecting microphone... | Conectando micrófono... |
544
+ | `minimumRecordingTimeNotReached` | You have not met the minimum recording time yet | Aun no cumples el tiempo minimo de grabacion |
355
545
  | `uploading` | Uploading... | Subiendo... |
356
-
357
- The full key list lives in [`src/i18n/translations.ts`](./src/i18n/translations.ts) — there's a key for every visible string, including the permission flow recovery guide.
546
+ | `finalizing` | Finalizing… | Finalizando… |
547
+ | `retryingUpload` | Retrying upload... | Reintentando subida... |
548
+ | `uploadInsufficientCredits` | This video couldn't be uploaded. Please contact the site administrator. | No se pudo subir el video. Contacta al administrador del sitio. |
549
+ | `uploadInsufficientCreditsTitle` | Video couldn't be uploaded | No se pudo subir el video |
550
+ | `uploadErrorClose` | Close | Cerrar |
551
+ | `finishing` | Finishing... | Finalizando... |
552
+ | `userInAnotherTab` | User in another tab | Usuario en otra pestaña |
553
+ | `download` | Download | Descargar |
554
+ | `nativeCameraSelectVideo` | Select Video from Gallery | Seleccionar Video de la Galería |
555
+ | `nativeCameraRecordVideo` | Record with Camera | Grabar con Cámara |
556
+ | `nativeCameraProcessing` | Processing video... | Procesando video... |
557
+ | `nativeCameraConfigLoading` | Loading settings... | Cargando configuración... |
558
+ | `nativeCameraConfigLoadError` | Failed to load settings | No se pudo cargar la configuración |
559
+ | `nativeCameraPreviewAlt` | Video preview | Vista previa del video |
560
+ | `errorTitle` | Configuration Error | Error de Configuración |
561
+ | `errorApiKeyRequired` | An API Key or access token provider is required. | Se requiere una API Key o un proveedor de token de acceso. |
562
+ | `errorGeneric` | An error occurred while initializing the recorder | Ocurrió un error al inicializar la grabadora |
563
+ | `mobileOpenCamera` | Allow Access | Permitir Acceso |
564
+ | `mobileOpenCameraTitle` | Camera & Microphone | Cámara y Micrófono |
565
+ | `mobileOpenCameraDescription` | We need access to your camera and microphone to start recording | Necesitamos acceso a tu cámara y micrófono para comenzar a grabar |
566
+ | `mobileCloseCamera` | Close | Cerrar |
567
+ | `mobileHideRecordingPrompt` | Hide prompt | Ocultar pregunta |
568
+ | `mobileShowRecordingPrompt` | Show prompt | Mostrar pregunta |
569
+ | `mobilePermissionDenied` | Camera Access Denied | Acceso a Cámara Denegado |
570
+ | `mobilePermissionDeniedDescription` | Please allow camera access in your browser settings to record video. | Por favor permite el acceso a la cámara en la configuración de tu navegador para grabar video. |
571
+ | `permissionFlowTitle` | Set Up Your Camera | Configurar tu Cámara |
572
+ | `permissionFlowCameraTitle` | Camera & Microphone | Cámara y Micrófono |
573
+ | `permissionFlowMicrophoneTitle` | Camera & Microphone | Cámara y Micrófono |
574
+ | `permissionFlowCameraLabel` | We need access to your camera and microphone to start recording | Necesitamos acceso a tu cámara y micrófono para comenzar a grabar |
575
+ | `permissionFlowMicrophoneLabel` | We need access to your camera and microphone to start recording | Necesitamos acceso a tu cámara y micrófono para comenzar a grabar |
576
+ | `permissionFlowStatusPending` | Pending | Pendiente |
577
+ | `permissionFlowStatusGranted` | Ready | Listo |
578
+ | `permissionFlowStatusDenied` | Blocked | Bloqueado |
579
+ | `permissionFlowStatusRequesting` | Click "Allow" in the browser popup above | Haz clic en "Permitir" en el aviso del navegador |
580
+ | `permissionFlowAllowCamera` | Allow Access | Permitir Acceso |
581
+ | `permissionFlowAllowMicrophone` | Allow Access | Permitir Acceso |
582
+ | `permissionFlowRetry` | Try Again | Reintentar |
583
+ | `permissionFlowRecoveryTitle` | Allow access to continue | Permite el acceso para continuar |
584
+ | `permissionFlowRecoveryInstructions` | Open your browser settings and allow camera and microphone access, then try again. | Abre la configuración de tu navegador y permite el acceso a la cámara y micrófono, luego intenta de nuevo. |
585
+ | `permissionFlowConnecting` | Setting up... | Preparando... |
586
+ | `initializingMicrophone` | Initializing microphone... | Iniciando micrófono... |
587
+ | `grantMicrophonePermission` | Grant microphone permission when prompted | Concede el permiso de micrófono cuando se te solicite |
588
+ | `retryMicrophone` | Retry Microphone | Reintentar micrófono |
589
+ | `audioOnlyReady` | Ready to record | Listo para grabar |
590
+ | `audioOnlyRecording` | Recording | Grabando |
591
+ | `audioOnlyPaused` | Paused | En pausa |
592
+ | `audioOnlyUploading` | Uploading {progress}% | Subiendo {progress}% |
593
+ | `audioOnlyUploaded` | Upload complete | Subida completada |
594
+ | `audioOnlyElapsedTime` | Elapsed time | Tiempo transcurrido |
595
+ | `audioOnlyNoMicrophones` | No microphones available | No hay micrófonos disponibles |
596
+ | `audioRecordingDisabledTitle` | Audio recording unavailable | Grabación de audio no disponible |
597
+ | `audioRecordingDisabled` | Audio recording is not enabled for this environment | La grabación de audio no está habilitada para este entorno |
598
+ | `permissionFlowMicrophoneOnlyTitle` | Microphone | Micrófono |
599
+ | `permissionFlowMicrophoneOnlyLabel` | We need access to your microphone to start recording | Necesitamos acceso a tu micrófono para comenzar a grabar |
600
+ | `permissionFlowMicrophoneOnlyRecoveryInstructions` | Open your browser settings and allow microphone access, then try again. | Abre la configuración de tu navegador y permite el acceso al micrófono, luego intenta de nuevo. |
601
+ | `mobileOpenMicrophoneTitle` | Microphone | Micrófono |
602
+ | `mobileOpenMicrophoneDescription` | We need access to your microphone to start recording | Necesitamos acceso a tu micrófono para comenzar a grabar |
603
+
604
+ `TranslationKeys` lists every available key. The full key list lives in [`src/i18n/translations.ts`](./src/i18n/translations.ts) — there's a key for every visible string, including the permission flow recovery guide.
358
605
 
359
606
  ## Mobile experience
360
607
 
@@ -368,6 +615,24 @@ The full key list lives in [`src/i18n/translations.ts`](./src/i18n/translations.
368
615
 
369
616
  The `<VidtreoRecorder>` component probes browser capabilities on mobile and falls back gracefully when `WebCodecs` isn't available.
370
617
 
618
+ ## Audio-only recording
619
+
620
+ Set `audioOnly: true` to record audio with the microphone only:
621
+
622
+ ```vue
623
+ <template>
624
+ <VidtreoRecorder :recorder-props="{ apiKey: 'your-api-key', audioOnly: true }" />
625
+ </template>
626
+ ```
627
+
628
+ - Audio recording must be enabled for the environment in the backend. The environment's audio settings (format, bitrate, max duration) apply, and the max duration is shown next to the timer (for example `00:12 / 10:00`).
629
+ - Only microphone permission is requested. The recorder renders as a compact voice-note pill (about 56px high, at most 20rem wide, light and dark aware): a red record/stop button, a live 18-bar waveform, the timer with the max duration (for example `00:12 / 10:00`) and a microphone button that opens a menu. The menu lists microphones when idle and holds pause/resume and mute/unmute while recording. Status text, permission prompts, errors and the upload-complete message appear on a caption line below the pill, and upload progress runs along the pill; there is no video area. The camera selector, source switching and the tab visibility overlay are not used.
630
+ - On mobile, `mobileMode: "native"` (and `nativeCamera`) is not used; the recorder falls back to `"overlay"`.
631
+ - `upload-complete` receives `mediaType: "audio"` and `audioId`.
632
+ - Demo mode has no environment audio config, so audio-only recording is unavailable there.
633
+
634
+ If audio recording is disabled for the environment, starting the recorder fails with the error code `recording.audio-disabled` (`ERROR_AUDIO_RECORDING_DISABLED` in `@vidtreo/recorder`). The bar shows the `audioRecordingDisabled` message without a retry button, and `error` is emitted with the original error.
635
+
371
636
  ## SSR (Nuxt, Astro-Vue, etc.)
372
637
 
373
638
  Every browser API is gated to `onMounted`/`if (typeof window !== "undefined")`. If you're on Nuxt 3, the cleanest path is the [`@vidtreo/recorder-nuxt`](../recorder-nuxt) module — it registers the component as `client`-only and injects the CSS for you.
@@ -376,10 +641,14 @@ For other SSR setups, wrap the component in `<ClientOnly>` (Nuxt) or guard it be
376
641
 
377
642
  ## TypeScript
378
643
 
379
- Every public surface is typed. Import types directly:
644
+ Every public surface is typed. The package also re-exports `getUploadErrorCode` and `UPLOAD_ERROR_INSUFFICIENT_CREDITS` from `@vidtreo/recorder`. Import types directly:
380
645
 
381
646
  ```ts
382
647
  import type {
648
+ AccessTokenProvider,
649
+ RecordingUploadResult,
650
+ UploadErrorCode,
651
+ UploadProgressPhase,
383
652
  VidtreoRecorderProps,
384
653
  VidtreoRecorderState,
385
654
  VidtreoRecorderActions,
@@ -0,0 +1,8 @@
1
+ type __VLS_Props = {
2
+ className: string;
3
+ isVisible: boolean;
4
+ text: string;
5
+ };
6
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
7
+ declare const _default: typeof __VLS_export;
8
+ export default _default;
@@ -0,0 +1,12 @@
1
+ type __VLS_Props = {
2
+ hideLabel: string;
3
+ isPromptVisible: boolean;
4
+ showLabel: string;
5
+ };
6
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
7
+ toggle: () => any;
8
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
9
+ onToggle?: (() => any) | undefined;
10
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
11
+ declare const _default: typeof __VLS_export;
12
+ export default _default;
@@ -0,0 +1,7 @@
1
+ import type { UseVidtreoRecorderConfig } from "../types";
2
+ type __VLS_Props = {
3
+ config: UseVidtreoRecorderConfig;
4
+ };
5
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
6
+ declare const _default: typeof __VLS_export;
7
+ export default _default;
@@ -0,0 +1,7 @@
1
+ import type { UseVidtreoRecorderConfig } from "../types";
2
+ type __VLS_Props = {
3
+ config: UseVidtreoRecorderConfig;
4
+ };
5
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
6
+ declare const _default: typeof __VLS_export;
7
+ export default _default;
@@ -1,28 +1,23 @@
1
+ import type { RecordingUploadResult, UploadProgressPhase } from "@vidtreo/recorder";
1
2
  import type { VidtreoRecorderProps } from "../types";
2
3
  type __VLS_Props = {
3
4
  recorderProps: VidtreoRecorderProps;
4
5
  };
5
6
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
6
7
  error: (error: Error) => any;
7
- uploadProgress: (progress: number) => any;
8
+ uploadProgress: (progress: number, phase: UploadProgressPhase | null) => any;
8
9
  transcodingProgress: (progress: number) => any;
9
10
  recordingStart: () => any;
10
11
  recordingStop: () => any;
11
- uploadComplete: (result: {
12
- recordingId: string;
13
- uploadUrl: string;
14
- }) => any;
12
+ uploadComplete: (result: RecordingUploadResult) => any;
15
13
  uploadError: (error: Error) => any;
16
14
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
17
15
  onError?: ((error: Error) => any) | undefined;
18
- onUploadProgress?: ((progress: number) => any) | undefined;
16
+ onUploadProgress?: ((progress: number, phase: UploadProgressPhase | null) => any) | undefined;
19
17
  onTranscodingProgress?: ((progress: number) => any) | undefined;
20
18
  onRecordingStart?: (() => any) | undefined;
21
19
  onRecordingStop?: (() => any) | undefined;
22
- onUploadComplete?: ((result: {
23
- recordingId: string;
24
- uploadUrl: string;
25
- }) => any) | undefined;
20
+ onUploadComplete?: ((result: RecordingUploadResult) => any) | undefined;
26
21
  onUploadError?: ((error: Error) => any) | undefined;
27
22
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
28
23
  declare const _default: typeof __VLS_export;
@@ -0,0 +1,24 @@
1
+ import { type RecordingUploadResult, type UploadProgressPhase } from "@vidtreo/recorder";
2
+ import type { VidtreoRecorderProps } from "../types";
3
+ type __VLS_Props = {
4
+ recorderProps: VidtreoRecorderProps;
5
+ };
6
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
7
+ error: (error: Error) => any;
8
+ uploadProgress: (progress: number, phase: UploadProgressPhase | null) => any;
9
+ transcodingProgress: (progress: number) => any;
10
+ recordingStart: () => any;
11
+ recordingStop: () => any;
12
+ uploadComplete: (result: RecordingUploadResult) => any;
13
+ uploadError: (error: Error) => any;
14
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
15
+ onError?: ((error: Error) => any) | undefined;
16
+ onUploadProgress?: ((progress: number, phase: UploadProgressPhase | null) => any) | undefined;
17
+ onTranscodingProgress?: ((progress: number) => any) | undefined;
18
+ onRecordingStart?: (() => any) | undefined;
19
+ onRecordingStop?: (() => any) | undefined;
20
+ onUploadComplete?: ((result: RecordingUploadResult) => any) | undefined;
21
+ onUploadError?: ((error: Error) => any) | undefined;
22
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
23
+ declare const _default: typeof __VLS_export;
24
+ export default _default;
@@ -1,28 +1,23 @@
1
+ import { type RecordingUploadResult, type UploadProgressPhase } from "@vidtreo/recorder";
1
2
  import type { VidtreoRecorderProps } from "../types";
2
3
  type __VLS_Props = {
3
4
  recorderProps: VidtreoRecorderProps;
4
5
  };
5
6
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
6
7
  error: (error: Error) => any;
7
- uploadProgress: (progress: number) => any;
8
+ uploadProgress: (progress: number, phase: UploadProgressPhase | null) => any;
8
9
  transcodingProgress: (progress: number) => any;
9
10
  recordingStart: () => any;
10
11
  recordingStop: () => any;
11
- uploadComplete: (result: {
12
- recordingId: string;
13
- uploadUrl: string;
14
- }) => any;
12
+ uploadComplete: (result: RecordingUploadResult) => any;
15
13
  uploadError: (error: Error) => any;
16
14
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
17
15
  onError?: ((error: Error) => any) | undefined;
18
- onUploadProgress?: ((progress: number) => any) | undefined;
16
+ onUploadProgress?: ((progress: number, phase: UploadProgressPhase | null) => any) | undefined;
19
17
  onTranscodingProgress?: ((progress: number) => any) | undefined;
20
18
  onRecordingStart?: (() => any) | undefined;
21
19
  onRecordingStop?: (() => any) | undefined;
22
- onUploadComplete?: ((result: {
23
- recordingId: string;
24
- uploadUrl: string;
25
- }) => any) | undefined;
20
+ onUploadComplete?: ((result: RecordingUploadResult) => any) | undefined;
26
21
  onUploadError?: ((error: Error) => any) | undefined;
27
22
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
28
23
  declare const _default: typeof __VLS_export;
@@ -0,0 +1,40 @@
1
+ import { type PermissionFlowStep } from "@vidtreo/recorder";
2
+ import type { TranslationKeys } from "../../i18n/translations";
3
+ import type { VidtreoRecorderState } from "../../types";
4
+ type __VLS_Props = {
5
+ state: VidtreoRecorderState;
6
+ audioLevel: number;
7
+ translations: TranslationKeys;
8
+ isStopLocked: boolean;
9
+ isRetrying: boolean;
10
+ permissionStep: PermissionFlowStep | null;
11
+ canRetryPermission: boolean;
12
+ enablePause?: boolean;
13
+ enableMute?: boolean;
14
+ enableDeviceChange?: boolean;
15
+ };
16
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
17
+ record: () => any;
18
+ stop: () => any;
19
+ pause: () => any;
20
+ resume: () => any;
21
+ retry: () => any;
22
+ toggleMute: () => any;
23
+ micChange: (deviceId: string) => any;
24
+ closeUploadError: () => any;
25
+ requestPermission: () => any;
26
+ retryPermission: () => any;
27
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
28
+ onRecord?: (() => any) | undefined;
29
+ onStop?: (() => any) | undefined;
30
+ onPause?: (() => any) | undefined;
31
+ onResume?: (() => any) | undefined;
32
+ onRetry?: (() => any) | undefined;
33
+ onToggleMute?: (() => any) | undefined;
34
+ onMicChange?: ((deviceId: string) => any) | undefined;
35
+ onCloseUploadError?: (() => any) | undefined;
36
+ onRequestPermission?: (() => any) | undefined;
37
+ onRetryPermission?: (() => any) | undefined;
38
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
39
+ declare const _default: typeof __VLS_export;
40
+ export default _default;