feat: add keyframe index extraction and frame/keyframe navigation

Wire ffprobe-based keyframe indexing through Tauri and auto-load positions after download completes.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-21 11:10:20 -04:00
parent 2f25db3cc5
commit c96b0cedc9
5 changed files with 97 additions and 3 deletions

View File

@@ -1,3 +1,5 @@
import { invoke } from '@tauri-apps/api/core';
export interface ThumbnailSpritesheet {
filePath: string;
startIndex: number;
@@ -7,3 +9,7 @@ export interface ThumbnailSpritesheet {
columns: number;
intervalSeconds: number;
}
export async function extractKeyframes(filePath: string): Promise<number[]> {
return invoke<number[]>('extract_keyframes', { filePath });
}

View File

@@ -1,6 +1,7 @@
import type { VideoMetadata } from '$lib/bindings/video';
import { startDownload } from '$lib/bindings/video';
import type { ThumbnailSpritesheet } from '$lib/bindings/mediaAnalysis';
import { extractKeyframes } from '$lib/bindings/mediaAnalysis';
export type SessionStatus = 'idle' | 'resolving' | 'ready' | 'error';
export type DownloadStatus = 'idle' | 'downloading' | 'complete' | 'failed';
@@ -77,6 +78,15 @@ export function reset() {
session.error = null;
}
async function triggerPostDownloadProcessing(filePath: string) {
try {
session.keyframePositions = await extractKeyframes(filePath);
} catch (e) {
console.error('Keyframe extraction failed:', e);
}
// Waveform and thumbnails will be added in Tasks 10 and 11
}
export async function beginDownload() {
if (!session.url) return;
@@ -98,6 +108,7 @@ export async function beginDownload() {
session.downloadProgress = 1.0;
session.localFilePath = path;
session.downloadStatus = 'complete';
void triggerPostDownloadProcessing(path);
} else {
session.downloadStatus = 'failed';
}