@waveform-playlist/browser 10.3.0 → 11.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.mts CHANGED
@@ -505,7 +505,6 @@ interface UseClipDragHandlersOptions {
505
505
  tracks: ClipTrack[];
506
506
  onTracksChange: (tracks: ClipTrack[]) => void;
507
507
  samplesPerPixel: number;
508
- sampleRate: number;
509
508
  engineRef: React__default.RefObject<PlaylistEngine | null>;
510
509
  /** Ref toggled during boundary trim drags. When true, the provider's loadAudio
511
510
  * skips engine rebuilds so engine keeps original clip positions. On drag end,
@@ -536,7 +535,6 @@ interface UseClipDragHandlersOptions {
536
535
  * tracks,
537
536
  * onTracksChange: setTracks,
538
537
  * samplesPerPixel,
539
- * sampleRate,
540
538
  * engineRef: playoutRef,
541
539
  * isDraggingRef,
542
540
  * });
@@ -553,7 +551,7 @@ interface UseClipDragHandlersOptions {
553
551
  * );
554
552
  * ```
555
553
  */
556
- declare function useClipDragHandlers({ tracks, onTracksChange, samplesPerPixel, sampleRate, engineRef, isDraggingRef, snapSamplePosition, }: UseClipDragHandlersOptions): {
554
+ declare function useClipDragHandlers({ tracks, onTracksChange, samplesPerPixel, engineRef, isDraggingRef, snapSamplePosition, }: UseClipDragHandlersOptions): {
557
555
  onDragStart: (event: Parameters<DragStartEvent>[0]) => void;
558
556
  onDragMove: (event: Parameters<DragMoveEvent>[0]) => void;
559
557
  onDragEnd: (event: Parameters<DragEndEvent>[0]) => void;
@@ -563,7 +561,8 @@ interface UseAnnotationDragHandlersOptions {
563
561
  annotations: AnnotationData[];
564
562
  onAnnotationsChange: (annotations: AnnotationData[]) => void;
565
563
  samplesPerPixel: number;
566
- sampleRate: number;
564
+ /** Sample rate for pixel-to-time conversion. Defaults to AudioContext.sampleRate. */
565
+ sampleRate?: number;
567
566
  duration: number;
568
567
  linkEndpoints: boolean;
569
568
  }
@@ -579,7 +578,6 @@ interface UseAnnotationDragHandlersOptions {
579
578
  * annotations,
580
579
  * onAnnotationsChange: setAnnotations,
581
580
  * samplesPerPixel,
582
- * sampleRate,
583
581
  * duration,
584
582
  * linkEndpoints,
585
583
  * });
@@ -654,7 +652,6 @@ declare function useDragSensors(options?: DragSensorOptions): (typeof PointerSen
654
652
 
655
653
  interface UseClipSplittingOptions {
656
654
  tracks: ClipTrack[];
657
- sampleRate: number;
658
655
  samplesPerPixel: number;
659
656
  engineRef: React__default.RefObject<PlaylistEngine | null>;
660
657
  }
@@ -676,7 +673,6 @@ interface UseClipSplittingResult {
676
673
  * ```tsx
677
674
  * const { splitClipAtPlayhead } = useClipSplitting({
678
675
  * tracks,
679
- * sampleRate,
680
676
  * samplesPerPixel,
681
677
  * engineRef: playoutRef,
682
678
  * });
@@ -806,10 +802,6 @@ interface UseAnnotationKeyboardControlsOptions {
806
802
  enabled?: boolean;
807
803
  /** Optional: scroll container ref for auto-scrolling to annotation */
808
804
  scrollContainerRef?: React.RefObject<HTMLDivElement | null>;
809
- /** Optional: samples per pixel for scroll position calculation */
810
- samplesPerPixel?: number;
811
- /** Optional: sample rate for scroll position calculation */
812
- sampleRate?: number;
813
805
  /** Optional: callback to start playback at a time with optional duration */
814
806
  onPlay?: (startTime: number, duration?: number) => void;
815
807
  }
@@ -844,7 +836,7 @@ interface UseAnnotationKeyboardControlsOptions {
844
836
  * });
845
837
  * ```
846
838
  */
847
- declare function useAnnotationKeyboardControls({ annotations, activeAnnotationId, onAnnotationsChange, onActiveAnnotationChange, duration, linkEndpoints, continuousPlay, enabled, scrollContainerRef, samplesPerPixel, sampleRate, onPlay, }: UseAnnotationKeyboardControlsOptions): {
839
+ declare function useAnnotationKeyboardControls({ annotations, activeAnnotationId, onAnnotationsChange, onActiveAnnotationChange, duration, linkEndpoints, continuousPlay, enabled, scrollContainerRef, onPlay, }: UseAnnotationKeyboardControlsOptions): {
848
840
  moveStartBoundary: (delta: number) => void;
849
841
  moveEndBoundary: (delta: number) => void;
850
842
  selectPrevious: () => void;
package/dist/index.d.ts CHANGED
@@ -505,7 +505,6 @@ interface UseClipDragHandlersOptions {
505
505
  tracks: ClipTrack[];
506
506
  onTracksChange: (tracks: ClipTrack[]) => void;
507
507
  samplesPerPixel: number;
508
- sampleRate: number;
509
508
  engineRef: React__default.RefObject<PlaylistEngine | null>;
510
509
  /** Ref toggled during boundary trim drags. When true, the provider's loadAudio
511
510
  * skips engine rebuilds so engine keeps original clip positions. On drag end,
@@ -536,7 +535,6 @@ interface UseClipDragHandlersOptions {
536
535
  * tracks,
537
536
  * onTracksChange: setTracks,
538
537
  * samplesPerPixel,
539
- * sampleRate,
540
538
  * engineRef: playoutRef,
541
539
  * isDraggingRef,
542
540
  * });
@@ -553,7 +551,7 @@ interface UseClipDragHandlersOptions {
553
551
  * );
554
552
  * ```
555
553
  */
556
- declare function useClipDragHandlers({ tracks, onTracksChange, samplesPerPixel, sampleRate, engineRef, isDraggingRef, snapSamplePosition, }: UseClipDragHandlersOptions): {
554
+ declare function useClipDragHandlers({ tracks, onTracksChange, samplesPerPixel, engineRef, isDraggingRef, snapSamplePosition, }: UseClipDragHandlersOptions): {
557
555
  onDragStart: (event: Parameters<DragStartEvent>[0]) => void;
558
556
  onDragMove: (event: Parameters<DragMoveEvent>[0]) => void;
559
557
  onDragEnd: (event: Parameters<DragEndEvent>[0]) => void;
@@ -563,7 +561,8 @@ interface UseAnnotationDragHandlersOptions {
563
561
  annotations: AnnotationData[];
564
562
  onAnnotationsChange: (annotations: AnnotationData[]) => void;
565
563
  samplesPerPixel: number;
566
- sampleRate: number;
564
+ /** Sample rate for pixel-to-time conversion. Defaults to AudioContext.sampleRate. */
565
+ sampleRate?: number;
567
566
  duration: number;
568
567
  linkEndpoints: boolean;
569
568
  }
@@ -579,7 +578,6 @@ interface UseAnnotationDragHandlersOptions {
579
578
  * annotations,
580
579
  * onAnnotationsChange: setAnnotations,
581
580
  * samplesPerPixel,
582
- * sampleRate,
583
581
  * duration,
584
582
  * linkEndpoints,
585
583
  * });
@@ -654,7 +652,6 @@ declare function useDragSensors(options?: DragSensorOptions): (typeof PointerSen
654
652
 
655
653
  interface UseClipSplittingOptions {
656
654
  tracks: ClipTrack[];
657
- sampleRate: number;
658
655
  samplesPerPixel: number;
659
656
  engineRef: React__default.RefObject<PlaylistEngine | null>;
660
657
  }
@@ -676,7 +673,6 @@ interface UseClipSplittingResult {
676
673
  * ```tsx
677
674
  * const { splitClipAtPlayhead } = useClipSplitting({
678
675
  * tracks,
679
- * sampleRate,
680
676
  * samplesPerPixel,
681
677
  * engineRef: playoutRef,
682
678
  * });
@@ -806,10 +802,6 @@ interface UseAnnotationKeyboardControlsOptions {
806
802
  enabled?: boolean;
807
803
  /** Optional: scroll container ref for auto-scrolling to annotation */
808
804
  scrollContainerRef?: React.RefObject<HTMLDivElement | null>;
809
- /** Optional: samples per pixel for scroll position calculation */
810
- samplesPerPixel?: number;
811
- /** Optional: sample rate for scroll position calculation */
812
- sampleRate?: number;
813
805
  /** Optional: callback to start playback at a time with optional duration */
814
806
  onPlay?: (startTime: number, duration?: number) => void;
815
807
  }
@@ -844,7 +836,7 @@ interface UseAnnotationKeyboardControlsOptions {
844
836
  * });
845
837
  * ```
846
838
  */
847
- declare function useAnnotationKeyboardControls({ annotations, activeAnnotationId, onAnnotationsChange, onActiveAnnotationChange, duration, linkEndpoints, continuousPlay, enabled, scrollContainerRef, samplesPerPixel, sampleRate, onPlay, }: UseAnnotationKeyboardControlsOptions): {
839
+ declare function useAnnotationKeyboardControls({ annotations, activeAnnotationId, onAnnotationsChange, onActiveAnnotationChange, duration, linkEndpoints, continuousPlay, enabled, scrollContainerRef, onPlay, }: UseAnnotationKeyboardControlsOptions): {
848
840
  moveStartBoundary: (delta: number) => void;
849
841
  moveEndBoundary: (delta: number) => void;
850
842
  selectPrevious: () => void;
package/dist/index.js CHANGED
@@ -163,7 +163,7 @@ var Tone2 = __toESM(require("tone"));
163
163
  // src/WaveformPlaylistContext.tsx
164
164
  var import_react23 = require("react");
165
165
  var import_styled_components = require("styled-components");
166
- var import_playout4 = require("@waveform-playlist/playout");
166
+ var import_playout5 = require("@waveform-playlist/playout");
167
167
  var import_engine3 = require("@waveform-playlist/engine");
168
168
  var import_ui_components2 = require("@waveform-playlist/ui-components");
169
169
  var import_tone4 = require("tone");
@@ -807,11 +807,11 @@ function useClipDragHandlers({
807
807
  tracks,
808
808
  onTracksChange,
809
809
  samplesPerPixel,
810
- sampleRate,
811
810
  engineRef,
812
811
  isDraggingRef,
813
812
  snapSamplePosition
814
813
  }) {
814
+ const { sampleRate } = usePlaylistData();
815
815
  const snapSamplePositionRef = import_react9.default.useRef(snapSamplePosition);
816
816
  snapSamplePositionRef.current = snapSamplePosition;
817
817
  const originalClipStateRef = import_react9.default.useRef(null);
@@ -970,12 +970,13 @@ function useClipDragHandlers({
970
970
 
971
971
  // src/hooks/useAnnotationDragHandlers.ts
972
972
  var import_react10 = __toESM(require("react"));
973
+ var import_playout = require("@waveform-playlist/playout");
973
974
  var LINK_THRESHOLD = 0.01;
974
975
  function useAnnotationDragHandlers({
975
976
  annotations,
976
977
  onAnnotationsChange,
977
978
  samplesPerPixel,
978
- sampleRate,
979
+ sampleRate = (0, import_playout.getGlobalAudioContext)().sampleRate,
979
980
  duration,
980
981
  linkEndpoints
981
982
  }) {
@@ -1174,7 +1175,8 @@ function useDragSensors(options = {}) {
1174
1175
  var import_react12 = require("react");
1175
1176
  var import_engine2 = require("@waveform-playlist/engine");
1176
1177
  var useClipSplitting = (options) => {
1177
- const { tracks, sampleRate, engineRef } = options;
1178
+ const { tracks, engineRef } = options;
1179
+ const { sampleRate } = usePlaylistData();
1178
1180
  const { currentTimeRef } = usePlaybackAnimation();
1179
1181
  const { selectedTrackId } = usePlaylistState();
1180
1182
  const splitClipAt = (0, import_react12.useCallback)(
@@ -1199,7 +1201,7 @@ var useClipSplitting = (options) => {
1199
1201
  engine.splitClip(track.id, clip.id, snappedSplitSample);
1200
1202
  return true;
1201
1203
  },
1202
- [tracks, options, sampleRate, engineRef]
1204
+ [tracks, options, engineRef, sampleRate]
1203
1205
  );
1204
1206
  const splitClipAtPlayhead = (0, import_react12.useCallback)(() => {
1205
1207
  var _a;
@@ -1357,10 +1359,9 @@ function useAnnotationKeyboardControls({
1357
1359
  continuousPlay = false,
1358
1360
  enabled = true,
1359
1361
  scrollContainerRef,
1360
- samplesPerPixel,
1361
- sampleRate,
1362
1362
  onPlay
1363
1363
  }) {
1364
+ const { samplesPerPixel, sampleRate } = usePlaylistData();
1364
1365
  const activeIndex = (0, import_react15.useMemo)(() => {
1365
1366
  if (!activeAnnotationId) return -1;
1366
1367
  return annotations.findIndex((a) => a.id === activeAnnotationId);
@@ -2713,7 +2714,7 @@ function useTrackDynamicEffects() {
2713
2714
 
2714
2715
  // src/hooks/useExportWav.ts
2715
2716
  var import_react18 = require("react");
2716
- var import_playout = require("@waveform-playlist/playout");
2717
+ var import_playout2 = require("@waveform-playlist/playout");
2717
2718
 
2718
2719
  // src/utils/wavEncoder.ts
2719
2720
  function encodeWav(audioBuffer, options = {}) {
@@ -2812,7 +2813,7 @@ function useExportWav() {
2812
2813
  if (mode === "individual" && (trackIndex === void 0 || trackIndex < 0 || trackIndex >= tracks.length)) {
2813
2814
  throw new Error("Invalid track index for individual export");
2814
2815
  }
2815
- const sampleRate = (0, import_playout.getGlobalAudioContext)().sampleRate;
2816
+ const sampleRate = (0, import_playout2.getGlobalAudioContext)().sampleRate;
2816
2817
  let totalDurationSamples = 0;
2817
2818
  for (const track of tracks) {
2818
2819
  for (const clip of track.clips) {
@@ -2940,7 +2941,7 @@ function renderWithToneEffects(tracksToRender, _trackStates, hasSolo, duration,
2940
2941
  if (fadeIn) {
2941
2942
  const fadeInStart = startTime;
2942
2943
  const fadeInEnd = startTime + fadeIn.duration;
2943
- const audioParam = (0, import_playout.getUnderlyingAudioParam)(fadeGain.gain);
2944
+ const audioParam = (0, import_playout2.getUnderlyingAudioParam)(fadeGain.gain);
2944
2945
  if (audioParam) {
2945
2946
  audioParam.setValueAtTime(0, fadeInStart);
2946
2947
  audioParam.linearRampToValueAtTime(clipGain, fadeInEnd);
@@ -2949,7 +2950,7 @@ function renderWithToneEffects(tracksToRender, _trackStates, hasSolo, duration,
2949
2950
  if (fadeOut) {
2950
2951
  const fadeOutStart = startTime + clipDuration - fadeOut.duration;
2951
2952
  const fadeOutEnd = startTime + clipDuration;
2952
- const audioParam = (0, import_playout.getUnderlyingAudioParam)(fadeGain.gain);
2953
+ const audioParam = (0, import_playout2.getUnderlyingAudioParam)(fadeGain.gain);
2953
2954
  if (audioParam) {
2954
2955
  audioParam.setValueAtTime(clipGain, fadeOutStart);
2955
2956
  audioParam.linearRampToValueAtTime(0, fadeOutEnd);
@@ -3493,7 +3494,7 @@ function useWaveformDataCache(tracks, baseScale) {
3493
3494
  // src/hooks/useDynamicTracks.ts
3494
3495
  var import_react21 = require("react");
3495
3496
  var import_core2 = require("@waveform-playlist/core");
3496
- var import_playout2 = require("@waveform-playlist/playout");
3497
+ var import_playout3 = require("@waveform-playlist/playout");
3497
3498
  function getSourceName(source) {
3498
3499
  var _a, _b, _c, _d, _e;
3499
3500
  if (source instanceof File) {
@@ -3544,7 +3545,7 @@ function useDynamicTracks() {
3544
3545
  }, []);
3545
3546
  const addTracks = (0, import_react21.useCallback)((sources) => {
3546
3547
  if (sources.length === 0) return;
3547
- const audioContext = (0, import_playout2.getGlobalAudioContext)();
3548
+ const audioContext = (0, import_playout3.getGlobalAudioContext)();
3548
3549
  const placeholders = sources.map((source) => ({
3549
3550
  track: (0, import_core2.createTrack)({ name: `${getSourceName(source)} (loading...)`, clips: [] }),
3550
3551
  source
@@ -3615,7 +3616,7 @@ function useDynamicTracks() {
3615
3616
 
3616
3617
  // src/hooks/useOutputMeter.ts
3617
3618
  var import_react22 = require("react");
3618
- var import_playout3 = require("@waveform-playlist/playout");
3619
+ var import_playout4 = require("@waveform-playlist/playout");
3619
3620
  var import_core3 = require("@waveform-playlist/core");
3620
3621
  var import_worklets = require("@waveform-playlist/worklets");
3621
3622
  var PEAK_DECAY = 0.98;
@@ -3643,7 +3644,7 @@ function useOutputMeter(options = {}) {
3643
3644
  (0, import_react22.useEffect)(() => {
3644
3645
  let isMounted = true;
3645
3646
  const setup = () => __async(null, null, function* () {
3646
- const context = (0, import_playout3.getGlobalContext)();
3647
+ const context = (0, import_playout4.getGlobalContext)();
3647
3648
  const rawCtx = context.rawContext;
3648
3649
  yield rawCtx.audioWorklet.addModule(import_worklets.meterProcessorUrl);
3649
3650
  if (!isMounted) return;
@@ -3692,7 +3693,7 @@ function useOutputMeter(options = {}) {
3692
3693
  isMounted = false;
3693
3694
  if (workletNodeRef.current) {
3694
3695
  try {
3695
- const context = (0, import_playout3.getGlobalContext)();
3696
+ const context = (0, import_playout4.getGlobalContext)();
3696
3697
  context.destination.chain();
3697
3698
  } catch (err) {
3698
3699
  console.warn("[waveform-playlist] Failed to restore destination chain:", String(err));
@@ -3802,7 +3803,7 @@ var WaveformPlaylistProvider = ({
3802
3803
  const prevTracksRef = (0, import_react23.useRef)([]);
3803
3804
  const samplesPerPixelRef = (0, import_react23.useRef)(initialSamplesPerPixel);
3804
3805
  const sampleRateRef = (0, import_react23.useRef)(
3805
- typeof AudioContext !== "undefined" ? (0, import_playout4.getGlobalAudioContext)().sampleRate : 48e3
3806
+ typeof AudioContext !== "undefined" ? (0, import_playout5.getGlobalAudioContext)().sampleRate : 48e3
3806
3807
  );
3807
3808
  const { timeFormat, setTimeFormat, formatTime: formatTime2 } = useTimeFormat();
3808
3809
  const zoom = useZoomControls({ engineRef, initialSamplesPerPixel });
@@ -4039,7 +4040,7 @@ var WaveformPlaylistProvider = ({
4039
4040
  lastTracksVersionRef.current = 0;
4040
4041
  engineTracksRef.current = null;
4041
4042
  audioInitializedRef.current = false;
4042
- const adapter = (0, import_playout4.createToneAdapter)({ effects, soundFontCache: soundFontCacheRef.current });
4043
+ const adapter = (0, import_playout5.createToneAdapter)({ effects, soundFontCache: soundFontCacheRef.current });
4043
4044
  const engine = new import_engine3.PlaylistEngine({
4044
4045
  adapter,
4045
4046
  samplesPerPixel: samplesPerPixelRef.current,
@@ -5436,7 +5437,7 @@ function useClipInteractionEnabled() {
5436
5437
  var import_react32 = require("react");
5437
5438
  var import_react_dom = require("react-dom");
5438
5439
  var import_styled_components6 = __toESM(require("styled-components"));
5439
- var import_playout5 = require("@waveform-playlist/playout");
5440
+ var import_playout6 = require("@waveform-playlist/playout");
5440
5441
  var import_ui_components9 = require("@waveform-playlist/ui-components");
5441
5442
 
5442
5443
  // src/components/AnimatedPlayhead.tsx
@@ -5739,7 +5740,7 @@ var CustomPlayhead = ({ renderPlayhead, color, samplesPerPixel, sampleRate }) =>
5739
5740
  samplesPerPixel,
5740
5741
  sampleRate,
5741
5742
  controlsOffset: 0,
5742
- getAudioContextTime: () => (0, import_playout5.getGlobalContext)().rawContext.currentTime,
5743
+ getAudioContextTime: () => (0, import_playout6.getGlobalContext)().rawContext.currentTime,
5743
5744
  getPlaybackTime
5744
5745
  });
5745
5746
  };
@@ -6726,7 +6727,6 @@ var MediaElementPlaylist = ({
6726
6727
  annotations,
6727
6728
  onAnnotationsChange: handleAnnotationUpdate,
6728
6729
  samplesPerPixel,
6729
- sampleRate,
6730
6730
  duration,
6731
6731
  linkEndpoints: linkEndpointsProp
6732
6732
  });
@@ -7032,7 +7032,7 @@ var KeyboardShortcuts = ({
7032
7032
  annotations = false,
7033
7033
  additionalShortcuts = []
7034
7034
  }) => {
7035
- const { tracks, samplesPerPixel, sampleRate, playoutRef, duration } = usePlaylistData();
7035
+ const { tracks, samplesPerPixel, playoutRef, duration } = usePlaylistData();
7036
7036
  const {
7037
7037
  annotations: annotationList,
7038
7038
  linkEndpoints,
@@ -7042,7 +7042,6 @@ var KeyboardShortcuts = ({
7042
7042
  const { setAnnotations, setActiveAnnotationId, scrollContainerRef, play } = usePlaylistControls();
7043
7043
  const { splitClipAtPlayhead } = useClipSplitting({
7044
7044
  tracks,
7045
- sampleRate,
7046
7045
  samplesPerPixel,
7047
7046
  engineRef: playoutRef
7048
7047
  });
@@ -7070,8 +7069,6 @@ var KeyboardShortcuts = ({
7070
7069
  linkEndpoints,
7071
7070
  continuousPlay,
7072
7071
  scrollContainerRef,
7073
- samplesPerPixel,
7074
- sampleRate,
7075
7072
  onPlay: play,
7076
7073
  enabled: annotations && annotationList.length > 0
7077
7074
  });
@@ -7196,7 +7193,6 @@ var ClipInteractionProvider = ({
7196
7193
  tracks,
7197
7194
  onTracksChange: onTracksChange != null ? onTracksChange : NOOP_TRACKS_CHANGE,
7198
7195
  samplesPerPixel,
7199
- sampleRate,
7200
7196
  engineRef: playoutRef,
7201
7197
  isDraggingRef,
7202
7198
  snapSamplePosition