const API_BASE = process.env.NEXT_PUBLIC_API_BASE ?? "http://localhost:4291" export type JobStatus = | "created" | "downloading" | "splitting" | "frames_extracted" | "transcribing" | "transcribed" | "failed" export interface KeyFrame { index: number timestamp: number url: string } export interface TranscriptSegment { index: number start: number end: number en: string zh: string } export interface Job { id: string url: string status: JobStatus progress: number message?: string video_url?: string duration?: number width?: number height?: number frames: KeyFrame[] transcript: TranscriptSegment[] error?: string } export async function createJob(tkUrl: string): Promise { const res = await fetch(`${API_BASE}/jobs`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ url: tkUrl }), }) if (!res.ok) throw new Error(`createJob ${res.status}`) return res.json() } export async function getJob(id: string): Promise { const res = await fetch(`${API_BASE}/jobs/${id}`) if (!res.ok) throw new Error(`getJob ${res.status}`) return res.json() } export async function triggerTranscribe(id: string): Promise { const res = await fetch(`${API_BASE}/jobs/${id}/transcribe`, { method: "POST" }) if (!res.ok) throw new Error(`transcribe ${res.status}`) return res.json() } export function frameUrl(jobId: string, frameIndex: number): string { return `${API_BASE}/jobs/${jobId}/frames/${frameIndex}.jpg` } export function videoUrl(jobId: string): string { return `${API_BASE}/jobs/${jobId}/video.mp4` }