Hiyve Components - v1.0.0
    Preparing search index...

    Module @hiyve/react-clips

    @hiyve/react-clips — Clip composition tool with client-side recording, multi-clip grid, and media playback for Hiyve video conferencing.

    @hiyve/react-clips

    Clip composition tool with client-side recording, multi-clip grid, and media playback for Hiyve video conferencing.

    npm install @hiyve/react-clips
    

    Peer dependencies:

    npm install @hiyve/react @hiyve/utilities @mui/material @mui/icons-material @emotion/react @emotion/styled react
    

    Optional peer dependencies:

    • @hiyve/react-collaboration — host ClipComposition inside FileSessionHost for full file-management workflows
    • @hiyve/react-media-player — enhanced clip playback with waveforms, regions, and volume controls (falls back to native <audio> / <video> elements)
    import { HiyveProvider } from '@hiyve/react';
    import { ClipComposition } from '@hiyve/react-clips';

    function App() {
    return (
    <HiyveProvider region="us-east-2">
    <ClipComposition
    enableRecording
    enableDragReorder
    maxClips={10}
    onClipAdded={(clip) => console.log('Added:', clip.name)}
    onError={(err) => console.error(err)}
    />
    </HiyveProvider>
    );
    }

    Tokens are generated automatically when your server uses @hiyve/admin middleware. See @hiyve/react for HiyveProvider configuration options.

    Component Description
    ClipComposition Main composition component with recording, multi-clip grid, and auto-save
    CreateCompositionDialog Dialog for naming a new composition before creation
    ClipSettingsDialog Recording settings: microphone, camera and the capture profile (instrument / voice) for new clips
    ClipRecorder Recording panel for capturing audio and video clips
    ClipPlayer Single clip playback (wraps @hiyve/react-media-player or falls back to native elements)
    ClipGrid Responsive grid layout with drag-and-drop reorder
    ClipToolbar Composition controls (lock, play all, collaboration mode, recorder toggle)
    Hook Description
    useClipRecorder Records audio/video clips client-side. Manages device selection, the audio capture profile, recording lifecycle, and clip upload.
    useClipPersistence Auto-save composition data with configurable interval, manual save, and unsaved change tracking.
    Function Description
    generateCompositionId() Generate a unique composition ID
    generateClipId() Generate a unique clip ID
    getSupportedMimeType(mediaType) Get the first browser-supported MIME type for recording
    formatRecordingDuration(seconds) Format seconds as mm:ss string
    getFileExtensionFromMime(mimeType) Get file extension (.webm, .ogg, .mp4) from a MIME type
    createCompositionFile(client, options) Create and upload a new composition JSON file
    remuxFmp4ToMp4(blob, mimeType?) Remux fragmented MP4 to standard MP4. Use after recording to produce a seekable file for cross-browser playback. Returns the original blob unchanged if it's already flat or remuxing fails.
    clipCompositionDownloadHandler A file-manager download handler (<FileManager downloadHandlers={[clipCompositionDownloadHandler]} />). Downloading a clip composition saves its media instead of its JSON edit list: one clip becomes that clip's audio or video file, several become a ZIP of them. Declines (so the stored file is saved) when the composition has no fetchable clips
    buildStoredZip(entries, now?) / crc32(bytes) Minimal dependency-free ZIP writer (store method) used by the handler; usable for any "several files as one download" case
    Prop Type Default Description
    initialComposition ClipCompositionFile — Initial composition data to load
    title string — Composition title
    fileId string — Existing file ID for updates
    fileLocation string '/Clips' Storage location for composition files
    enableAutoSave boolean true Auto-save composition changes
    enableRecording boolean true Show recording controls
    enableRegions boolean false Enable named regions on clip players
    enableAudioPassthrough boolean false Enable audio passthrough mode. Adds a per-clip passthrough toggle and a toolbar toggle that switches passthrough on every clip together
    enableDragReorder boolean true Enable drag-and-drop clip reordering
    maxClips number 20 Maximum number of clips in the composition
    maxRecordingDuration number 300 Maximum recording duration in seconds
    autoSaveInterval number 5000 Auto-save interval in milliseconds
    showHeader boolean true Show header with title and save status
    showToolbar boolean true Show toolbar with controls
    readOnly boolean false Disable editing
    labels Partial<ClipCompositionLabels> — Custom text labels
    icons Partial<ClipCompositionIcons> — Custom icons (ReactNode)
    colors Partial<ClipCompositionColors> — Custom color values
    styles Partial<ClipCompositionStyles> — Custom style values
    onAutoSave (fileId: string) => void — Called after auto-save completes
    onSaveError (error: Error) => void — Called when a save error occurs
    onChange (composition: ClipCompositionFile) => void — Called when the composition changes
    onClipAdded (clip: ClipItem) => void — Called when a clip is added
    onClipRemoved (clipId: string) => void — Called when a clip is removed
    onError (error: Error) => void — General error callback
    onImportMedia () => void — Shows an "Import Media" toolbar button next to the recorder toggle. Open your own file picker here and add the chosen files as clips via the ref's addClip — lets users bring in existing audio/video instead of recording. Hidden while read-only/locked or at maxClips
    maxHeight string | number — Maximum container height
    sx SxProps<Theme> — MUI sx styling prop

    ClipComposition exposes a ref with the following methods:

    import { useRef } from 'react';
    import { ClipComposition, type ClipCompositionRef } from '@hiyve/react-clips';

    function MyEditor() {
    const ref = useRef<ClipCompositionRef>(null);

    return (
    <>
    <ClipComposition ref={ref} />
    <button onClick={() => ref.current?.save()}>Save Now</button>
    </>
    );
    }
    Method / Property Type Description
    save() () => Promise<string | null> Trigger a manual save, returns file ID
    isSaving boolean Whether currently saving
    hasUnsavedChanges boolean Whether there are unsaved changes
    lastSaved Date | null Timestamp of the last save
    fileId string | null Current file ID
    addClip(clip, options?) (clip: ClipItem, options?: AddClipOptions) => void Add a clip programmatically. No-op if a clip with the same id already exists. Pass { silent: true } when replaying a clip another participant recorded — suppresses onClipAdded (the "recorded here" notification) while onChange still fires
    removeClip(clipId, options?) (clipId: string, options?: RemoveClipOptions) => void Remove a clip by ID. No-op for an unknown id. Pass { silent: true } when replaying another participant's removal — suppresses onClipRemoved while onChange still fires
    getComposition() () => ClipCompositionFile Get the current composition data

    Record audio or video clips with device selection and max duration enforcement:

    import { useClipRecorder } from '@hiyve/react-clips';

    function MyRecorder() {
    const recorder = useClipRecorder({
    maxDuration: 120, // 2 minutes
    onError: (err) => console.error(err),
    });

    return (
    <div>
    <p>State: {recorder.state}</p>
    {recorder.state === 'idle' && (
    <button onClick={recorder.initialize}>Initialize</button>
    )}
    {recorder.state === 'ready' && (
    <button onClick={recorder.start}>Record</button>
    )}
    {recorder.state === 'recording' && (
    <>
    <span>{recorder.duration}s</span>
    <button onClick={recorder.pause}>Pause</button>
    <button onClick={recorder.stop}>Stop</button>
    </>
    )}
    {recorder.state === 'paused' && (
    <>
    <button onClick={recorder.resume}>Resume</button>
    <button onClick={recorder.stop}>Stop</button>
    </>
    )}
    {recorder.state === 'stopped' && recorder.previewUrl && (
    <>
    <audio src={recorder.previewUrl} controls />
    <button onClick={recorder.discard}>Discard</button>
    </>
    )}
    </div>
    );
    }

    Recorder states:

    State Meaning
    idle Recorder has not been initialized — call initialize()
    requesting Requesting camera/microphone permission from the user
    ready Permissions granted and ready to record — call start()
    recording Currently recording — call pause() or stop()
    paused Recording paused — call resume() or stop()
    stopped Recording finished — review previewUrl or discard()
    saving Uploading the recorded clip

    Browsers capture microphone audio for phone calls by default: echo cancellation, noise suppression and automatic gain, downmixed to mono. That flattens an instrument or an audio interface into a compressed, band-limited recording. Clips therefore record with an instrument profile unless the user chooses otherwise: processing off, stereo and 48 kHz requested where the device allows, tracks tagged as music, and the encoder set to 256 kbps stereo (128 kbps mono) instead of the browser's voice-class default.

    The voice profile keeps the browser's speech processing — the right choice for spoken notes, and for recording over speakers, since instrument does not remove speaker sound from the recording.

    The user picks in ClipSettingsDialog; the choice is remembered. Set the starting profile per context with the audioProfile prop on ClipComposition / ClipRecorder, or the option on useClipRecorder; the hook exposes audioProfile and setAudioProfile.

    // A composition used for spoken feedback, recorded over speakers
    <ClipComposition audioProfile="voice" ... />

    Auto-save composition data with retry logic:

    import { useClipPersistence } from '@hiyve/react-clips';

    const persistence = useClipPersistence({
    client,
    clips,
    title: 'My Composition',
    lockMode: 'unlocked',
    collaborationMode: 'public',
    enabled: true,
    userId: 'user-123',
    autoSaveInterval: 5000,
    onSaved: (fileId) => console.log('Saved:', fileId),
    onError: (err) => console.error(err),
    });

    // persistence.save() — trigger manual save
    // persistence.isSaving — currently saving?
    // persistence.hasUnsavedChanges — pending changes?
    // persistence.lastSaved — last save timestamp
    // persistence.fileId — current file ID
    // persistence.markUnsaved() — mark as changed

    For full file-management workflows (browse compositions, create new ones, switch between them) use FileSessionHost from @hiyve/react-collaboration with ClipComposition registered as the editor for the clip-composition resource type. See @hiyve/react-collaboration for details.

    All visual aspects are customizable through four prop objects. Only override the keys you want to change — defaults are applied for the rest.

    ~40 text strings covering header, save status, toolbar, recorder, player, grid, collaboration, and error messages. Includes two functions: lastSaved(date) and clipCount(count).

    <ClipComposition
    labels={{
    title: 'Sound Clips',
    startRecording: 'Record',
    noClips: 'No clips yet — start recording!',
    lastSaved: (date) => `Saved at ${date.toLocaleTimeString()}`,
    }}
    />

    25 icon slots, each accepting a ReactNode. Defaults use @mui/icons-material.

    import { MicNone, FiberManualRecord } from '@mui/icons-material';

    <ClipComposition
    icons={{
    recordAudio: <MicNone />,
    startRecording: <FiberManualRecord color="error" />,
    }}
    />

    24 color values for container, header, toolbar, recorder, grid, clip cards, save status, and collaboration mode indicators.

    <ClipComposition
    colors={{
    containerBackground: '#2d2d2d',
    recordingIndicator: '#e53935',
    clipCardBackground: '#383838',
    }}
    />

    12 numeric/string values for border radius, padding, grid layout, and component dimensions.

    <ClipComposition
    styles={{
    borderRadius: 12,
    gridGap: 16,
    gridMinColumnWidth: 320,
    playerHeight: 150,
    }}
    />
    Default Object Merge Function
    defaultClipCompositionLabels mergeClipCompositionLabels(overrides?)
    defaultClipCompositionIcons mergeClipCompositionIcons(overrides?)
    defaultClipCompositionColors mergeClipCompositionColors(overrides?)
    defaultClipCompositionStyles mergeClipCompositionStyles(overrides?)
    defaultCreateCompositionDialogLabels mergeCreateCompositionDialogLabels(overrides?)
    • Record audio and video clips directly in the browser
    • Multi-clip responsive grid with drag-and-drop reordering
    • Toolbar transport controls for all clips together: synchronized Play All / Stop All, Rewind All, and an audio-passthrough master toggle (when passthrough is enabled)
    • Enhanced playback with waveforms, named regions, and volume controls (when @hiyve/react-media-player is installed)
    • Native <audio> / <video> fallback when media player is not available
    • Auto-save with configurable interval and manual save trigger
    • Lock/unlock compositions to prevent editing
    • Private/public collaboration modes for clip visibility
    • Device selection for microphone and camera
    • Mirror the camera preview while recording video (on by default), remembered between sessions — preview only, the saved clip is never mirrored
    • Pause/resume recording with duration tracking
    • Max recording duration enforcement (configurable, hard limit 30 minutes)
    • Imperative ref API for programmatic control
    • Works both inside and outside HiyveProvider
    • Fully customizable labels, icons, colors, and styles
    Constant Value Description
    DEFAULT_FILE_LOCATION '/Clips' Default storage location
    CLIP_COMPOSITION_FILE_EXTENSION '.json' Composition file extension
    CLIP_COMPOSITION_FILE_MIME_TYPE 'application/json' Composition MIME type
    CLIP_RESOURCE_TYPE 'clip-composition' Resource type identifier for composition files
    CLIP_VIDEO_RESOURCE_TYPE 'clip' Resource type identifier for individual video clip files
    CLIP_AUDIO_RESOURCE_TYPE 'clip-audio' Resource type identifier for individual audio clip files
    DEFAULT_AUTO_SAVE_INTERVAL 5000 Auto-save interval (ms)
    DEFAULT_MAX_RECORDING_DURATION 300 Default max recording (seconds)
    MAX_RECORDING_DURATION_HARD 1800 Hard limit on recording (seconds)
    RECORDING_TIMESLICE 1000 MediaRecorder timeslice (ms)
    DEFAULT_MAX_CLIPS 20 Default max clips per composition
    DEFAULT_GRID_COLUMNS 2 Default grid columns
    PREFERRED_AUDIO_MIME_TYPES string[] Audio MIME type preference order
    PREFERRED_VIDEO_MIME_TYPES string[] Video MIME type preference order
    COLLABORATION_MODES ['private', 'public'] Available collaboration modes
    LOCK_MODES ['locked', 'unlocked'] Available lock modes
    Type Description
    ClipItem A single clip with media type, file reference, duration, regions, and metadata
    ClipCompositionFile Full composition data: title, clips array, lock/collaboration modes, author info
    ClipMediaType 'audio' | 'video'
    CompositionLockMode 'locked' | 'unlocked'
    CollaborationMode 'private' | 'public'
    RecorderState 'idle' | 'requesting' | 'ready' | 'recording' | 'paused' | 'stopped' | 'saving'
    RegionData Named region for clip playback (id, start, end, content)
    GridLayoutItem Custom grid position for a clip
    ClipFileClient File client interface for upload and URL resolution
    ClipCompositionRef Imperative handle exposed by ClipComposition
    CreateCompositionDialogLabels Customizable labels for the create composition dialog
    CreateCompositionDialogProps Props for CreateCompositionDialog
    ClipSettingsDialogProps Props for ClipSettingsDialog
    TimelineMarkerData Marker data (id, time, content, optional authorId, authorName, createdAt, editedAt, color) attached to a clip

    Seven style-generating functions for building custom layouts:

    Function Description
    getContainerStyles(colors, styles) Main container styles
    getHeaderStyles(colors, styles) Header bar styles
    getToolbarStyles(colors, styles) Toolbar styles
    getRecorderStyles(colors, styles) Recorder panel styles
    getGridStyles(colors, styles) CSS Grid layout styles
    getClipCardStyles(colors, styles, isDragging?) Individual clip card styles
    getEmptyStateStyles(colors) Empty state placeholder styles
    • React 18+
    • MUI v9 (@mui/material, @mui/icons-material, @emotion/react, @emotion/styled)
    • @hiyve/react — provides HiyveProvider context (components work outside the provider with limited functionality)
    • @hiyve/utilities — debug logging and retry utilities
    • Browser support: MediaRecorder API required for recording (Chrome, Firefox, Edge, Safari 14.1+)

    Interfaces

    AddClipOptions
    ClipCompositionColors
    ClipCompositionFile
    ClipCompositionIcons
    ClipCompositionLabels
    ClipCompositionProps
    ClipCompositionRef
    ClipCompositionStyles
    ClipDownloadContext
    ClipDownloadFile
    ClipFileClient
    ClipGridProps
    ClipItem
    ClipPlayerProps
    ClipRecorderProps
    ClipSettingsDialogProps
    ClipToolbarProps
    CompositionFileClient
    CreateCompositionDialogLabels
    CreateCompositionDialogProps
    CreateCompositionFileOptions
    CreateCompositionFileResult
    GridLayoutItem
    RegionData
    RemoveClipOptions
    TimelineMarkerData
    UseClipPersistenceOptions
    UseClipPersistenceResult
    UseClipRecorderOptions
    UseClipRecorderResult
    ZipEntry

    Type Aliases

    ClipMediaType
    ClipMutation
    CollaborationMode
    CompositionLockMode
    RecorderState

    Variables

    CLIP_AUDIO_RESOURCE_TYPE
    CLIP_COMPOSITION_FILE_EXTENSION
    CLIP_COMPOSITION_FILE_MIME_TYPE
    CLIP_RESOURCE_TYPE
    CLIP_VIDEO_RESOURCE_TYPE
    ClipComposition
    clipCompositionDownloadHandler
    COLLABORATION_MODES
    DEFAULT_AUTO_SAVE_INTERVAL
    DEFAULT_FILE_LOCATION
    DEFAULT_GRID_COLUMNS
    DEFAULT_MAX_CLIPS
    DEFAULT_MAX_RECORDING_DURATION
    defaultClipCompositionIcons
    defaultClipCompositionLabels
    defaultClipCompositionStyles
    defaultCreateCompositionDialogLabels
    LOCK_MODES
    MAX_RECORDING_DURATION_HARD
    PREFERRED_AUDIO_MIME_TYPES
    PREFERRED_VIDEO_MIME_TYPES
    RECORDING_TIMESLICE

    Functions

    applyClipMutationToClips
    buildDefaultClipCompositionColors
    buildStoredZip
    ClipGrid
    ClipPlayer
    ClipRecorder
    ClipSettingsDialog
    ClipToolbar
    crc32
    CreateCompositionDialog
    createCompositionFile
    formatRecordingDuration
    generateClipId
    generateCompositionId
    getClipCardStyles
    getContainerStyles
    getEmptyStateStyles
    getFileExtensionFromMime
    getGridStyles
    getHeaderStyles
    getRecorderStyles
    getSupportedMimeType
    getToolbarStyles
    mergeClipCompositionColors
    mergeClipCompositionIcons
    mergeClipCompositionLabels
    mergeClipCompositionStyles
    mergeCreateCompositionDialogLabels
    remuxFmp4ToMp4
    useClipPersistence
    useClipRecorder