Files
2026-02-27 23:33:56 +03:00

178 lines
3.8 KiB
Python

from __future__ import annotations
from datetime import datetime
from typing import Literal
from uuid import UUID
from pydantic import ConfigDict
from cpv3.common.schemas import Schema
ArtifactTypeEnum = Literal[
"TRANSCRIPTION_JSON",
"SILENCE_REMOVED_VIDEO",
"CONVERTED_VIDEO",
"THUMBNAIL",
"AUDIO_PROXY",
"RENDERED_VIDEO",
"FRAME_SPRITES",
]
class MediaFileRead(Schema):
id: UUID
owner_id: UUID
project_id: UUID | None
duration_seconds: float
frame_rate: float | None
width: int | None
height: int | None
probe_json: dict | None
notes: str | None
meta: dict | None
is_deleted: bool
is_active: bool
created_at: datetime
updated_at: datetime
class MediaFileCreate(Schema):
project_id: UUID | None = None
duration_seconds: float
frame_rate: float | None = None
width: int | None = None
height: int | None = None
probe_json: dict | None = None
notes: str | None = None
meta: dict | None = None
class MediaFileUpdate(Schema):
notes: str | None = None
meta: dict | None = None
is_deleted: bool | None = None
class ArtifactMediaFileRead(Schema):
id: UUID
project_id: UUID | None
file_id: UUID | None
media_file_id: UUID | None
artifact_type: ArtifactTypeEnum
is_deleted: bool
is_active: bool
created_at: datetime
updated_at: datetime
class ArtifactMediaFileCreate(Schema):
project_id: UUID | None = None
file_id: UUID | None = None
media_file_id: UUID | None = None
artifact_type: ArtifactTypeEnum
class ArtifactMediaFileUpdate(Schema):
is_deleted: bool | None = None
class DispositionSchema(Schema):
model_config = ConfigDict(extra="allow")
default: int | None = None
class StreamSchema(Schema):
model_config = ConfigDict(extra="allow")
index: int | None = None
codec_name: str | None = None
codec_long_name: str | None = None
profile: str | None = None
codec_type: str | None = None
codec_tag_string: str | None = None
codec_tag: str | None = None
width: int | None = None
height: int | None = None
id: str | None = None
r_frame_rate: str | None = None
avg_frame_rate: str | None = None
time_base: str | None = None
start_pts: int | None = None
start_time: str | None = None
duration_ts: int | None = None
duration: str | None = None
bit_rate: str | None = None
nb_frames: str | None = None
extradata_size: int | None = None
disposition: DispositionSchema | None = None
tags: dict[str, str] | None = None
class FormatSchema(Schema):
model_config = ConfigDict(extra="allow")
filename: str | None = None
nb_streams: int | None = None
format_name: str | None = None
format_long_name: str | None = None
start_time: str | None = None
duration: str | None = None
size: str | None = None
bit_rate: str | None = None
probe_score: int | None = None
tags: dict[str, str] | None = None
class MediaProbeSchema(Schema):
model_config = ConfigDict(extra="allow")
streams: list[StreamSchema] = []
format: FormatSchema | None = None
class MediaSilencerParams(Schema):
file_path: str
folder: str = ""
min_silence_duration_ms: int = 200
silence_threshold_db: int = 16
padding_ms: int = 100
class MediaConverterParams(Schema):
file_path: str
folder: str = ""
class FrameSpriteMetadata(Schema):
"""Metadata stored in ArtifactMediaFile.meta for extracted frames."""
frame_count: int
interval: float
width: int
height: int
folder_key: str
source_file_key: str
class FrameItem(Schema):
"""Single frame in a range query response."""
timestamp: float
url: str
class FrameRangeResponse(Schema):
"""Response for GET /api/media/frames/ range query."""
interval: float
frames: list[FrameItem]