@waveform-playlist/browser 11.2.0 → 11.3.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 +15 -2
- package/dist/index.d.ts +15 -2
- package/dist/index.js +70 -86
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +71 -87
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -7
package/dist/index.mjs
CHANGED
|
@@ -3759,6 +3759,7 @@ var WaveformPlaylistProvider = ({
|
|
|
3759
3759
|
const playbackEndTimeRef = useRef15(null);
|
|
3760
3760
|
const scrollContainerRef = useRef15(null);
|
|
3761
3761
|
const isAutomaticScrollRef = useRef15(false);
|
|
3762
|
+
const frameCallbacksRef = useRef15(/* @__PURE__ */ new Map());
|
|
3762
3763
|
const continuousPlayRef = useRef15((_d = annotationList == null ? void 0 : annotationList.isContinuousPlay) != null ? _d : false);
|
|
3763
3764
|
const activeAnnotationIdRef = useRef15(null);
|
|
3764
3765
|
const engineTracksRef = useRef15(null);
|
|
@@ -4219,10 +4220,30 @@ var WaveformPlaylistProvider = ({
|
|
|
4219
4220
|
const elapsed = getContext2().currentTime - ((_a2 = playbackStartTimeRef.current) != null ? _a2 : 0);
|
|
4220
4221
|
return ((_b2 = audioStartPositionRef.current) != null ? _b2 : 0) + elapsed;
|
|
4221
4222
|
}, []);
|
|
4223
|
+
const registerFrameCallback = useCallback19((id, cb) => {
|
|
4224
|
+
frameCallbacksRef.current.set(id, cb);
|
|
4225
|
+
}, []);
|
|
4226
|
+
const unregisterFrameCallback = useCallback19((id) => {
|
|
4227
|
+
frameCallbacksRef.current.delete(id);
|
|
4228
|
+
}, []);
|
|
4222
4229
|
const startAnimationLoop = useCallback19(() => {
|
|
4230
|
+
const audioCtx = getGlobalAudioContext4();
|
|
4223
4231
|
const updateTime = () => {
|
|
4224
4232
|
const time = getPlaybackTime();
|
|
4225
4233
|
currentTimeRef.current = time;
|
|
4234
|
+
const latency = "outputLatency" in audioCtx ? audioCtx.outputLatency : 0;
|
|
4235
|
+
const visualTime = Math.max(0, time - latency);
|
|
4236
|
+
const sr = sampleRateRef.current;
|
|
4237
|
+
const spp = samplesPerPixelRef.current;
|
|
4238
|
+
const frameData = {
|
|
4239
|
+
time,
|
|
4240
|
+
visualTime,
|
|
4241
|
+
sampleRate: sr,
|
|
4242
|
+
samplesPerPixel: spp
|
|
4243
|
+
};
|
|
4244
|
+
for (const cb of frameCallbacksRef.current.values()) {
|
|
4245
|
+
cb(frameData);
|
|
4246
|
+
}
|
|
4226
4247
|
const currentAnnotations = annotationsRef.current;
|
|
4227
4248
|
if (currentAnnotations.length > 0) {
|
|
4228
4249
|
const currentAnnotation = currentAnnotations.find(
|
|
@@ -4257,10 +4278,9 @@ var WaveformPlaylistProvider = ({
|
|
|
4257
4278
|
}
|
|
4258
4279
|
if (isAutomaticScrollRef.current && scrollContainerRef.current && duration > 0) {
|
|
4259
4280
|
const container = scrollContainerRef.current;
|
|
4260
|
-
const
|
|
4261
|
-
const pixelPosition = time * sr / samplesPerPixelRef.current;
|
|
4281
|
+
const pixelPosition = visualTime * sr / spp;
|
|
4262
4282
|
const containerWidth = container.clientWidth;
|
|
4263
|
-
const targetScrollLeft = Math.max(0, pixelPosition - containerWidth / 2);
|
|
4283
|
+
const targetScrollLeft = Math.round(Math.max(0, pixelPosition - containerWidth / 2));
|
|
4264
4284
|
container.scrollLeft = targetScrollLeft;
|
|
4265
4285
|
}
|
|
4266
4286
|
if (playbackEndTimeRef.current !== null && time >= playbackEndTimeRef.current) {
|
|
@@ -4496,7 +4516,9 @@ var WaveformPlaylistProvider = ({
|
|
|
4496
4516
|
currentTimeRef,
|
|
4497
4517
|
playbackStartTimeRef,
|
|
4498
4518
|
audioStartPositionRef,
|
|
4499
|
-
getPlaybackTime
|
|
4519
|
+
getPlaybackTime,
|
|
4520
|
+
registerFrameCallback,
|
|
4521
|
+
unregisterFrameCallback
|
|
4500
4522
|
}),
|
|
4501
4523
|
[
|
|
4502
4524
|
isPlaying,
|
|
@@ -4504,7 +4526,9 @@ var WaveformPlaylistProvider = ({
|
|
|
4504
4526
|
currentTimeRef,
|
|
4505
4527
|
playbackStartTimeRef,
|
|
4506
4528
|
audioStartPositionRef,
|
|
4507
|
-
getPlaybackTime
|
|
4529
|
+
getPlaybackTime,
|
|
4530
|
+
registerFrameCallback,
|
|
4531
|
+
unregisterFrameCallback
|
|
4508
4532
|
]
|
|
4509
4533
|
);
|
|
4510
4534
|
const stateValue = useMemo4(
|
|
@@ -5299,32 +5323,19 @@ var PositionDisplay = styled.span`
|
|
|
5299
5323
|
var AudioPosition = ({ className }) => {
|
|
5300
5324
|
var _a;
|
|
5301
5325
|
const timeRef = useRef17(null);
|
|
5302
|
-
const
|
|
5303
|
-
const { isPlaying, currentTimeRef, getPlaybackTime } = usePlaybackAnimation();
|
|
5326
|
+
const { isPlaying, currentTimeRef, registerFrameCallback, unregisterFrameCallback } = usePlaybackAnimation();
|
|
5304
5327
|
const { timeFormat: format } = usePlaylistData();
|
|
5305
5328
|
useEffect12(() => {
|
|
5306
|
-
const
|
|
5307
|
-
var _a2;
|
|
5308
|
-
if (timeRef.current) {
|
|
5309
|
-
const time = isPlaying ? getPlaybackTime() : (_a2 = currentTimeRef.current) != null ? _a2 : 0;
|
|
5310
|
-
timeRef.current.textContent = formatTime(time, format);
|
|
5311
|
-
}
|
|
5312
|
-
if (isPlaying) {
|
|
5313
|
-
animationFrameRef.current = requestAnimationFrame(updateTime);
|
|
5314
|
-
}
|
|
5315
|
-
};
|
|
5329
|
+
const id = "audio-position";
|
|
5316
5330
|
if (isPlaying) {
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
|
|
5331
|
+
registerFrameCallback(id, ({ time }) => {
|
|
5332
|
+
if (timeRef.current) {
|
|
5333
|
+
timeRef.current.textContent = formatTime(time, format);
|
|
5334
|
+
}
|
|
5335
|
+
});
|
|
5320
5336
|
}
|
|
5321
|
-
return () =>
|
|
5322
|
-
|
|
5323
|
-
cancelAnimationFrame(animationFrameRef.current);
|
|
5324
|
-
animationFrameRef.current = null;
|
|
5325
|
-
}
|
|
5326
|
-
};
|
|
5327
|
-
}, [isPlaying, format, currentTimeRef, getPlaybackTime]);
|
|
5337
|
+
return () => unregisterFrameCallback(id);
|
|
5338
|
+
}, [isPlaying, format, registerFrameCallback, unregisterFrameCallback]);
|
|
5328
5339
|
useEffect12(() => {
|
|
5329
5340
|
var _a2;
|
|
5330
5341
|
if (!isPlaying && timeRef.current) {
|
|
@@ -5507,33 +5518,20 @@ var PlayheadLine = styled2.div.attrs((props) => ({
|
|
|
5507
5518
|
`;
|
|
5508
5519
|
var AnimatedPlayhead = ({ color = "#ff0000" }) => {
|
|
5509
5520
|
const playheadRef = useRef18(null);
|
|
5510
|
-
const
|
|
5511
|
-
const { isPlaying, currentTimeRef, getPlaybackTime } = usePlaybackAnimation();
|
|
5521
|
+
const { isPlaying, currentTimeRef, registerFrameCallback, unregisterFrameCallback } = usePlaybackAnimation();
|
|
5512
5522
|
const { samplesPerPixel, sampleRate, progressBarWidth } = usePlaylistData();
|
|
5513
5523
|
useEffect13(() => {
|
|
5514
|
-
const
|
|
5515
|
-
var _a;
|
|
5516
|
-
if (playheadRef.current) {
|
|
5517
|
-
const time = isPlaying ? getPlaybackTime() : (_a = currentTimeRef.current) != null ? _a : 0;
|
|
5518
|
-
const position = time * sampleRate / samplesPerPixel;
|
|
5519
|
-
playheadRef.current.style.transform = `translate3d(${position}px, 0, 0)`;
|
|
5520
|
-
}
|
|
5521
|
-
if (isPlaying) {
|
|
5522
|
-
animationFrameRef.current = requestAnimationFrame(updatePosition);
|
|
5523
|
-
}
|
|
5524
|
-
};
|
|
5524
|
+
const id = "playhead";
|
|
5525
5525
|
if (isPlaying) {
|
|
5526
|
-
|
|
5527
|
-
|
|
5528
|
-
|
|
5526
|
+
registerFrameCallback(id, ({ visualTime, sampleRate: sr, samplesPerPixel: spp }) => {
|
|
5527
|
+
if (playheadRef.current) {
|
|
5528
|
+
const px = visualTime * sr / spp;
|
|
5529
|
+
playheadRef.current.style.transform = `translate3d(${px}px, 0, 0)`;
|
|
5530
|
+
}
|
|
5531
|
+
});
|
|
5529
5532
|
}
|
|
5530
|
-
return () =>
|
|
5531
|
-
|
|
5532
|
-
cancelAnimationFrame(animationFrameRef.current);
|
|
5533
|
-
animationFrameRef.current = null;
|
|
5534
|
-
}
|
|
5535
|
-
};
|
|
5536
|
-
}, [isPlaying, sampleRate, samplesPerPixel, currentTimeRef, getPlaybackTime]);
|
|
5533
|
+
return () => unregisterFrameCallback(id);
|
|
5534
|
+
}, [isPlaying, registerFrameCallback, unregisterFrameCallback]);
|
|
5537
5535
|
useEffect13(() => {
|
|
5538
5536
|
var _a;
|
|
5539
5537
|
if (!isPlaying && playheadRef.current) {
|
|
@@ -5546,7 +5544,7 @@ var AnimatedPlayhead = ({ color = "#ff0000" }) => {
|
|
|
5546
5544
|
};
|
|
5547
5545
|
|
|
5548
5546
|
// src/components/ChannelWithProgress.tsx
|
|
5549
|
-
import { useRef as useRef19, useEffect as useEffect14 } from "react";
|
|
5547
|
+
import { useId, useRef as useRef19, useEffect as useEffect14 } from "react";
|
|
5550
5548
|
import styled3 from "styled-components";
|
|
5551
5549
|
import {
|
|
5552
5550
|
clipPixelWidth as computeClipPixelWidth
|
|
@@ -5612,10 +5610,10 @@ var ChannelWithProgress = (_a) => {
|
|
|
5612
5610
|
"clipOffsetSeconds"
|
|
5613
5611
|
]);
|
|
5614
5612
|
const progressRef = useRef19(null);
|
|
5615
|
-
const
|
|
5613
|
+
const callbackId = useId();
|
|
5616
5614
|
const theme = useTheme();
|
|
5617
5615
|
const { waveHeight } = usePlaylistInfo();
|
|
5618
|
-
const { isPlaying, currentTimeRef,
|
|
5616
|
+
const { isPlaying, currentTimeRef, registerFrameCallback, unregisterFrameCallback } = usePlaybackAnimation();
|
|
5619
5617
|
const { samplesPerPixel, sampleRate } = usePlaylistData();
|
|
5620
5618
|
const progressColor = (theme == null ? void 0 : theme.waveProgressColor) || "rgba(0, 0, 0, 0.1)";
|
|
5621
5619
|
const clipPixelWidth = computeClipPixelWidth(
|
|
@@ -5624,46 +5622,32 @@ var ChannelWithProgress = (_a) => {
|
|
|
5624
5622
|
samplesPerPixel
|
|
5625
5623
|
);
|
|
5626
5624
|
useEffect14(() => {
|
|
5627
|
-
const updateProgress = () => {
|
|
5628
|
-
var _a2;
|
|
5629
|
-
if (progressRef.current) {
|
|
5630
|
-
const currentTime = isPlaying ? getPlaybackTime() : (_a2 = currentTimeRef.current) != null ? _a2 : 0;
|
|
5631
|
-
const currentSample = currentTime * sampleRate;
|
|
5632
|
-
const clipEndSample = clipStartSample + clipDurationSamples;
|
|
5633
|
-
let ratio = 0;
|
|
5634
|
-
if (currentSample <= clipStartSample) {
|
|
5635
|
-
ratio = 0;
|
|
5636
|
-
} else if (currentSample >= clipEndSample) {
|
|
5637
|
-
ratio = 1;
|
|
5638
|
-
} else {
|
|
5639
|
-
const playedSamples = currentSample - clipStartSample;
|
|
5640
|
-
ratio = playedSamples / clipDurationSamples;
|
|
5641
|
-
}
|
|
5642
|
-
progressRef.current.style.transform = `scaleX(${ratio})`;
|
|
5643
|
-
}
|
|
5644
|
-
if (isPlaying) {
|
|
5645
|
-
animationFrameRef.current = requestAnimationFrame(updateProgress);
|
|
5646
|
-
}
|
|
5647
|
-
};
|
|
5648
5625
|
if (isPlaying) {
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
|
|
5626
|
+
registerFrameCallback(callbackId, ({ visualTime, sampleRate: sr }) => {
|
|
5627
|
+
if (progressRef.current) {
|
|
5628
|
+
const currentSample = visualTime * sr;
|
|
5629
|
+
const clipEndSample = clipStartSample + clipDurationSamples;
|
|
5630
|
+
let ratio = 0;
|
|
5631
|
+
if (currentSample <= clipStartSample) {
|
|
5632
|
+
ratio = 0;
|
|
5633
|
+
} else if (currentSample >= clipEndSample) {
|
|
5634
|
+
ratio = 1;
|
|
5635
|
+
} else {
|
|
5636
|
+
const playedSamples = currentSample - clipStartSample;
|
|
5637
|
+
ratio = playedSamples / clipDurationSamples;
|
|
5638
|
+
}
|
|
5639
|
+
progressRef.current.style.transform = `scaleX(${ratio})`;
|
|
5640
|
+
}
|
|
5641
|
+
});
|
|
5652
5642
|
}
|
|
5653
|
-
return () =>
|
|
5654
|
-
if (animationFrameRef.current) {
|
|
5655
|
-
cancelAnimationFrame(animationFrameRef.current);
|
|
5656
|
-
animationFrameRef.current = null;
|
|
5657
|
-
}
|
|
5658
|
-
};
|
|
5643
|
+
return () => unregisterFrameCallback(callbackId);
|
|
5659
5644
|
}, [
|
|
5660
5645
|
isPlaying,
|
|
5661
|
-
sampleRate,
|
|
5662
5646
|
clipStartSample,
|
|
5663
5647
|
clipDurationSamples,
|
|
5664
|
-
|
|
5665
|
-
|
|
5666
|
-
|
|
5648
|
+
callbackId,
|
|
5649
|
+
registerFrameCallback,
|
|
5650
|
+
unregisterFrameCallback
|
|
5667
5651
|
]);
|
|
5668
5652
|
useEffect14(() => {
|
|
5669
5653
|
var _a2;
|