@vidtreo/recorder-vue 1.13.0 → 1.14.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.
package/README.md CHANGED
@@ -352,8 +352,78 @@ const { state, actions, audioLevel, controller } = useVidtreoRecorder({
352
352
  | `stopPreview` | `() => void` | Tear the preview stream down. |
353
353
  | `downloadVideo` | `() => void` | Download the last `recordedBlob` (demo mode). |
354
354
  | `clearUploadError` | `() => void` | Clear `uploadErrorCode` after the user dismisses the upload error. |
355
+ | `mark` | `(marker: { id: string; label: string }) => void` | Record the current position in the recording. See [Markers](#markers). |
355
356
  | `cleanup` | `() => void` | Release all resources. Useful before unmounting. |
356
357
 
358
+ ### Markers
359
+
360
+ Call `actions.mark({ id, label })` while recording to note where something happens, for example when your UI moves on to the next question. The SDK stores the position in seconds of the recording (without paused time, rounded to the millisecond) and uploads the markers with that recording. The backend returns them as `markers` on the video or audio.
361
+
362
+ ```vue
363
+ <script setup lang="ts">
364
+ import { ref } from "vue";
365
+ import { useVidtreoRecorder } from "@vidtreo/recorder-vue";
366
+
367
+ const questions = [
368
+ { id: "q1", text: "First question" },
369
+ { id: "q2", text: "Second question" },
370
+ ];
371
+ const index = ref(0);
372
+ const { state, actions } = useVidtreoRecorder({ apiKey: "your-api-key" });
373
+
374
+ function next() {
375
+ index.value += 1;
376
+ const question = questions[index.value];
377
+ actions.mark({ id: question.id, label: question.text });
378
+ }
379
+ </script>
380
+
381
+ <template>
382
+ <p>{{ questions[index].text }}</p>
383
+ <button v-if="state.recordingState === 'recording'" @click="next">
384
+ Next question
385
+ </button>
386
+ </template>
387
+ ```
388
+
389
+ For example, `actions.mark({ id: "q2", label: "Second question" })` when the second question appears gives the uploaded video `markers: [{ id: "q2", time: 42.318, label: "Second question" }]`.
390
+
391
+ - Labels are free text. The SDK never reads or changes them.
392
+ - Each recording starts with no markers. Without `mark()` nothing changes and the upload has no `markers` key.
393
+ - Markers are kept in the upload queue, so they are sent when an upload resumes after a reload.
394
+ - `mark()` throws a `RecordingMarkerError` from `@vidtreo/recorder` when no recording is running (a paused recording counts as running), when `id` is not 1 to 64 characters or `label` is not 1 to 500 characters, when the `id` is already used in the recording, or after 200 markers. Its `code` is one of `recording.marker-not-recording`, `recording.marker-invalid-id`, `recording.marker-invalid-label`, `recording.marker-duplicate-id` or `recording.marker-limit-reached`.
395
+ - The stock `VidtreoRecorder` component has no markers UI. Call `mark()` through its template ref (see [Markers with the component](#markers-with-the-component)) or use the composable.
396
+
397
+ ### Markers with the component
398
+
399
+ Put a template ref on the stock `VidtreoRecorder` to mark from your own UI:
400
+
401
+ ```vue
402
+ <script setup lang="ts">
403
+ import { ref } from "vue";
404
+ import {
405
+ VidtreoRecorder,
406
+ type VidtreoRecorderExposed,
407
+ } from "@vidtreo/recorder-vue";
408
+
409
+ const recorderRef = ref<VidtreoRecorderExposed | null>(null);
410
+
411
+ function showSecondQuestion() {
412
+ recorderRef.value?.mark({ id: "q2", label: "Second question" });
413
+ }
414
+ </script>
415
+
416
+ <template>
417
+ <VidtreoRecorder ref="recorderRef" :recorder-props="{ apiKey: 'your-api-key' }" />
418
+ <button @click="showSecondQuestion">Next question</button>
419
+ </template>
420
+ ```
421
+
422
+ - The exposed `mark()` follows the same rules as `actions.mark()`. Before the recorder is ready or when no recording is running, it throws a `RecordingMarkerError` with code `recording.marker-not-recording`.
423
+ - It marks the recording of whichever recorder the component shows: desktop, mobile embed or mobile overlay. In native camera mode (`nativeCamera` or `mobileMode: "native"`) it does nothing, because the device's camera app records outside the page.
424
+ - `StandardRecorder`, `MobileWebRecorderUI` and `NativeCameraUI` expose the same `mark()`, and so does the `<VidtreoRecorder>` that `@vidtreo/recorder-nuxt` auto-imports.
425
+ - `isRecordingMarkerError`, the `ERROR_RECORDING_MARKER_*` codes and the `RecordingMarkerError` type are exported from `@vidtreo/recorder-vue`, so you don't need to import `@vidtreo/recorder`.
426
+
357
427
  ### Specialized composables
358
428
 
359
429
  | Composable | Purpose |
@@ -641,7 +711,7 @@ For other SSR setups, wrap the component in `<ClientOnly>` (Nuxt) or guard it be
641
711
 
642
712
  ## TypeScript
643
713
 
644
- Every public surface is typed. The package also re-exports `getUploadErrorCode` and `UPLOAD_ERROR_INSUFFICIENT_CREDITS` from `@vidtreo/recorder`. Import types directly:
714
+ Every public surface is typed. The package also re-exports `getUploadErrorCode`, `UPLOAD_ERROR_INSUFFICIENT_CREDITS`, `isRecordingMarkerError`, the `ERROR_RECORDING_MARKER_*` codes and the `RecordingMarkerError` type from `@vidtreo/recorder`. Import types directly:
645
715
 
646
716
  ```ts
647
717
  import type {
@@ -659,6 +729,7 @@ import type {
659
729
  MobileMode,
660
730
  AudioWarning,
661
731
  RecordingStopResult,
732
+ VidtreoRecorderExposed,
662
733
  } from "@vidtreo/recorder-vue";
663
734
  ```
664
735
 
@@ -1,7 +1,7 @@
1
- import type { UseVidtreoRecorderConfig } from "../types";
1
+ import type { UseVidtreoRecorderConfig, VidtreoRecorderExposed } from "../types";
2
2
  type __VLS_Props = {
3
3
  config: UseVidtreoRecorderConfig;
4
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>;
5
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, VidtreoRecorderExposed, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
6
6
  declare const _default: typeof __VLS_export;
7
7
  export default _default;
@@ -1,7 +1,7 @@
1
- import type { UseVidtreoRecorderConfig } from "../types";
1
+ import type { UseVidtreoRecorderConfig, VidtreoRecorderExposed } from "../types";
2
2
  type __VLS_Props = {
3
3
  config: UseVidtreoRecorderConfig;
4
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>;
5
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, VidtreoRecorderExposed, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
6
6
  declare const _default: typeof __VLS_export;
7
7
  export default _default;
@@ -1,7 +1,7 @@
1
- import type { UseVidtreoRecorderConfig } from "../types";
1
+ import type { UseVidtreoRecorderConfig, VidtreoRecorderExposed } from "../types";
2
2
  type __VLS_Props = {
3
3
  config: UseVidtreoRecorderConfig;
4
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>;
5
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, VidtreoRecorderExposed, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
6
6
  declare const _default: typeof __VLS_export;
7
7
  export default _default;
@@ -1,9 +1,9 @@
1
1
  import type { RecordingUploadResult, UploadProgressPhase } from "@vidtreo/recorder";
2
- import type { VidtreoRecorderProps } from "../types";
2
+ import type { VidtreoRecorderExposed, VidtreoRecorderProps } from "../types";
3
3
  type __VLS_Props = {
4
4
  recorderProps: VidtreoRecorderProps;
5
5
  };
6
- declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
6
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, VidtreoRecorderExposed, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
7
7
  error: (error: Error) => any;
8
8
  uploadProgress: (progress: number, phase: UploadProgressPhase | null) => any;
9
9
  transcodingProgress: (progress: number) => any;
@@ -1,9 +1,9 @@
1
1
  import { type RecordingUploadResult, type UploadProgressPhase } from "@vidtreo/recorder";
2
- import type { VidtreoRecorderProps } from "../types";
2
+ import type { VidtreoRecorderExposed, VidtreoRecorderProps } from "../types";
3
3
  type __VLS_Props = {
4
4
  recorderProps: VidtreoRecorderProps;
5
5
  };
6
- declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
6
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, VidtreoRecorderExposed, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
7
7
  error: (error: Error) => any;
8
8
  uploadProgress: (progress: number, phase: UploadProgressPhase | null) => any;
9
9
  transcodingProgress: (progress: number) => any;
@@ -1,9 +1,9 @@
1
1
  import { type RecordingUploadResult, type UploadProgressPhase } from "@vidtreo/recorder";
2
- import type { VidtreoRecorderProps } from "../types";
2
+ import type { VidtreoRecorderExposed, VidtreoRecorderProps } from "../types";
3
3
  type __VLS_Props = {
4
4
  recorderProps: VidtreoRecorderProps;
5
5
  };
6
- declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
6
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, VidtreoRecorderExposed, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
7
7
  error: (error: Error) => any;
8
8
  uploadProgress: (progress: number, phase: UploadProgressPhase | null) => any;
9
9
  transcodingProgress: (progress: number) => any;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import "@vidtreo/ui-styles/recorder.css";
2
- export { CONFIG_ERROR_CREDENTIAL_CONFLICT, getUploadErrorCode, isCredentialConflictError, UPLOAD_ERROR_INSUFFICIENT_CREDITS, } from "@vidtreo/recorder";
2
+ export { CONFIG_ERROR_CREDENTIAL_CONFLICT, ERROR_RECORDING_MARKER_DUPLICATE_ID, ERROR_RECORDING_MARKER_INVALID_ID, ERROR_RECORDING_MARKER_INVALID_LABEL, ERROR_RECORDING_MARKER_LIMIT_REACHED, ERROR_RECORDING_MARKER_NOT_RECORDING, getUploadErrorCode, isCredentialConflictError, isRecordingMarkerError, type RecordingMarkerError, type RecordingMarkerErrorCode, UPLOAD_ERROR_INSUFFICIENT_CREDITS, } from "@vidtreo/recorder";
3
3
  export { default as MobileWebRecorderUI } from "./components/MobileWebRecorderUI.vue";
4
4
  export { default as NativeCameraUI } from "./components/NativeCameraUI.vue";
5
5
  export { default as StandardRecorder } from "./components/StandardRecorder.vue";
@@ -14,4 +14,4 @@ export type { ButtonTranslations, PreviewTranslations, RecorderTranslations, Set
14
14
  export { useRecorderTranslations } from "./composables/use-recorder-translations";
15
15
  export { useVidtreoRecorder } from "./composables/use-vidtreo-recorder";
16
16
  export { defaultTranslations, getTranslations, type PartialTranslations, type TranslationKeys, } from "./i18n/translations";
17
- export type { AccessTokenProvider, AudioWarning, MediaType, MobileMode, RecordingPrompt, RecordingPromptCountdown, RecordingPromptCountdownPlacement, RecordingState, RecordingStopResult, RecordingUploadResult, SourceType, UploadErrorCode, UploadProgressPhase, UseVidtreoRecorderConfig, UseVidtreoRecorderReturn, VidtreoRecorderActions, VidtreoRecorderEmits, VidtreoRecorderProps, VidtreoRecorderState, } from "./types";
17
+ export type { AccessTokenProvider, AudioWarning, MediaType, MobileMode, RecordingMarker, RecordingMarkerInput, RecordingPrompt, RecordingPromptCountdown, RecordingPromptCountdownPlacement, RecordingState, RecordingStopResult, RecordingUploadResult, SourceType, UploadErrorCode, UploadProgressPhase, UseVidtreoRecorderConfig, UseVidtreoRecorderReturn, VidtreoRecorderActions, VidtreoRecorderEmits, VidtreoRecorderExposed, VidtreoRecorderProps, VidtreoRecorderState, } from "./types";