chunker ui redo
This commit is contained in:
@@ -1,15 +1,4 @@
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family:
|
||||
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
background: #1a1a1a;
|
||||
color: #e0e0e0;
|
||||
}
|
||||
@import "../../common/styles/theme.css";
|
||||
|
||||
.app {
|
||||
display: flex;
|
||||
|
||||
@@ -115,7 +115,6 @@ function App() {
|
||||
setJobs(data);
|
||||
};
|
||||
|
||||
const assetJobs = jobs.filter((j) => j.source_asset_id === selectedAsset?.id);
|
||||
const completedJobs = jobs.filter((j) => j.status === "completed");
|
||||
|
||||
if (loading) return <div className="loading">Loading...</div>;
|
||||
|
||||
@@ -42,6 +42,8 @@ export default function JobPanel({
|
||||
preset_id: selectedPresetId || null,
|
||||
trim_start: hasTrim ? trimStart : null,
|
||||
trim_end: hasTrim ? trimEnd : null,
|
||||
output_filename: null,
|
||||
priority: 0,
|
||||
});
|
||||
onJobCreated();
|
||||
} catch (e) {
|
||||
|
||||
@@ -2,45 +2,17 @@
|
||||
* GraphQL API client
|
||||
*/
|
||||
|
||||
import { gql } from "../../common/api/graphql";
|
||||
import { getAssets, scanMediaFolder } from "../../common/api/media";
|
||||
import type {
|
||||
MediaAsset,
|
||||
TranscodePreset,
|
||||
TranscodeJob,
|
||||
CreateJobRequest,
|
||||
SystemStatus,
|
||||
MediaAsset,
|
||||
} from "./types";
|
||||
|
||||
const GRAPHQL_URL = "/api/graphql";
|
||||
|
||||
async function gql<T>(query: string, variables?: Record<string, unknown>): Promise<T> {
|
||||
const response = await fetch(GRAPHQL_URL, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ query, variables }),
|
||||
});
|
||||
|
||||
const json = await response.json();
|
||||
|
||||
if (json.errors?.length) {
|
||||
throw new Error(json.errors[0].message);
|
||||
}
|
||||
|
||||
return json.data as T;
|
||||
}
|
||||
|
||||
// Assets
|
||||
export async function getAssets(): Promise<MediaAsset[]> {
|
||||
const data = await gql<{ assets: MediaAsset[] }>(`
|
||||
query {
|
||||
assets {
|
||||
id filename file_path status error_message file_size duration
|
||||
video_codec audio_codec width height framerate bitrate
|
||||
properties comments tags created_at updated_at
|
||||
}
|
||||
}
|
||||
`);
|
||||
return data.assets;
|
||||
}
|
||||
export { getAssets, scanMediaFolder };
|
||||
|
||||
export async function getAsset(id: string): Promise<MediaAsset> {
|
||||
const data = await gql<{ asset: MediaAsset }>(`
|
||||
@@ -55,20 +27,6 @@ export async function getAsset(id: string): Promise<MediaAsset> {
|
||||
return data.asset;
|
||||
}
|
||||
|
||||
export async function scanMediaFolder(): Promise<{
|
||||
found: number;
|
||||
registered: number;
|
||||
skipped: number;
|
||||
files: string[];
|
||||
}> {
|
||||
const data = await gql<{ scan_media_folder: { found: number; registered: number; skipped: number; files: string[] } }>(`
|
||||
mutation {
|
||||
scan_media_folder { found registered skipped files }
|
||||
}
|
||||
`);
|
||||
return data.scan_media_folder;
|
||||
}
|
||||
|
||||
// Presets
|
||||
export async function getPresets(): Promise<TranscodePreset[]> {
|
||||
const data = await gql<{ presets: TranscodePreset[] }>(`
|
||||
|
||||
@@ -1,135 +1,21 @@
|
||||
/**
|
||||
* TypeScript Types - GENERATED FILE
|
||||
* TypeScript Types — re-exported from common generated types.
|
||||
*
|
||||
* Do not edit directly. Regenerate using modelgen.
|
||||
*/
|
||||
|
||||
export type AssetStatus = "pending" | "ready" | "error";
|
||||
export type JobStatus = "pending" | "processing" | "completed" | "failed" | "cancelled";
|
||||
export type ChunkJobStatus = "pending" | "chunking" | "processing" | "collecting" | "completed" | "failed" | "cancelled";
|
||||
|
||||
export interface MediaAsset {
|
||||
id: string;
|
||||
filename: string;
|
||||
file_path: string;
|
||||
status: AssetStatus;
|
||||
error_message: string | null;
|
||||
file_size: number | null;
|
||||
duration: number | null;
|
||||
video_codec: string | null;
|
||||
audio_codec: string | null;
|
||||
width: number | null;
|
||||
height: number | null;
|
||||
framerate: number | null;
|
||||
bitrate: number | null;
|
||||
properties: Record<string, unknown>;
|
||||
comments: string;
|
||||
tags: string[];
|
||||
created_at: string | null;
|
||||
updated_at: string | null;
|
||||
}
|
||||
|
||||
export interface TranscodePreset {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
is_builtin: boolean;
|
||||
container: string;
|
||||
video_codec: string;
|
||||
video_bitrate: string | null;
|
||||
video_crf: number | null;
|
||||
video_preset: string | null;
|
||||
resolution: string | null;
|
||||
framerate: number | null;
|
||||
audio_codec: string;
|
||||
audio_bitrate: string | null;
|
||||
audio_channels: number | null;
|
||||
audio_samplerate: number | null;
|
||||
extra_args: string[];
|
||||
created_at: string | null;
|
||||
updated_at: string | null;
|
||||
}
|
||||
|
||||
export interface TranscodeJob {
|
||||
id: string;
|
||||
source_asset_id: string;
|
||||
preset_id: string | null;
|
||||
preset_snapshot: Record<string, unknown>;
|
||||
trim_start: number | null;
|
||||
trim_end: number | null;
|
||||
output_filename: string;
|
||||
output_path: string | null;
|
||||
output_asset_id: string | null;
|
||||
status: JobStatus;
|
||||
progress: number;
|
||||
current_frame: number | null;
|
||||
current_time: number | null;
|
||||
speed: string | null;
|
||||
error_message: string | null;
|
||||
celery_task_id: string | null;
|
||||
execution_arn: string | null;
|
||||
priority: number;
|
||||
created_at: string | null;
|
||||
started_at: string | null;
|
||||
completed_at: string | null;
|
||||
}
|
||||
|
||||
export interface ChunkJob {
|
||||
id: string;
|
||||
source_asset_id: string;
|
||||
chunk_duration: number;
|
||||
num_workers: number;
|
||||
max_retries: number;
|
||||
processor_type: string;
|
||||
status: ChunkJobStatus;
|
||||
progress: number;
|
||||
total_chunks: number;
|
||||
processed_chunks: number;
|
||||
failed_chunks: number;
|
||||
retry_count: number;
|
||||
error_message: string | null;
|
||||
throughput_mbps: number | null;
|
||||
elapsed_seconds: number | null;
|
||||
celery_task_id: string | null;
|
||||
priority: number;
|
||||
created_at: string | null;
|
||||
started_at: string | null;
|
||||
completed_at: string | null;
|
||||
}
|
||||
|
||||
export interface CreateJobRequest {
|
||||
source_asset_id: string;
|
||||
preset_id: string | null;
|
||||
trim_start: number | null;
|
||||
trim_end: number | null;
|
||||
output_filename: string | null;
|
||||
priority: number;
|
||||
}
|
||||
|
||||
export interface UpdateAssetRequest {
|
||||
comments: string | null;
|
||||
tags: string[] | null;
|
||||
}
|
||||
|
||||
export interface SystemStatus {
|
||||
status: string;
|
||||
version: string;
|
||||
}
|
||||
|
||||
export interface ScanResult {
|
||||
found: number;
|
||||
registered: number;
|
||||
skipped: number;
|
||||
files: string[];
|
||||
}
|
||||
|
||||
export interface DeleteResult {
|
||||
ok: boolean;
|
||||
}
|
||||
|
||||
export interface WorkerStatus {
|
||||
available: boolean;
|
||||
active_jobs: number;
|
||||
supported_codecs: string[];
|
||||
gpu_available: boolean;
|
||||
}
|
||||
export type {
|
||||
AssetStatus,
|
||||
JobStatus,
|
||||
ChunkJobStatus,
|
||||
MediaAsset,
|
||||
TranscodePreset,
|
||||
TranscodeJob,
|
||||
ChunkJob,
|
||||
CreateJobRequest,
|
||||
UpdateAssetRequest,
|
||||
SystemStatus,
|
||||
ScanResult,
|
||||
DeleteResult,
|
||||
WorkerStatus,
|
||||
} from "../../common/types/generated";
|
||||
|
||||
Reference in New Issue
Block a user