fix last waveform segment overflowing

fixes #2798
pull/2806/head
Mikael Finstad 4 months ago
parent 260314db55
commit 2603142fbc
No known key found for this signature in database
GPG Key ID: 25AB36E3E81CBC26

@ -1,9 +1,11 @@
import type { CSSProperties, MouseEventHandler, WheelEventHandler } from 'react';
import { memo, useEffect, useState, useCallback, useRef, useMemo } from 'react';
import { FaExclamationCircle } from 'react-icons/fa';
import { ffmpegExtractWindow } from '../util/constants';
import type { WaveformSlice } from '../types';
import Spinner from './Spinner';
import isDev from '../isDev';
function BigWaveform({ waveforms, relevantTime, playing, fileDurationNonZero, zoom, seekRel, darkMode }: {
@ -108,18 +110,18 @@ function BigWaveform({ waveforms, relevantTime, playing, fileDurationNonZero, zo
width: widthPercent,
left: leftPercent,
borderLeft: waveform.from === 0 ? '1px solid var(--gray-11)' : undefined,
borderRight: waveform.to >= fileDurationNonZero ? '1px solid var(--gray-11)' : undefined,
borderRight: waveform.to >= fileDurationNonZero || isDev ? '1px solid var(--gray-11)' : undefined,
filter: darkMode ? undefined : 'invert(1)',
};
if (waveform.url == null) {
if (waveform.url == null || waveform.failed) {
return (
<div
key={`${waveform.from}-${waveform.to}`}
draggable={false}
style={{ ...style, display: 'flex', alignItems: 'center', justifyContent: 'center' }}
>
<Spinner />
{waveform.failed ? <FaExclamationCircle color="var(--red-11)" /> : <Spinner />}
</div>
);
}

@ -35,7 +35,6 @@ export default ({ filePath, relevantTime, fileDuration, waveformEnabled, audioSt
}, [filePath, audioStream, setWaveforms]);
const waveformStartTime = Math.floor(relevantTime / ffmpegExtractWindow) * ffmpegExtractWindow;
const safeExtractDuration = fileDuration != null ? Math.min(waveformStartTime + ffmpegExtractWindow, fileDuration) - waveformStartTime : undefined;
const waveformStartTimeRef = useRef(waveformStartTime);
@ -47,7 +46,7 @@ export default ({ filePath, relevantTime, fileDuration, waveformEnabled, audioSt
let aborted = false;
(async () => {
if (!filePath || safeExtractDuration == null || !audioStream || !waveformEnabled) {
if (!filePath || fileDuration == null || !audioStream || !waveformEnabled) {
return;
}
@ -59,8 +58,10 @@ export default ({ filePath, relevantTime, fileDuration, waveformEnabled, audioSt
];
for (const time of times) {
const safeExtractDuration = Math.min(time + ffmpegExtractWindow, fileDuration) - time;
const alreadyHaveWaveformAtTime = (waveformsRef.current ?? []).some((waveform) => waveform.from === time);
if (!alreadyHaveWaveformAtTime) {
if (!alreadyHaveWaveformAtTime && time < fileDuration) {
try {
const promise = renderWaveformPng({ filePath, start: time, duration: safeExtractDuration, color, streamIndex: audioStream.index, timeout: 10000 });
@ -87,18 +88,20 @@ export default ({ filePath, relevantTime, fileDuration, waveformEnabled, audioSt
return;
}
setWaveforms((currentWaveforms) => currentWaveforms.map((w) => {
if (w.from !== time) {
return w;
}
return {
setWaveforms((currentWaveforms) => currentWaveforms.map((w) => (
w.from === time ? {
...w,
url: URL.createObjectURL(safeCreateBlob(buffer, { type: 'image/png' })),
};
}));
} : w
)));
} catch (err) {
console.error('Failed to render waveform', err);
setWaveforms((currentWaveforms) => currentWaveforms.map((w) => (
w.from === time ? {
...w,
failed: true,
} : w
)));
}
}
}
@ -111,7 +114,7 @@ export default ({ filePath, relevantTime, fileDuration, waveformEnabled, audioSt
return () => {
aborted = true;
};
}, [audioStream, ffmpegExtractWindow, filePath, safeExtractDuration, waveformEnabled]);
}, [audioStream, ffmpegExtractWindow, fileDuration, filePath, waveformEnabled]);
const lastWaveformsRef = useRef<WaveformSlice[]>([]);
useEffect(() => {

@ -105,6 +105,7 @@ export interface WaveformSlice extends WaveformBase {
to: number,
duration: number,
url?: string, // undefined while rendering
failed?: true, // if failed to render
}
export interface OverviewWaveform extends WaveformBase {

@ -1,6 +1,7 @@
// anything more than this will probably cause the UI to become unusably slow
export const maxSegmentsAllowed = 2000;
/** Size of the window to extract keyframes/waveforms */
export const ffmpegExtractWindow = 60;
export const zoomMax = 2 ** 14;

Loading…
Cancel
Save