mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-09-24 23:05:49 +00:00
fix valid code rabbits comments
This commit is contained in:
@@ -110,47 +110,59 @@ export function useSourceAudioTrackSettings({
|
||||
[defaultSourceAudioTrackSettings, sourceAudioTrackSettingsByClip],
|
||||
);
|
||||
|
||||
const onSelectedClipSourceAudioTrackVolumeChange = useCallback(
|
||||
(id: string, volume: number) => {
|
||||
if (!selectedClipId) return;
|
||||
setSourceAudioTrackSettingsByClip((prev) => {
|
||||
const prevClip = prev[selectedClipId] ?? defaultSourceAudioTrackSettings;
|
||||
return {
|
||||
...prev,
|
||||
[selectedClipId]: {
|
||||
...prevClip,
|
||||
[id]: {
|
||||
volume: Number.isFinite(volume)
|
||||
? Math.max(0, Math.min(2, volume))
|
||||
: (prevClip[id]?.volume ?? 1),
|
||||
normalize: prevClip[id]?.normalize ?? false,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
},
|
||||
[defaultSourceAudioTrackSettings, selectedClipId],
|
||||
);
|
||||
const onSelectedClipSourceAudioTrackVolumeChange = useCallback(
|
||||
(id: string, volume: number) => {
|
||||
if (!selectedClipId) return;
|
||||
setSourceAudioTrackSettingsByClip((prev) => {
|
||||
const prevClip = prev[selectedClipId] ?? defaultSourceAudioTrackSettings;
|
||||
const nextVolume = Number.isFinite(volume)
|
||||
? Math.max(0, Math.min(2, volume))
|
||||
: (prevClip[id]?.volume ?? 1);
|
||||
const prevNormalize = prevClip[id]?.normalize ?? false;
|
||||
if (
|
||||
prevClip[id]?.volume === nextVolume &&
|
||||
prevClip[id]?.normalize === prevNormalize
|
||||
) {
|
||||
return prev;
|
||||
}
|
||||
return {
|
||||
...prev,
|
||||
[selectedClipId]: {
|
||||
...prevClip,
|
||||
[id]: {
|
||||
volume: nextVolume,
|
||||
normalize: prevNormalize,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
},
|
||||
[defaultSourceAudioTrackSettings, selectedClipId],
|
||||
);
|
||||
|
||||
const onSelectedClipSourceAudioTrackNormalizeChange = useCallback(
|
||||
(id: string, normalize: boolean) => {
|
||||
if (!selectedClipId) return;
|
||||
setSourceAudioTrackSettingsByClip((prev) => {
|
||||
const prevClip = prev[selectedClipId] ?? defaultSourceAudioTrackSettings;
|
||||
return {
|
||||
...prev,
|
||||
[selectedClipId]: {
|
||||
...prevClip,
|
||||
[id]: {
|
||||
volume: prevClip[id]?.volume ?? 1,
|
||||
normalize,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
},
|
||||
[defaultSourceAudioTrackSettings, selectedClipId],
|
||||
);
|
||||
const onSelectedClipSourceAudioTrackNormalizeChange = useCallback(
|
||||
(id: string, normalize: boolean) => {
|
||||
if (!selectedClipId) return;
|
||||
setSourceAudioTrackSettingsByClip((prev) => {
|
||||
const prevClip = prev[selectedClipId] ?? defaultSourceAudioTrackSettings;
|
||||
const prevVolume = prevClip[id]?.volume ?? 1;
|
||||
if (prevClip[id]?.normalize === normalize) {
|
||||
return prev;
|
||||
}
|
||||
return {
|
||||
...prev,
|
||||
[selectedClipId]: {
|
||||
...prevClip,
|
||||
[id]: {
|
||||
volume: prevVolume,
|
||||
normalize,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
},
|
||||
[defaultSourceAudioTrackSettings, selectedClipId],
|
||||
);
|
||||
|
||||
return {
|
||||
sourceAudioTrackMeta,
|
||||
|
||||
@@ -1,24 +1,33 @@
|
||||
self.onmessage = (e: MessageEvent) => {
|
||||
const { requestId, channels, samples } = e.data as {
|
||||
requestId: number;
|
||||
channels: Float32Array[];
|
||||
samples: number;
|
||||
};
|
||||
type WaveformWorkerRequest = {
|
||||
requestId: number;
|
||||
channels: Float32Array[];
|
||||
samples: number;
|
||||
};
|
||||
|
||||
interface WorkerContext {
|
||||
onmessage: (e: MessageEvent<WaveformWorkerRequest>) => void;
|
||||
postMessage: (message: any, transfer?: Transferable[]) => void;
|
||||
}
|
||||
|
||||
const workerScope = self as unknown as WorkerContext;
|
||||
|
||||
workerScope.onmessage = (e: MessageEvent<WaveformWorkerRequest>) => {
|
||||
const { requestId, channels, samples } = e.data;
|
||||
|
||||
if (!channels || channels.length === 0 || samples <= 0) {
|
||||
const empty = new Float32Array(0);
|
||||
(self as any).postMessage({ requestId, peaks: empty }, [empty.buffer]);
|
||||
workerScope.postMessage({ requestId, peaks: empty }, [empty.buffer]);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const firstChannel = channels[0];
|
||||
const step = Math.max(1, Math.floor(firstChannel.length / samples));
|
||||
const result = new Float32Array(samples);
|
||||
const total = firstChannel.length;
|
||||
|
||||
for (let i = 0; i < samples; i++) {
|
||||
const start = i * step;
|
||||
const end = Math.min(start + step, firstChannel.length);
|
||||
const start = Math.floor((i * total) / samples);
|
||||
const end = Math.floor(((i + 1) * total) / samples);
|
||||
let max = 0;
|
||||
for (let j = start; j < end; j++) {
|
||||
for (let c = 0; c < channels.length; c++) {
|
||||
@@ -29,9 +38,9 @@ self.onmessage = (e: MessageEvent) => {
|
||||
result[i] = max;
|
||||
}
|
||||
|
||||
(self as any).postMessage({ requestId, peaks: result }, [result.buffer]);
|
||||
workerScope.postMessage({ requestId, peaks: result }, [result.buffer]);
|
||||
} catch (err) {
|
||||
(self as any).postMessage({
|
||||
workerScope.postMessage({
|
||||
requestId,
|
||||
error: err instanceof Error ? err.message : "Unknown worker error",
|
||||
});
|
||||
|
||||
@@ -399,7 +399,7 @@ const TimelineCanvasRows = memo(function TimelineCanvasRows({
|
||||
onSelect={() => onSelectClip?.(item.id)}
|
||||
variant="audio"
|
||||
waveformPeaks={track.peaks}
|
||||
waveformSegmentSpan={liveSpanPreviewById?.[item.id] ?? item.span}
|
||||
waveformSegmentSpan={item.sourceSpan ?? item.span}
|
||||
waveformGain={Math.max(0, Math.min(2, settings.volume))}
|
||||
waveformNormalize={Boolean(settings.normalize)}
|
||||
muted={item.muted}
|
||||
|
||||
@@ -51,7 +51,10 @@ function AudioWaveformComponent({
|
||||
|
||||
const draw = () => {
|
||||
const now = performance.now();
|
||||
if (now - lastDrawAtRef.current < 33) return;
|
||||
if (now - lastDrawAtRef.current < 33) {
|
||||
rafId = requestAnimationFrame(draw);
|
||||
return;
|
||||
}
|
||||
lastDrawAtRef.current = now;
|
||||
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
@@ -146,7 +146,7 @@ export default function TimelineWrapper({
|
||||
? (event.activatorEvent as PointerEvent).clientX + (event.delta?.x ?? 0)
|
||||
: undefined;
|
||||
if (span) showTooltip(span, screenX);
|
||||
const moved = Math.abs(event.delta?.x ?? 0) > 0.01;
|
||||
const moved = Math.hypot(event.delta?.x ?? 0, event.delta?.y ?? 0) > 0.01;
|
||||
if (moved) {
|
||||
onLiveSpanPreviewChange?.(event.active.id as string, span ?? null);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ export interface TimelineRenderItem {
|
||||
id: string;
|
||||
rowId: string;
|
||||
span: Span;
|
||||
sourceSpan?: Span;
|
||||
label: string;
|
||||
audioPath?: string;
|
||||
audioGain?: number;
|
||||
|
||||
@@ -47,15 +47,22 @@ export function buildTimelineItems(params: {
|
||||
variant: "zoom",
|
||||
}));
|
||||
|
||||
const clips: TimelineRenderItem[] = clipRegions.map((region, index) => ({
|
||||
id: region.id,
|
||||
rowId: CLIP_ROW_ID,
|
||||
span: { start: region.startMs, end: region.endMs },
|
||||
label: `Clip ${index + 1}`,
|
||||
showSourceAudio: region.showSourceAudio,
|
||||
muted: Boolean(region.muted),
|
||||
variant: "clip",
|
||||
}));
|
||||
const clips: TimelineRenderItem[] = clipRegions.map((region, index) => {
|
||||
const displayDurationMs = Math.max(0, region.endMs - region.startMs);
|
||||
const speed = Number.isFinite(region.speed) && region.speed > 0 ? region.speed : 1;
|
||||
const sourceEndMs = region.startMs + displayDurationMs * speed;
|
||||
|
||||
return {
|
||||
id: region.id,
|
||||
rowId: CLIP_ROW_ID,
|
||||
span: { start: region.startMs, end: region.endMs },
|
||||
sourceSpan: { start: region.startMs, end: sourceEndMs },
|
||||
label: `Clip ${index + 1}`,
|
||||
showSourceAudio: region.showSourceAudio,
|
||||
muted: Boolean(region.muted),
|
||||
variant: "clip",
|
||||
};
|
||||
});
|
||||
|
||||
const annotations: TimelineRenderItem[] = annotationRegions.map((region) => ({
|
||||
id: region.id,
|
||||
|
||||
@@ -190,10 +190,10 @@
|
||||
"volumeTitle": "Audio",
|
||||
"volume": "Volume",
|
||||
"normalize": "Normaliser",
|
||||
"sourceTracksTitle": "Audio source du clip",
|
||||
"systemLabel": "Son Système",
|
||||
"sourceTracksTitle": "Source audio du clip",
|
||||
"systemLabel": "Son système",
|
||||
"micLabel": "Microphone",
|
||||
"mixedLabel": "Source",
|
||||
"deleteRegion": "Supprimer l'audio"
|
||||
"deleteRegion": "Supprimer la zone audio"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user