@waveform-playlist/browser 5.0.0-alpha.8 → 5.0.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/dist/index.d.ts +282 -12
- package/dist/index.js +145 -128
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3656 -4360
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -11
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { default as default_3 } from 'waveform-data';
|
|
|
4
4
|
import { DragEndEvent } from '@dnd-kit/core';
|
|
5
5
|
import { Fade as Fade_2 } from '@waveform-playlist/core';
|
|
6
6
|
import { Gain } from 'tone';
|
|
7
|
+
import { MediaElementPlayout } from '@waveform-playlist/media-element-playout';
|
|
7
8
|
import { MutableRefObject } from 'react';
|
|
8
9
|
import react__default from 'react';
|
|
9
10
|
import { ReactNode } from 'react';
|
|
@@ -50,7 +51,7 @@ declare interface AnnotationActionOptions {
|
|
|
50
51
|
[key: string]: unknown;
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
declare interface AnnotationData {
|
|
54
|
+
export declare interface AnnotationData {
|
|
54
55
|
id: string;
|
|
55
56
|
start: number;
|
|
56
57
|
end: number;
|
|
@@ -58,24 +59,56 @@ declare interface AnnotationData {
|
|
|
58
59
|
language?: string;
|
|
59
60
|
}
|
|
60
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Shared annotation types used across Waveform components
|
|
64
|
+
*/
|
|
65
|
+
/**
|
|
66
|
+
* Base annotation data structure
|
|
67
|
+
*/
|
|
68
|
+
declare interface AnnotationData_2 {
|
|
69
|
+
id: string;
|
|
70
|
+
start: number;
|
|
71
|
+
end: number;
|
|
72
|
+
lines: string[];
|
|
73
|
+
}
|
|
74
|
+
|
|
61
75
|
/**
|
|
62
76
|
* Represents a single audio clip on the timeline
|
|
63
77
|
*
|
|
64
78
|
* IMPORTANT: All positions/durations are stored as SAMPLE COUNTS (integers)
|
|
65
79
|
* to avoid floating-point precision errors. Convert to seconds only when
|
|
66
80
|
* needed for playback using: seconds = samples / sampleRate
|
|
81
|
+
*
|
|
82
|
+
* Clips can be created with just waveformData (for instant visual rendering)
|
|
83
|
+
* and have audioBuffer added later when audio finishes loading.
|
|
67
84
|
*/
|
|
68
85
|
export declare interface AudioClip {
|
|
69
86
|
/** Unique identifier for this clip */
|
|
70
87
|
id: string;
|
|
71
|
-
/**
|
|
72
|
-
|
|
88
|
+
/**
|
|
89
|
+
* The audio buffer containing the audio data.
|
|
90
|
+
* Optional for peaks-first rendering - can be added later.
|
|
91
|
+
* Required for playback and editing operations.
|
|
92
|
+
*/
|
|
93
|
+
audioBuffer?: AudioBuffer;
|
|
73
94
|
/** Position on timeline where this clip starts (in samples at timeline sampleRate) */
|
|
74
95
|
startSample: number;
|
|
75
96
|
/** Duration of this clip (in samples) - how much of the audio buffer to play */
|
|
76
97
|
durationSamples: number;
|
|
77
98
|
/** Offset into the audio buffer where playback starts (in samples) - the "trim start" point */
|
|
78
99
|
offsetSamples: number;
|
|
100
|
+
/**
|
|
101
|
+
* Sample rate for this clip's audio.
|
|
102
|
+
* Required when audioBuffer is not provided (for peaks-first rendering).
|
|
103
|
+
* When audioBuffer is present, this should match audioBuffer.sampleRate.
|
|
104
|
+
*/
|
|
105
|
+
sampleRate: number;
|
|
106
|
+
/**
|
|
107
|
+
* Total duration of the source audio in samples.
|
|
108
|
+
* Required when audioBuffer is not provided (for trim bounds calculation).
|
|
109
|
+
* When audioBuffer is present, this should equal audioBuffer.length.
|
|
110
|
+
*/
|
|
111
|
+
sourceDurationSamples: number;
|
|
79
112
|
/** Optional fade in effect */
|
|
80
113
|
fadeIn?: Fade;
|
|
81
114
|
/** Optional fade out effect */
|
|
@@ -106,9 +139,20 @@ export declare const AudioPosition: default_2.FC<{
|
|
|
106
139
|
|
|
107
140
|
/**
|
|
108
141
|
* Configuration for a single audio track to load
|
|
142
|
+
*
|
|
143
|
+
* Audio can be provided in three ways:
|
|
144
|
+
* 1. `src` - URL to fetch and decode (standard loading)
|
|
145
|
+
* 2. `audioBuffer` - Pre-loaded AudioBuffer (skip fetch/decode)
|
|
146
|
+
* 3. `waveformData` only - Peaks-first rendering (audio loads later)
|
|
147
|
+
*
|
|
148
|
+
* For peaks-first rendering, just provide `waveformData` - the sample rate
|
|
149
|
+
* and duration are derived from the waveform data automatically.
|
|
109
150
|
*/
|
|
110
151
|
export declare interface AudioTrackConfig {
|
|
111
|
-
|
|
152
|
+
/** URL to audio file - used if audioBuffer not provided */
|
|
153
|
+
src?: string;
|
|
154
|
+
/** Pre-loaded AudioBuffer - skips fetch/decode if provided */
|
|
155
|
+
audioBuffer?: AudioBuffer;
|
|
112
156
|
name?: string;
|
|
113
157
|
muted?: boolean;
|
|
114
158
|
soloed?: boolean;
|
|
@@ -380,6 +424,21 @@ export declare const FastForwardButton: default_2.FC<{
|
|
|
380
424
|
className?: string;
|
|
381
425
|
}>;
|
|
382
426
|
|
|
427
|
+
/**
|
|
428
|
+
* Custom function to generate the label shown on annotation boxes in the waveform.
|
|
429
|
+
* Receives the annotation data and its index in the list, returns a string label.
|
|
430
|
+
* Default behavior: displays annotation.id
|
|
431
|
+
*
|
|
432
|
+
* @example
|
|
433
|
+
* // Show sequence numbers
|
|
434
|
+
* getAnnotationBoxLabel={(annotation, index) => String(index + 1)}
|
|
435
|
+
*
|
|
436
|
+
* @example
|
|
437
|
+
* // Show formatted time
|
|
438
|
+
* getAnnotationBoxLabel={(annotation) => formatTime(annotation.start)}
|
|
439
|
+
*/
|
|
440
|
+
export declare type GetAnnotationBoxLabelFn = (annotation: AnnotationData_2, index: number) => string;
|
|
441
|
+
|
|
383
442
|
export declare const getEffectDefinition: (id: string) => EffectDefinition | undefined;
|
|
384
443
|
|
|
385
444
|
export declare const getEffectsByCategory: (category: EffectDefinition["category"]) => EffectDefinition[];
|
|
@@ -500,12 +559,165 @@ export declare interface MasterVolumeControls {
|
|
|
500
559
|
setMasterVolume: (volume: number) => void;
|
|
501
560
|
}
|
|
502
561
|
|
|
562
|
+
export declare interface MediaElementAnimationContextValue {
|
|
563
|
+
isPlaying: boolean;
|
|
564
|
+
currentTime: number;
|
|
565
|
+
currentTimeRef: default_2.RefObject<number>;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
export declare interface MediaElementControlsContextValue {
|
|
569
|
+
play: (startTime?: number) => void;
|
|
570
|
+
pause: () => void;
|
|
571
|
+
stop: () => void;
|
|
572
|
+
seekTo: (time: number) => void;
|
|
573
|
+
setPlaybackRate: (rate: number) => void;
|
|
574
|
+
setContinuousPlay: (enabled: boolean) => void;
|
|
575
|
+
setAnnotations: (annotations: AnnotationData[]) => void;
|
|
576
|
+
setActiveAnnotationId: (id: string | null) => void;
|
|
577
|
+
setAutomaticScroll: (enabled: boolean) => void;
|
|
578
|
+
setScrollContainer: (element: HTMLDivElement | null) => void;
|
|
579
|
+
scrollContainerRef: default_2.RefObject<HTMLDivElement | null>;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
export declare interface MediaElementDataContextValue {
|
|
583
|
+
duration: number;
|
|
584
|
+
peaksDataArray: TrackClipPeaks[];
|
|
585
|
+
sampleRate: number;
|
|
586
|
+
waveHeight: number;
|
|
587
|
+
timeScaleHeight: number;
|
|
588
|
+
samplesPerPixel: number;
|
|
589
|
+
playoutRef: default_2.RefObject<MediaElementPlayout | null>;
|
|
590
|
+
controls: {
|
|
591
|
+
show: boolean;
|
|
592
|
+
width: number;
|
|
593
|
+
};
|
|
594
|
+
barWidth: number;
|
|
595
|
+
barGap: number;
|
|
596
|
+
progressBarWidth: number;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/**
|
|
600
|
+
* MediaElementPlaylistProvider
|
|
601
|
+
*
|
|
602
|
+
* A simplified playlist provider for single-track playback using HTMLAudioElement.
|
|
603
|
+
* Key features:
|
|
604
|
+
* - Pitch-preserving playback rate (0.5x - 2.0x)
|
|
605
|
+
* - Pre-computed peaks visualization (no AudioBuffer needed)
|
|
606
|
+
* - Simpler API than full WaveformPlaylistProvider
|
|
607
|
+
*
|
|
608
|
+
* Use this for:
|
|
609
|
+
* - Language learning apps (speed control)
|
|
610
|
+
* - Podcast players
|
|
611
|
+
* - Single-track audio viewers
|
|
612
|
+
*
|
|
613
|
+
* For multi-track editing, use WaveformPlaylistProvider instead.
|
|
614
|
+
*/
|
|
615
|
+
export declare const MediaElementPlaylistProvider: default_2.FC<MediaElementPlaylistProviderProps>;
|
|
616
|
+
|
|
617
|
+
declare interface MediaElementPlaylistProviderProps {
|
|
618
|
+
/** Single track configuration with source URL and waveform data */
|
|
619
|
+
track: MediaElementTrackConfig;
|
|
620
|
+
/** Initial samples per pixel (zoom level) */
|
|
621
|
+
samplesPerPixel?: number;
|
|
622
|
+
/** Height of each waveform track */
|
|
623
|
+
waveHeight?: number;
|
|
624
|
+
/** Show timescale */
|
|
625
|
+
timescale?: boolean;
|
|
626
|
+
/** Initial playback rate (0.5 to 2.0) */
|
|
627
|
+
playbackRate?: number;
|
|
628
|
+
/** Enable automatic scroll to keep playhead centered */
|
|
629
|
+
automaticScroll?: boolean;
|
|
630
|
+
/** Theme configuration */
|
|
631
|
+
theme?: Partial<WaveformPlaylistTheme>;
|
|
632
|
+
/** Track controls configuration */
|
|
633
|
+
controls?: {
|
|
634
|
+
show: boolean;
|
|
635
|
+
width: number;
|
|
636
|
+
};
|
|
637
|
+
/** Annotations */
|
|
638
|
+
annotationList?: {
|
|
639
|
+
annotations?: any[];
|
|
640
|
+
isContinuousPlay?: boolean;
|
|
641
|
+
};
|
|
642
|
+
/** Width of waveform bars */
|
|
643
|
+
barWidth?: number;
|
|
644
|
+
/** Gap between waveform bars */
|
|
645
|
+
barGap?: number;
|
|
646
|
+
/** Width of progress bars */
|
|
647
|
+
progressBarWidth?: number;
|
|
648
|
+
/** Callback when audio is ready */
|
|
649
|
+
onReady?: () => void;
|
|
650
|
+
children: ReactNode;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
export declare interface MediaElementStateContextValue {
|
|
654
|
+
continuousPlay: boolean;
|
|
655
|
+
annotations: AnnotationData[];
|
|
656
|
+
activeAnnotationId: string | null;
|
|
657
|
+
playbackRate: number;
|
|
658
|
+
isAutomaticScroll: boolean;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
export declare interface MediaElementTrackConfig {
|
|
662
|
+
/** Audio source URL or Blob URL */
|
|
663
|
+
source: string;
|
|
664
|
+
/** Pre-computed waveform data (required for visualization) */
|
|
665
|
+
waveformData: WaveformDataObject;
|
|
666
|
+
/** Track name for display */
|
|
667
|
+
name?: string;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
/**
|
|
671
|
+
* Simplified Waveform component for MediaElementPlaylistProvider
|
|
672
|
+
*
|
|
673
|
+
* This is a stripped-down version of Waveform that works with the
|
|
674
|
+
* MediaElement context. It supports:
|
|
675
|
+
* - Single track visualization
|
|
676
|
+
* - Click to seek
|
|
677
|
+
* - Annotation display and click-to-play
|
|
678
|
+
* - Playhead animation
|
|
679
|
+
*
|
|
680
|
+
* For multi-track editing, use the full Waveform with WaveformPlaylistProvider.
|
|
681
|
+
*/
|
|
682
|
+
export declare const MediaElementWaveform: default_2.FC<MediaElementWaveformProps>;
|
|
683
|
+
|
|
684
|
+
export declare interface MediaElementWaveformProps {
|
|
685
|
+
/** Height in pixels for the annotation text list */
|
|
686
|
+
annotationTextHeight?: number;
|
|
687
|
+
/** Custom function to generate the label shown on annotation boxes */
|
|
688
|
+
getAnnotationBoxLabel?: GetAnnotationBoxLabelFn;
|
|
689
|
+
/**
|
|
690
|
+
* Custom render function for annotation items in the text list.
|
|
691
|
+
* When provided, completely replaces the default annotation item rendering.
|
|
692
|
+
* Use this to customize the appearance of each annotation (e.g., add furigana).
|
|
693
|
+
*/
|
|
694
|
+
renderAnnotationItem?: (props: RenderAnnotationItemProps) => default_2.ReactNode;
|
|
695
|
+
/** Whether annotation boundaries can be edited by dragging. Defaults to false. */
|
|
696
|
+
editable?: boolean;
|
|
697
|
+
/**
|
|
698
|
+
* Callback when annotations are updated (e.g., boundaries dragged).
|
|
699
|
+
* Called with the full updated annotations array.
|
|
700
|
+
*/
|
|
701
|
+
onAnnotationUpdate?: OnAnnotationUpdateFn;
|
|
702
|
+
/** Where to position the active annotation when auto-scrolling: 'center', 'start', 'end', or 'nearest'. Defaults to 'center'. */
|
|
703
|
+
scrollActivePosition?: ScrollLogicalPosition;
|
|
704
|
+
/** Which scrollable containers to scroll: 'nearest' (only the annotation list) or 'all' (including viewport). Defaults to 'nearest'. */
|
|
705
|
+
scrollActiveContainer?: 'nearest' | 'all';
|
|
706
|
+
className?: string;
|
|
707
|
+
}
|
|
708
|
+
|
|
503
709
|
declare interface MicrophoneDevice {
|
|
504
710
|
deviceId: string;
|
|
505
711
|
label: string;
|
|
506
712
|
groupId: string;
|
|
507
713
|
}
|
|
508
714
|
|
|
715
|
+
/**
|
|
716
|
+
* Callback when annotations are updated (e.g., boundaries dragged).
|
|
717
|
+
* Called with the full updated annotations array.
|
|
718
|
+
*/
|
|
719
|
+
export declare type OnAnnotationUpdateFn = (annotations: AnnotationData_2[]) => void;
|
|
720
|
+
|
|
509
721
|
/**
|
|
510
722
|
* Effect definitions for all available Tone.js effects
|
|
511
723
|
* Each effect has parameters with min/max/default values for UI controls
|
|
@@ -643,6 +855,17 @@ declare interface PlaylistStateContextValue {
|
|
|
643
855
|
loopEnd: number;
|
|
644
856
|
}
|
|
645
857
|
|
|
858
|
+
/**
|
|
859
|
+
* Props passed to the renderAnnotationItem function for custom rendering
|
|
860
|
+
*/
|
|
861
|
+
export declare interface RenderAnnotationItemProps {
|
|
862
|
+
annotation: AnnotationData;
|
|
863
|
+
index: number;
|
|
864
|
+
isActive: boolean;
|
|
865
|
+
onClick: () => void;
|
|
866
|
+
formatTime: (seconds: number) => string;
|
|
867
|
+
}
|
|
868
|
+
|
|
646
869
|
/**
|
|
647
870
|
* Type for custom playhead render functions.
|
|
648
871
|
* Receives position, color, and animation refs for smooth 60fps animation.
|
|
@@ -968,7 +1191,8 @@ declare interface UseAnnotationKeyboardControlsOptions {
|
|
|
968
1191
|
* with a single clip per track. Supports custom positioning for multi-clip arrangements.
|
|
969
1192
|
*
|
|
970
1193
|
* @param configs - Array of audio track configurations
|
|
971
|
-
* @
|
|
1194
|
+
* @param options - Optional configuration for loading behavior
|
|
1195
|
+
* @returns Object with tracks array, loading state, and progress info
|
|
972
1196
|
*
|
|
973
1197
|
* @example
|
|
974
1198
|
* ```typescript
|
|
@@ -978,25 +1202,48 @@ declare interface UseAnnotationKeyboardControlsOptions {
|
|
|
978
1202
|
* { src: 'audio/drums.mp3', name: 'Drums' },
|
|
979
1203
|
* ]);
|
|
980
1204
|
*
|
|
981
|
-
* //
|
|
982
|
-
* const { tracks, loading,
|
|
983
|
-
* { src: 'audio/
|
|
984
|
-
* {
|
|
985
|
-
*
|
|
1205
|
+
* // Progressive loading (tracks appear as they load)
|
|
1206
|
+
* const { tracks, loading, loadedCount, totalCount } = useAudioTracks(
|
|
1207
|
+
* [{ src: 'audio/vocals.mp3' }, { src: 'audio/drums.mp3' }],
|
|
1208
|
+
* { progressive: true }
|
|
1209
|
+
* );
|
|
1210
|
+
*
|
|
1211
|
+
* // Pre-loaded AudioBuffer (skip fetch/decode)
|
|
1212
|
+
* const { tracks } = useAudioTracks([
|
|
1213
|
+
* { audioBuffer: myPreloadedBuffer, name: 'Pre-loaded' },
|
|
986
1214
|
* ]);
|
|
987
1215
|
*
|
|
988
|
-
*
|
|
1216
|
+
* // Peaks-first rendering (instant visual, audio loads later)
|
|
1217
|
+
* const { tracks } = useAudioTracks([
|
|
1218
|
+
* { waveformData: preloadedPeaks, name: 'Peaks Only' }, // Renders immediately
|
|
1219
|
+
* ]);
|
|
1220
|
+
*
|
|
1221
|
+
* if (loading) return <div>Loading {loadedCount}/{totalCount}...</div>;
|
|
989
1222
|
* if (error) return <div>Error: {error}</div>;
|
|
990
1223
|
*
|
|
991
1224
|
* return <WaveformPlaylistProvider tracks={tracks}>...</WaveformPlaylistProvider>;
|
|
992
1225
|
* ```
|
|
993
1226
|
*/
|
|
994
|
-
export declare function useAudioTracks(configs: AudioTrackConfig[]): {
|
|
1227
|
+
export declare function useAudioTracks(configs: AudioTrackConfig[], options?: UseAudioTracksOptions): {
|
|
995
1228
|
tracks: ClipTrack[];
|
|
996
1229
|
loading: boolean;
|
|
997
1230
|
error: string | null;
|
|
1231
|
+
loadedCount: number;
|
|
1232
|
+
totalCount: number;
|
|
998
1233
|
};
|
|
999
1234
|
|
|
1235
|
+
/**
|
|
1236
|
+
* Options for useAudioTracks hook
|
|
1237
|
+
*/
|
|
1238
|
+
declare interface UseAudioTracksOptions {
|
|
1239
|
+
/**
|
|
1240
|
+
* When true, tracks are added to the playlist progressively as they load,
|
|
1241
|
+
* rather than waiting for all tracks to finish loading.
|
|
1242
|
+
* Default: false (wait for all tracks)
|
|
1243
|
+
*/
|
|
1244
|
+
progressive?: boolean;
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1000
1247
|
/**
|
|
1001
1248
|
* Custom hook for handling clip drag operations (movement and trimming)
|
|
1002
1249
|
*
|
|
@@ -1249,6 +1496,14 @@ declare interface UseMasterVolumeProps {
|
|
|
1249
1496
|
onVolumeChange?: (volume: number) => void;
|
|
1250
1497
|
}
|
|
1251
1498
|
|
|
1499
|
+
export declare const useMediaElementAnimation: () => MediaElementAnimationContextValue;
|
|
1500
|
+
|
|
1501
|
+
export declare const useMediaElementControls: () => MediaElementControlsContextValue;
|
|
1502
|
+
|
|
1503
|
+
export declare const useMediaElementData: () => MediaElementDataContextValue;
|
|
1504
|
+
|
|
1505
|
+
export declare const useMediaElementState: () => MediaElementStateContextValue;
|
|
1506
|
+
|
|
1252
1507
|
export declare const usePlaybackAnimation: () => PlaybackAnimationContextValue;
|
|
1253
1508
|
|
|
1254
1509
|
/**
|
|
@@ -1599,6 +1854,21 @@ export declare interface WaveformProps {
|
|
|
1599
1854
|
annotationControls?: AnnotationAction[];
|
|
1600
1855
|
annotationListConfig?: AnnotationActionOptions;
|
|
1601
1856
|
annotationTextHeight?: number;
|
|
1857
|
+
/**
|
|
1858
|
+
* Custom render function for annotation items in the text list.
|
|
1859
|
+
* Use this to completely customize how each annotation is displayed.
|
|
1860
|
+
*/
|
|
1861
|
+
renderAnnotationItem?: (props: RenderAnnotationItemProps) => ReactNode;
|
|
1862
|
+
/**
|
|
1863
|
+
* Custom function to generate the label shown on annotation boxes in the waveform.
|
|
1864
|
+
* Receives the annotation data and its index, returns a string label.
|
|
1865
|
+
* Default: annotation.id
|
|
1866
|
+
*/
|
|
1867
|
+
getAnnotationBoxLabel?: GetAnnotationBoxLabelFn;
|
|
1868
|
+
/** Where to position the active annotation when auto-scrolling: 'center', 'start', 'end', or 'nearest'. Defaults to 'center'. */
|
|
1869
|
+
scrollActivePosition?: ScrollLogicalPosition;
|
|
1870
|
+
/** Which scrollable containers to scroll: 'nearest' (only the annotation list) or 'all' (including viewport). Defaults to 'nearest'. */
|
|
1871
|
+
scrollActiveContainer?: 'nearest' | 'all';
|
|
1602
1872
|
className?: string;
|
|
1603
1873
|
showClipHeaders?: boolean;
|
|
1604
1874
|
interactiveClips?: boolean;
|