Skip to content

Commit c773581

Browse files
committed
docs(studio): keep the filmstrip files at or under main's comment share
The comment ratchet allows no file a higher share of comment lines than on main; the added explanations move to the PR description.
1 parent a3a89a4 commit c773581

5 files changed

Lines changed: 3 additions & 30 deletions

File tree

‎packages/studio/src/hooks/useMusicBeatAnalysis.ts‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ async function loadBeatAnalysis(
8080
): Promise<{ analysis: MusicAnalysis; times: number[]; strengths: number[] } | null> {
8181
let promise = analysisCache.get(musicSrc);
8282
if (!promise) {
83-
// Each long stage of the analysis waits for the timeline to rest, so it never lands mid-zoom.
8483
promise = analyzeMusicFromUrl(musicSrc, { pause: whenTimelineIdle });
8584
cacheAnalysis(musicSrc, promise);
8685
}

‎packages/studio/src/player/components/AudioWaveform.tsx‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,16 +158,13 @@ async function decodeWaveformPeaks(url: string, signal: AbortSignal): Promise<nu
158158
}
159159

160160
/** Bounded waveform subscriber; cache, cancellation and dedupe live in one scheduler. */
161-
// One screen each side and half a screen above and below; scrollMargin applies it inside the
162-
// timeline's own scroller too (TypeScript's DOM types lack it).
163161
const NEAR_SCREEN: IntersectionObserverInit & { scrollMargin: string } = {
164162
rootMargin: "50% 100%",
165163
scrollMargin: "50% 100%",
166164
};
167165
const nearScreenListeners = new Map<Element, (near: boolean) => void>();
168166
let nearScreen: IntersectionObserver | null = null;
169167

170-
/** Whether `element` is on or near the screen, kept current by one observer for all waveforms. */
171168
function useNearScreen(element: Element | null): boolean {
172169
const [near, setNear] = useState(() => typeof IntersectionObserver === "undefined");
173170
useEffect(() => {
@@ -247,7 +244,6 @@ export const AudioWaveform = memo(function AudioWaveform({
247244
span,
248245
);
249246
}, [fades, from, muted, peaks, to, trimEndFraction, trimStartFraction]);
250-
// A waveform off screen draws when it comes near, not at every zoom that resizes it.
251247
const near = useNearScreen(root);
252248
useEffect(() => {
253249
if (near) draw();

‎packages/studio/src/player/components/VideoThumbnail.tsx‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,6 @@ function selectThumbnailSnapshot(
8383

8484
type VideoThumbnailRequest = ReturnType<typeof createVideoThumbnailRequest>;
8585

86-
/**
87-
* The strip to show: the requested width once ready, else the strip already on screen, kept leased
88-
* while a zoom's new width decodes, else the poster.
89-
*/
9086
function useVideoThumbnailSnapshot(
9187
poster: VideoThumbnailRequest | null,
9288
rich: VideoThumbnailRequest | null,

‎packages/studio/src/player/components/thumbnailUtils.ts‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ export interface ThumbnailStripLayout {
1111
/** Quantize request identities so a pixel-by-pixel resize does not thrash the cache. */
1212
export function quantizeThumbnailFrameCount(frameCount: number): number {
1313
const safeCount = Math.max(1, Number.isFinite(frameCount) ? Math.ceil(frameCount) : 1);
14-
// Capped at a power of two too, so the top step still holds every frame of the one below it.
1514
const cap = 2 ** Math.floor(Math.log2(MAX_VISIBLE_THUMBNAIL_FRAMES));
1615
return Math.min(cap, 2 ** Math.ceil(Math.log2(safeCount)));
1716
}

‎packages/studio/src/player/lib/thumbnailVideoDecoder.ts‎

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,7 @@ export interface VideoThumbnailDecodeRequest {
99
fit?: "contain" | "cover";
1010
}
1111

12-
/**
13-
* The times a strip of `frameCount` slices shows: each slice's left edge, so a strip twice as long
14-
* holds every frame of this one, then the clip's last frame. A poster is the midpoint.
15-
*/
16-
// Inside the last frame: a time at the very end of a file can decode to nothing.
17-
const END_FRAME_LEAD_S = 0.001;
12+
const LAST_FRAME_INSET_S = 0.001;
1813

1914
export function videoThumbnailTimestamps(
2015
start: number,
@@ -29,10 +24,9 @@ export function videoThumbnailTimestamps(
2924
{ length: count },
3025
(_, index) => safeStart + (safeDuration * index) / count,
3126
);
32-
return [...edges, safeStart + Math.max(0, safeDuration - END_FRAME_LEAD_S)];
27+
return [...edges, safeStart + Math.max(0, safeDuration - LAST_FRAME_INSET_S)];
3328
}
3429

35-
/** A decoded frame, shared by every strip of its source that would accept it for a time. */
3630
interface SharedFrame {
3731
url: string;
3832
decodedAt: number;
@@ -44,11 +38,9 @@ interface HeldFrame {
4438
frame: SharedFrame;
4539
}
4640

47-
/** A strip takes a frame decoded inside its range, at most `lead` before the time it shows. */
4841
interface FrameWindow {
4942
sourceStart: number;
5043
lead: number;
51-
/** The clip's last frame, shown as decoded at its own time, never from an earlier keyframe. */
5244
end: number;
5345
}
5446

@@ -64,7 +56,6 @@ function takeSharedFrame(key: string, time: number, window: FrameWindow): Shared
6456
return frame;
6557
}
6658

67-
/** Shares a newly decoded frame, or the same frame another strip decoded meanwhile. */
6859
function shareFrame(key: string, decodedAt: number, url: string): SharedFrame {
6960
const frames = sharedFrames.get(key) ?? [];
7061
const existing = frames.find((shared) => shared.decodedAt === decodedAt);
@@ -102,9 +93,7 @@ async function canvasToBlob(canvas: HTMLCanvasElement | OffscreenCanvas): Promis
10293
}
10394

10495
interface DecodedResources {
105-
/** One frame per slot of the strip; a slot the source could not decode stays empty. */
10696
urls: (string | undefined)[];
107-
/** The shared frames this strip holds, released when the strip is. */
10897
held: HeldFrame[];
10998
canvases: Set<HTMLCanvasElement | OffscreenCanvas>;
11099
}
@@ -115,7 +104,6 @@ interface ThumbnailCanvasSink {
115104
): AsyncIterable<{ canvas: HTMLCanvasElement | OffscreenCanvas } | null>;
116105
}
117106

118-
/** What a strip of a source needs before it can name its frames. */
119107
interface SourceInfo {
120108
aspect: number;
121109
metadataDuration: number | null;
@@ -149,7 +137,6 @@ function targetDimensions(
149137
};
150138
}
151139

152-
/** The strip's frame times, clamped to what the file holds, and the frames it accepts for them. */
153140
function stripTimes(
154141
request: VideoThumbnailDecodeRequest,
155142
info: SourceInfo,
@@ -181,7 +168,6 @@ function stripTimes(
181168
return { window, timestamps };
182169
}
183170

184-
/** Holds every frame of the strip already decoded; returns the slots still to decode. */
185171
function takeDecodedFrames(
186172
{ timestamps, window }: ReturnType<typeof stripTimes>,
187173
keyOf: (time: number) => string,
@@ -240,10 +226,7 @@ function loadedResult(
240226
};
241227
}
242228

243-
/**
244-
* Sparse Mediabunny extraction with one pooled canvas and one cleanup owner. Frames another strip
245-
* of the source already shows are reused, so a zoom decodes only the frames that are new.
246-
*/
229+
/** Sparse Mediabunny extraction with one pooled canvas and one cleanup owner. */
247230
export async function decodeVideoThumbnail(
248231
request: VideoThumbnailDecodeRequest,
249232
signal: AbortSignal,

0 commit comments

Comments
 (0)