ai-tube / src /types /general.ts
jbilcke's picture
preparing transition to user-generated content + gaussians
ac7030c
export type ProjectionMode = 'cartesian' | 'spherical'
export type MouseEventType = "hover" | "click"
export type MouseEventHandler = (type: MouseEventType, x: number, y: number) => Promise<void>
export type CacheMode = "use" | "renew" | "ignore"
export interface RenderRequest {
prompt: string
// whether to use video segmentation
// disabled (default)
// firstframe: we only analyze the first frame
// allframes: we analyze all the frames
segmentation: 'disabled' | 'firstframe' | 'allframes'
// segmentation will only be executed if we have a non-empty list of actionnables
// actionnables are names of things like "chest", "key", "tree", "chair" etc
actionnables: string[]
// note: this is the number of frames for Zeroscope,
// which is currently configured to only output 3 seconds, so:
// nbFrames=8 -> 1 sec
// nbFrames=16 -> 2 sec
// nbFrames=24 -> 3 sec
nbFrames: number // min: 1, max: 24
nbSteps: number // min: 1, max: 50
seed: number
width: number // fixed at 1024 for now
height: number // fixed at 512 for now
// upscaling factor
// 0: no upscaling
// 1: no upscaling
// 2: 2x larger
// 3: 3x larger
// 4x: 4x larger, up to 4096x4096 (warning: a PNG of this size can be 50 Mb!)
upscalingFactor: number
projection: ProjectionMode
/**
* Use turbo mode
*
* At the time of writing this will use SSD-1B + LCM
* https://huggingface.co/spaces/jbilcke-hf/fast-image-server
*/
turbo: boolean
cache: CacheMode
wait: boolean // wait until the job is completed
analyze: boolean // analyze the image to generate a caption (optional)
}
export interface ImageSegment {
id: number
box: number[]
color: number[]
label: string
score: number
}
export type RenderedSceneStatus =
| "pending" // for retro-compatibility only, but this is deprecated
| "to_generate"
| "to_interpolate"
| "to_upscale"
| "completed"
| "error"
export interface RenderedScene {
renderId: string
status: RenderedSceneStatus
assetUrl: string
alt: string
error: string
maskUrl: string
segments: ImageSegment[]
}
export interface ImageAnalysisRequest {
image: string // in base64
prompt: string
}
export interface ImageAnalysisResponse {
result: string
error?: string
}
export type RenderingEngine =
| "VIDEOCHAIN"
| "OPENAI"
| "REPLICATE"
export type PostVisibility =
| "featured" // featured by admins
| "trending" // top trending / received more than 10 upvotes
| "normal" // default visibility
export type Post = {
postId: string
appId: string
prompt: string
model: string
previewUrl: string
assetUrl: string
createdAt: string
visibility: PostVisibility
upvotes: number
downvotes: number
}
export type CreatePostResponse = {
success?: boolean
error?: string
post: Post
}
export type GetAppPostsResponse = {
success?: boolean
error?: string
posts: Post[]
}
export type GetAppPostResponse = {
success?: boolean
error?: string
post: Post
}
// vendor-specific types
export type HotshotImageInferenceSize =
| '320x768'
| '384x672'
| '416x608'
| '512x512'
| '608x416'
| '672x384'
| '768x320'
| '1024x1024' // custom ratio - this isn't supported / supposed to work properly
| '1024x512' // custom panoramic ratio - this isn't supported / supposed to work properly
| '1024x576' // movie ratio (16:9) this isn't supported / supposed to work properly
| '576x1024' // tiktok ratio (9:16) this isn't supported / supposed to work properly
export type VideoOptions = {
positivePrompt: string
negativePrompt?: string
size?: HotshotImageInferenceSize
/**
* Must be a model *name*
*/
huggingFaceLora?: string
replicateLora?: string
triggerWord?: string
nbFrames?: number // FPS (eg. 8)
duration?: number // in milliseconds
steps?: number
key?: string // a semi-unique key to prevent abuse from some users
}
/**
* A channel is a video generator
*
* Video will be uploaded to a dataset
*/
export type ChannelInfo = {
/**
* We actually use the dataset ID for the channel ID.
*
*/
id: string
/**
* The name used in the URL for the channel
*
* eg: my-time-travel-journeys
*/
slug: string
/**
* username id of the Hugging Face dataset
*
* ex: f9a38286ec3436a45edd2cca
*/
// DISABLED FOR NOW
// datasetUserId: string
/**
* username slug of the Hugging Face dataset
*
* eg: jbilcke-hf
*/
datasetUser: string
/**
* dataset slug of the Hugging Face dataset
*
* eg: ai-tube-my-time-travel-journeys
*/
datasetName: string
label: string
description: string
thumbnail: string
model: VideoGenerationModel
lora: string
style: string
voice: string
music: string
/**
* The system prompt
*/
prompt: string
likes: number
tags: string[]
updatedAt: string
/**
* Default video orientation
*/
orientation: VideoOrientation
}
export type VideoStatus =
| "draft" // the video should be ignored for now
| "submitted" // the video has been submitted, but is not added to the index queue yet
| "queued" // the video has been added to the index queue, but is not processed yet. Once queued it cannot be modified.
| "generating" // the video is being generated
// TODO add a state to indicate the audio is being generated
// this will be useful in case generation fails
| "published" // success!
| "error" // video failed to generate
/**
* A video request, made by a user or robot on a channel
*/
export type VideoRequest = {
/**
* UUID (v4)
*/
id: string
// skip generation (mostly used for debugging)
// skip?: boolean
/**
* Human readable title for the video
*/
label: string
/**
* Human readable description for the video
*/
description: string
/**
* Video prompt
*/
prompt: string
/**
* URL to the video thumbnail
*/
thumbnailUrl: string
/**
* URL to a clap file
*/
clapUrl: string
/**
* When was the video updated
*/
updatedAt: string
/**
* Arbotrary string tags to label the content
*/
tags: string[]
/**
* Model name
*/
model: VideoGenerationModel
/**
* LoRA name
*/
lora: string
/**
* style name
*/
style: string
/**
* Music prompt
*/
music: string
/**
* Voice prompt
*/
voice: string
/**
* ID of the channel
*/
channel: ChannelInfo
/**
* Video orientation
*/
orientation: VideoOrientation
/**
* Video duration
*/
duration: number
}
export type VideoOrientation =
| "portrait"
| "landscape"
| "square"
export type MediaProjection =
| "cartesian" // this is the default
| "equirectangular"
| "gaussian"
// TODO: renamed this to MediaInfo
export type MediaInfo = {
/**
* UUID (v4)
*/
id: string
/**
* Status of the media
*/
status: VideoStatus
/**
* Human readable title for the media
*/
label: string
/**
* Human readable description for the media
*/
description: string
/**
* Content prompt
*/
prompt: string
/**
* URL to the media thumbnail
*/
thumbnailUrl: string
/**
* URL to a clap file
*/
clapUrl: string
/**
* URL to the binary file
*
* This is the standard format
*
* see width and height for details
*
* (it will be something like 1024x576, 576x1024, 1024x512)
*
*/
assetUrl: string
/**
* This is contain the storage URL of the higher-resolution content
*/
assetUrlHd: string
/**
* Counter for the number of views
*
* Note: should be managed by the index to prevent cheating
*/
numberOfViews: number
/**
* Counter for the number of likes
*
* Note: should be managed by the index to prevent cheating
*/
numberOfLikes: number
/**
* Counter for the number of dislikes
*
* Note: should be managed by the index to prevent cheating
*/
numberOfDislikes: number
/**
* When was the media updated
*/
updatedAt: string
/**
* Arbotrary string tags to label the content
*/
tags: string[]
/**
* Model name
*/
model: VideoGenerationModel
/**
* LoRA name
*/
lora: string
/**
* style name
*/
style: string
/**
* Music prompt
*/
music: string
/**
* Voice prompt
*/
voice: string
/**
* The channel
*/
channel: ChannelInfo
/**
* Media duration
*/
duration: number
/**
* Media width (eg. 1024)
*/
width: number
/**
* Media height (eg. 576)
*/
height: number
/**
* General media aspect ratio
*/
orientation: VideoOrientation
/**
* Media projection (cartesian by default)
*/
projection: MediaProjection
}
export type CollectionInfo = {
/**
* UUID (v4)
*/
id: string
/**
* Human readable title for the video
*/
label: string
/**
* Human readable description for the video
*/
description: string
/**
* URL to the video thumbnail
*/
thumbnailUrl: string
/**
* Counter for the number of views
*
* Note: should be managed by the index to prevent cheating
*/
numberOfViews: number
/**
* Counter for the number of likes
*
* Note: should be managed by the index to prevent cheating
*/
numberOfLikes: number
/**
* When was the video updated
*/
updatedAt: string
/**
* Arbotrary string tags to label the content
*/
tags: string[]
/**
* The owner channel
*/
channel: ChannelInfo
/**
* Collection duration
*/
duration: number
items: Array<MediaInfo>[]
}
export type UserInfo = {
id: string
type: "creator" | "normal" | "admin"
userName: string
fullName: string
thumbnail: string
channels: ChannelInfo[]
// the Hugging Face API token is confidential,
// and will only be available for the current user
hfApiToken?: string
}
export type CommentInfo = {
id: string
userId: string
// only populated when rendering
userInfo?: UserInfo
// if the video comment is in response to another comment,
// then "inReplyTo" will contain the other video comment id
inReplyTo?: string
createdAt: string
updatedAt: string
message: string
// how many likes did the comment receive
numberOfLikes: number
// how many replies did the comment receive
numberOfReplies: number
// if the comment was appreciated by the original content poster
likedByOriginalPoster: boolean
}
export type StoredCommentInfo = Omit<CommentInfo, "userInfo">
export type VideoGenerationModel =
| "HotshotXL"
| "SVD"
| "LaVie"
export type InterfaceDisplayMode =
| "desktop"
| "tv"
export type InterfaceHeaderMode =
| "hidden"
| "normal"
| "compact"
export type InterfaceMenuMode =
| "slider_hidden"
| "slider_text"
| "normal_icon"
| "normal_text"
export type InterfaceView =
| "home"
| "user_channels"
| "user_channel" // for a user to admin their channels
| "user_videos"
| "user_video"
| "user_account"
| "public_channels"
| "public_channel" // public view of a channel
| "public_video" // public view of a video
| "public_video_embed" // for integration into twitter etc
| "public_music_videos" // public music videos - it's a special category, because music is *cool*
| "public_gaming" // for AiTube Gaming
| "public_4d" // for AiTube 4D
| "public_live" // for AiTube Live
| "not_found"
export type Settings = {
huggingfaceApiKey: string
huggingfaceTemporaryApiKey: string
}
export type ParsedDatasetReadme = {
license: string
pretty_name: string
model: VideoGenerationModel
lora: string
style: string
thumbnail: string
voice: string
music: string
tags: string[]
hf_tags: string[]
description: string
prompt: string
orientation: VideoOrientation
}
export type ParsedMetadataAndContent = {
metadata: {
license: string,
pretty_name: string,
tags: string[]
}
content: string
}
export type ParsedDatasetPrompt = {
title: string
description: string
prompt: string
tags: string[]
model: VideoGenerationModel
lora: string
style: string
thumbnail: string
voice: string
music: string
orientation: VideoOrientation
}
export type UpdateQueueRequest = {
channel?: ChannelInfo
apiKey: string
}
export type UpdateQueueResponse = {
error?: string
nbUpdated: number
}
export type AppQueryProps = {
params: { id: string }
searchParams: {
v?: string | string[],
m?: string | string[],
c?: string | string[],
[key: string]: string | string[] | undefined
}
}
export type MediaDisplayLayout =
| "grid" // default mode, items goas back to the line
| "horizontal" // will be used for a "Netflix" horizontal sliding mode
| "vertical" // used in the right recommendation panel
| "table" // used when shown in a table mode
| "micro"
export type MediaRating = {
isLikedByUser: boolean
isDislikedByUser: boolean
numberOfLikes: number
numberOfDislikes: number
}