File size: 3,563 Bytes
e40bd21
 
 
637b219
e40bd21
 
 
 
 
637b219
e40bd21
 
 
 
 
 
 
 
 
 
 
 
 
e02a62b
 
 
 
 
 
 
 
 
e40bd21
 
 
 
 
 
 
 
e02a62b
 
 
 
 
 
 
 
 
e40bd21
 
637b219
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e40bd21
 
 
 
 
 
 
637b219
e40bd21
3adb71a
e40bd21
 
 
 
3adb71a
637b219
 
e40bd21
 
 
 
 
 
 
 
 
637b219
e40bd21
3adb71a
e40bd21
 
 
 
3adb71a
637b219
 
e40bd21
 
 
 
 
 
 
637b219
e40bd21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
637b219
e40bd21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
import YAML from "yaml"
import { v4 as uuidv4 } from "uuid"

import { ClapHeader, ClapMeta, ClapModel, ClapProject, ClapScene, ClapSegment } from "./types"
import { getValidNumber } from "@/lib/getValidNumber"

export async function serializeClap({
  meta, // ClapMeta
  models, // ClapModel[]
  scenes, // ClapScene[]
  segments, // ClapSegment[]
}: ClapProject): Promise<Blob> {
  
  // we play it safe, and we verify the structure of the parameters,
  // to make sure we generate a valid clap file
  const clapModels: ClapModel[] = models.map(({
    id,
    category,
    triggerName,
    label,
    description,
    author,
    thumbnailUrl,
    seed,
    assetSourceType,
    assetUrl,
    age,
    gender,
    region,
    appearance,
    voiceVendor,
    voiceId,
  }) => ({
    id,
    category,
    triggerName,
    label,
    description,
    author,
    thumbnailUrl,
    seed,
    assetSourceType,
    assetUrl,
    age,
    gender,
    region,
    appearance,
    voiceVendor,
    voiceId,
  }))

  const clapScenes: ClapScene[] = scenes.map(({
    id,
    scene,
    line,
    rawLine,
    sequenceFullText,
    sequenceStartAtLine,
    sequenceEndAtLine,
    startAtLine,
    endAtLine,
    events,
  }) => ({
    id,
    scene,
    line,
    rawLine,
    sequenceFullText,
    sequenceStartAtLine,
    sequenceEndAtLine,
    startAtLine,
    endAtLine,
    events: events.map(e => e)
  }))

  const clapSegments: ClapSegment[] = segments.map(({
    id,
    track,
    startTimeInMs,
    endTimeInMs,
    category,
    modelId,
    sceneId,
    prompt,
    label,
    outputType,
    renderId,
    status,
    assetUrl,
    assetDurationInMs,
    createdBy,
    editedBy,
    outputGain,
    seed,
  }) => ({
    id,
    track,
    startTimeInMs,
    endTimeInMs,
    category,
    modelId,
    sceneId,
    prompt,
    label,
    outputType,
    renderId,
    status,
    assetUrl,
    assetDurationInMs,
    createdBy,
    editedBy,
    outputGain,
    seed,
  }))

  const clapHeader: ClapHeader = {
    format: "clap-0",
    numberOfModels: clapModels.length,
    numberOfScenes: clapScenes.length,
    numberOfSegments: clapSegments.length,
  }

  const clapMeta: ClapMeta = {
    id: meta.id || uuidv4(),
    title: typeof meta.title === "string" ? meta.title : "Untitled",
    description: typeof meta.description === "string" ? meta.description : "",
    licence: typeof meta.licence === "string" ? meta.licence : "",
    orientation: meta.orientation === "portrait" ? "portrait" : meta.orientation === "square" ? "square" : "landscape",
    width: getValidNumber(meta.width, 256, 8192, 1024),
    height: getValidNumber(meta.height, 256, 8192, 576),
    defaultVideoModel:  typeof meta.defaultVideoModel === "string" ? meta.defaultVideoModel : "SVD",
    extraPositivePrompt: Array.isArray(meta.extraPositivePrompt) ? meta.extraPositivePrompt : [],
  }

  const entries = [
    clapHeader,
    clapMeta,
    ...clapModels,
    ...clapScenes,
    ...clapSegments
  ]

  const strigifiedResult = YAML.stringify(entries)

  // Convert the string to a Blob
  const blobResult = new Blob([strigifiedResult], { type: "application/x-yaml" })

   // Create a stream for the blob
   const readableStream = blobResult.stream();

   // Compress the stream using gzip
   const compressionStream = new CompressionStream('gzip');
   const compressedStream = readableStream.pipeThrough(compressionStream);

   // Create a new blob from the compressed stream
   const compressedBlob = await new Response(compressedStream).blob();

  return compressedBlob
}