Skip to content

Commit

Permalink
Merge branch 'main' of github.com:jbilcke-hf/clapper
Browse files Browse the repository at this point in the history
  • Loading branch information
jbilcke-hf committed Aug 26, 2024
2 parents e4ff8a6 + c0d7223 commit d8d0649
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 56 deletions.
41 changes: 18 additions & 23 deletions packages/app/src/app/api/resolve/providers/comfyui/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
ComfyUIWorkflowApiGraph,
createPromptBuilder,
} from './utils'
import { ClapInputValueObject } from '@aitube/clap/dist/types'

export async function resolveSegment(
request: ResolveRequest
Expand Down Expand Up @@ -72,33 +73,27 @@ export async function resolveSegment(
)
})

// Set main inputs
comfyApiWorkflowPromptBuilder
.input(
(inputValues[ClapperComfyUiInputIds.PROMPT] as any).id,
request.prompts.image.positive
)
.input(
(inputValues[ClapperComfyUiInputIds.NEGATIVE_PROMPT] as any).id,
request.prompts.image.negative
)
.input(
(inputValues[ClapperComfyUiInputIds.WIDTH] as any).id,
request.meta.width
)
.input(
(inputValues[ClapperComfyUiInputIds.HEIGHT] as any).id,
request.meta.height
)
.input(
(inputValues[ClapperComfyUiInputIds.SEED] as any).id,
generateSeed()
)
const mainInputs = [
[ClapperComfyUiInputIds.PROMPT, request.prompts.image.positive],
[ClapperComfyUiInputIds.NEGATIVE_PROMPT, request.prompts.image.negative],
[ClapperComfyUiInputIds.WIDTH, request.meta.width],
[ClapperComfyUiInputIds.HEIGHT, request.meta.height],
[ClapperComfyUiInputIds.SEED, generateSeed()],
]

mainInputs.forEach((mainInput) => {
const inputId = (inputValues[mainInput[0]] as ClapInputValueObject).id
const inputValue = mainInput[1]
if (inputId) {
comfyApiWorkflowPromptBuilder.input(inputId, inputValue)
}
})

// Set output
comfyApiWorkflowPromptBuilder.setOutputNode(
ClapperComfyUiInputIds.OUTPUT,
(inputValues[ClapperComfyUiInputIds.OUTPUT] as any).id
(inputValues[ClapperComfyUiInputIds.OUTPUT] as ClapInputValueObject)
.id as string
)

const pipeline = new CallWrapper(api, comfyApiWorkflowPromptBuilder)
Expand Down
60 changes: 36 additions & 24 deletions packages/app/src/app/api/resolve/providers/comfyui/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -563,30 +563,42 @@ export function getInputsFromComfyUiWorkflow(workflowString: string): {
const outputNode = workflowGraph.getOutputNode()

const inputValues = {
[ClapperComfyUiInputIds.PROMPT]: {
id: promptNodeInputs?.[0].id,
label: `${promptNodeInputs?.[0].id} (from node ${promptNodeInputs?.[0].nodeId})`,
},
[ClapperComfyUiInputIds.NEGATIVE_PROMPT]: {
id: negativePromptNodeInputs?.[0].id,
label: `${negativePromptNodeInputs?.[0].id} (from node ${negativePromptNodeInputs?.[0].nodeId})`,
},
[ClapperComfyUiInputIds.WIDTH]: {
id: widthNodeInputs?.[0].id,
label: `${widthNodeInputs?.[0].id} (from node ${widthNodeInputs?.[0].nodeId})`,
},
[ClapperComfyUiInputIds.HEIGHT]: {
id: heightNodeInputs?.[0].id,
label: `${heightNodeInputs?.[0].id} (from node ${heightNodeInputs?.[0].nodeId})`,
},
[ClapperComfyUiInputIds.SEED]: {
id: seedNodeInputs?.[0].id,
label: `${seedNodeInputs?.[0].id} (from node ${seedNodeInputs?.[0].nodeId})`,
},
[ClapperComfyUiInputIds.OUTPUT]: {
id: outputNode?.id,
label: `${outputNode?._meta?.title} (id: ${outputNode?.id})`,
},
[ClapperComfyUiInputIds.PROMPT]: promptNodeInputs?.[0]
? {
id: promptNodeInputs?.[0].id,
label: `${promptNodeInputs?.[0].id} (from node ${promptNodeInputs?.[0].nodeId})`,
}
: undefined,
[ClapperComfyUiInputIds.NEGATIVE_PROMPT]: negativePromptNodeInputs?.[0]
? {
id: negativePromptNodeInputs?.[0].id,
label: `${negativePromptNodeInputs?.[0].id} (from node ${negativePromptNodeInputs?.[0].nodeId})`,
}
: undefined,
[ClapperComfyUiInputIds.WIDTH]: widthNodeInputs?.[0]
? {
id: widthNodeInputs?.[0].id,
label: `${widthNodeInputs?.[0].id} (from node ${widthNodeInputs?.[0].nodeId})`,
}
: undefined,
[ClapperComfyUiInputIds.HEIGHT]: heightNodeInputs?.[0]
? {
id: heightNodeInputs?.[0].id,
label: `${heightNodeInputs?.[0].id} (from node ${heightNodeInputs?.[0].nodeId})`,
}
: undefined,
[ClapperComfyUiInputIds.SEED]: seedNodeInputs?.[0]
? {
id: seedNodeInputs?.[0].id,
label: `${seedNodeInputs?.[0].id} (from node ${seedNodeInputs?.[0].nodeId})`,
}
: undefined,
[ClapperComfyUiInputIds.OUTPUT]: outputNode
? {
id: outputNode?.id,
label: `${outputNode?._meta?.title} (id: ${outputNode?.id})`,
}
: undefined,
}

const inputLabels = {
Expand Down
26 changes: 26 additions & 0 deletions packages/app/src/lib/utils/getTypeAndExtension.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,29 @@ test('getTypeAndExtension', () => {
outputType: ClapOutputType.VIDEO,
})
})

/**
* Related to the `Maximum call stack size exceeded` issue
* when using RegExp, now with string/array manipulation is
* much faster and the `stack` error solved; I wasn't able to easily
* replicate the stack size error in vitest env, seems happening only
* in Next env; so only a "performance" test is done.
*
* Issue: https://github.com/jbilcke-hf/clapper/issues/72
*/
test('getTypeAndExtension should be fast for long uris', () => {
const startTime = Date.now()
const longBase64String = 'a'.repeat(500_000_000)
const dataUri = `data:image/png;base64,${longBase64String}`
const result = getTypeAndExtension(dataUri)
expect(result).toStrictEqual({
assetFileFormat: 'image/png',
category: 'image',
extension: 'png',
outputType: ClapOutputType.IMAGE,
})
const endTime = Date.now()
const duration = endTime - startTime
// Original regexp approach was running around ~350ms; new one is around ~70ms
expect(duration).toBeLessThan(200)
})
16 changes: 7 additions & 9 deletions packages/app/src/lib/utils/getTypeAndExtension.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ClapOutputType } from '@aitube/clap'

/**
* break a base64 string into sub-components
* break a base64 data uri string into sub-components
*/
export function getTypeAndExtension(base64: string = ''): {
// category eg. video, audio, text
Expand All @@ -15,17 +15,15 @@ export function getTypeAndExtension(base64: string = ''): {

outputType: ClapOutputType
} {
// Regular expression to extract the MIME type and the base64 data
const matches = base64.match(/^data:([A-Za-z-+0-9/]+);base64,(.+)$/)

if (!matches || matches.length !== 3) {
throw new Error('Invalid base64 string')
if (!base64.startsWith('data:') || !base64.includes('base64,')) {
throw new Error('Invalid base64 data uri provided.')
}

const assetFileFormat = matches[1] || ''
const base64Index = base64.indexOf('base64,')
const mimeType = base64.slice(5, base64Index - 1)

// this should be enough for most media formats (jpeg, png, webp, mp4)
const [category, extension] = assetFileFormat.split('/')
const [category, extension] = mimeType.split('/')

let outputType = ClapOutputType.TEXT

Expand All @@ -39,7 +37,7 @@ export function getTypeAndExtension(base64: string = ''): {

return {
category,
assetFileFormat,
assetFileFormat: mimeType,
extension,
outputType,
}
Expand Down

0 comments on commit d8d0649

Please sign in to comment.