-
-
Notifications
You must be signed in to change notification settings - Fork 211
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9bbe0fa
commit b67cf31
Showing
3 changed files
with
146 additions
and
0 deletions.
There are no files selected for viewing
73 changes: 73 additions & 0 deletions
73
packages/app/src/app/api/resolve/providers/replicate/runLipSync.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import Replicate from 'replicate' | ||
import { ClapSegmentCategory } from '@aitube/clap' | ||
import { TimelineSegment } from '@aitube/timeline' | ||
import { ResolveRequest } from '@aitube/clapper-services' | ||
|
||
export async function runLipSync( | ||
request: ResolveRequest | ||
): Promise<TimelineSegment> { | ||
if (!request.settings.replicateApiKey) { | ||
throw new Error(`Missing API key for "Replicate.com"`) | ||
} | ||
|
||
const replicate = new Replicate({ auth: request.settings.replicateApiKey }) | ||
|
||
const segment: TimelineSegment = request.segment | ||
|
||
const firstDialogue = request.segments.find( | ||
(s) => s.category === ClapSegmentCategory.DIALOGUE | ||
) | ||
const firstDialogueAudio = firstDialogue?.assetUrl | ||
|
||
if (segment.category === ClapSegmentCategory.VIDEO) { | ||
const videoLipsyncWorkflowModel = | ||
request.settings.videoLipsyncWorkflow.data || '' | ||
|
||
if (!videoLipsyncWorkflowModel) { | ||
throw new Error( | ||
`cannot run the lip sync without an videoLipsyncWorkflowModel` | ||
) | ||
} | ||
if (!segment.assetUrl) { | ||
throw new Error(`cannot run the lip sync without a video`) | ||
} | ||
|
||
if (!firstDialogueAudio) { | ||
throw new Error(`cannot run the lip sync without a dialogue speech`) | ||
} | ||
|
||
try { | ||
// console.log(`requested model:`, request.settings.videoLipsyncWorkflow.data) | ||
const response = (await replicate.run( | ||
request.settings.videoLipsyncWorkflow.data as any, | ||
{ | ||
input: { | ||
// note: this is actually a VIDEO (they call it face, but it's a face video) | ||
face: segment.assetUrl, | ||
input_audio: firstDialogueAudio, | ||
|
||
disable_safety_checker: | ||
!request.settings.censorNotForAllAudiencesContent, | ||
}, | ||
} | ||
)) as any | ||
|
||
// note how it is | ||
const imageResult = `${response || ''}` | ||
|
||
if (!imageResult) { | ||
throw new Error(`the generated image is empty`) | ||
} | ||
|
||
segment.assetUrl = imageResult | ||
} catch (err) { | ||
console.error(`failed to run a lip sync using Replicate.com:`, err) | ||
} | ||
} else { | ||
throw new Error( | ||
`Clapper doesn't support lip sync for the "${segment.category}" category using Replicate.com yet` | ||
) | ||
} | ||
|
||
return segment | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters